This commit is contained in:
Ivan Bondarev 2023-02-26 11:10:08 +01:00
parent 8b24a037e3
commit 64b4430b85
5 changed files with 114 additions and 0 deletions

17
TestSuite/attributes5.pas Normal file
View file

@ -0,0 +1,17 @@
uses System;
type
[AttributeUsage(AttributeTargets.Field or AttributeTargets.Property) ]
myattr = class (Attribute) end;
TClass = class
[myattr]
a: integer;
[myattr]
property prop: integer read a;
end;
begin
end.

View file

@ -0,0 +1,23 @@
//!Атрибут myattr неприменим к методам
uses System;
type
[AttributeUsage(AttributeTargets.Field or AttributeTargets.Property) ]
myattr = class (Attribute) end;
TClass = class
[myattr]
a: integer;
[myattr]
property prop: integer read a;
[myattr]
procedure Test;
begin
end;
end;
begin
end.

View file

@ -5019,6 +5019,75 @@ namespace PascalABCCompiler.SystemLibrary
return new string_const_node(left.constant_value.ToString() + right.constant_value.ToString(), call_location);
}
public static expression_node enum_or_executor(location call_location, params expression_node[] parameters)
{
enum_const_node left = parameters[0] as enum_const_node;
if (left == null && parameters[0] is static_compiled_variable_reference)
{
static_compiled_variable_reference cvr = parameters[0] as static_compiled_variable_reference;
if (cvr.var.IsLiteral)
left = new enum_const_node((int)cvr.var.compiled_field.GetRawConstantValue(), parameters[0].type, parameters[0].location);
}
if (left == null)
return null;
enum_const_node right = parameters[1] as enum_const_node;
if (right == null && parameters[1] is static_compiled_variable_reference)
{
static_compiled_variable_reference cvr = parameters[1] as static_compiled_variable_reference;
if (cvr.var.IsLiteral)
right = new enum_const_node((int)cvr.var.compiled_field.GetRawConstantValue(), parameters[1].type, parameters[1].location);
}
if (right == null)
return null;
return new enum_const_node(left.constant_value | right.constant_value, left.type, call_location);
}
public static expression_node enum_and_executor(location call_location, params expression_node[] parameters)
{
enum_const_node left = parameters[0] as enum_const_node;
if (left == null && parameters[0] is static_compiled_variable_reference)
{
static_compiled_variable_reference cvr = parameters[0] as static_compiled_variable_reference;
if (cvr.var.IsLiteral)
left = new enum_const_node((int)cvr.var.compiled_field.GetRawConstantValue(), parameters[0].type, parameters[0].location);
}
if (left == null)
return null;
enum_const_node right = parameters[1] as enum_const_node;
if (right == null && parameters[1] is static_compiled_variable_reference)
{
static_compiled_variable_reference cvr = parameters[1] as static_compiled_variable_reference;
if (cvr.var.IsLiteral)
right = new enum_const_node((int)cvr.var.compiled_field.GetRawConstantValue(), parameters[1].type, parameters[1].location);
}
if (right == null)
return null;
return new enum_const_node(left.constant_value & right.constant_value, left.type, call_location);
}
public static expression_node enum_xor_executor(location call_location, params expression_node[] parameters)
{
enum_const_node left = parameters[0] as enum_const_node;
if (left == null && parameters[0] is static_compiled_variable_reference)
{
static_compiled_variable_reference cvr = parameters[0] as static_compiled_variable_reference;
if (cvr.var.IsLiteral)
left = new enum_const_node((int)cvr.var.compiled_field.GetRawConstantValue(), parameters[0].type, parameters[0].location);
}
if (left == null)
return null;
enum_const_node right = parameters[1] as enum_const_node;
if (right == null && parameters[1] is static_compiled_variable_reference)
{
static_compiled_variable_reference cvr = parameters[1] as static_compiled_variable_reference;
if (cvr.var.IsLiteral)
right = new enum_const_node((int)cvr.var.compiled_field.GetRawConstantValue(), parameters[1].type, parameters[1].location);
}
if (right == null)
return null;
return new enum_const_node(left.constant_value ^ right.constant_value, left.type, call_location);
}
}
}

View file

@ -12496,6 +12496,8 @@ namespace PascalABCCompiler.TreeConverter
for (int i = 0; i < cnstr_args.expressions.Count; i++)
{
constant_node cn = convert_strong_to_constant_node(cnstr_args.expressions[i]);
if (cn is basic_function_call_as_constant && (cn as basic_function_call_as_constant).method_call.function_node.compile_time_executor != null)
cn = (cn as basic_function_call_as_constant).method_call.function_node.compile_time_executor(cn.location, (cn as basic_function_call_as_constant).method_call.parameters.ToArray()) as constant_node;
check_for_strong_constant(cn, get_location(cnstr_args.expressions[i]));
args.AddElement(cn);
}

View file

@ -3340,8 +3340,11 @@ namespace PascalABCCompiler.TreeRealization
{
if (ctn.compiled_type.GetCustomAttributes(typeof(FlagsAttribute), true).Length == 0) return;
basic_function_node _int_and = SystemLibrary.SystemLibrary.make_binary_operator(compiler_string_consts.and_name, ctn, SemanticTree.basic_function_type.iand);
_int_and.compile_time_executor = SystemLibrary.static_executors.enum_and_executor;
basic_function_node _int_or = SystemLibrary.SystemLibrary.make_binary_operator(compiler_string_consts.or_name, ctn, SemanticTree.basic_function_type.ior);
_int_or.compile_time_executor = SystemLibrary.static_executors.enum_or_executor;
basic_function_node _int_xor = SystemLibrary.SystemLibrary.make_binary_operator(compiler_string_consts.xor_name, ctn, SemanticTree.basic_function_type.ixor);
_int_xor.compile_time_executor = SystemLibrary.static_executors.enum_xor_executor;
if (ctn.scope != null)
{
ctn.scope.AddSymbol(compiler_string_consts.and_name, new SymbolInfo(_int_and));