* rework code for parsing attributes to only allow constant expressions; Delphi only allows those as well and better we don't open *that* pandora's box just yet

git-svn-id: trunk@42379 -
This commit is contained in:
svenbarth 2019-07-12 22:06:24 +00:00
parent ab2fa724ec
commit db37146f12

View File

@ -61,7 +61,7 @@ implementation
{ symtable } { symtable }
symconst,symbase,symtype,symcpu,symcreat,defutil,defcmp,symtable, symconst,symbase,symtype,symcpu,symcreat,defutil,defcmp,symtable,
{ pass 1 } { pass 1 }
ninl,ncon,nobj,ngenutil,nld,nmem,ncal, ninl,ncon,nobj,ngenutil,nld,nmem,ncal,pass_1,
{ parser } { parser }
scanner, scanner,
pbase,pexpr,ptype,ptconst,pdecsub,pdecvar,pdecobj,pgenutil,pparautl, pbase,pexpr,ptype,ptconst,pdecsub,pdecvar,pdecobj,pgenutil,pparautl,
@ -412,14 +412,29 @@ implementation
end; end;
procedure parse_rttiattributes(var rtti_attrs_def:trtti_attribute_list); procedure parse_rttiattributes(var rtti_attrs_def:trtti_attribute_list);
function read_attr_paras:tnode;
var
old_block_type : tblock_type;
begin
if try_to_consume(_LKLAMMER) then
begin
{ we only want constants here }
old_block_type:=block_type;
block_type:=bt_const;
result:=parse_paras(false,false,_RKLAMMER);
block_type:=old_block_type;
consume(_RKLAMMER);
end
else
result:=nil;
end;
var var
p, p1 : tnode; p,paran,pcalln : tnode;
again : boolean;
od : tobjectdef; od : tobjectdef;
constrSym : tsymentry; constrsym : tsymentry;
constrProcDef : tprocdef; typesym : ttypesym;
typeSym : ttypesym;
oldblock_type : tblock_type;
begin begin
consume(_LECKKLAMMER); consume(_LECKKLAMMER);
@ -427,41 +442,39 @@ implementation
p:=factor(false,[ef_type_only,ef_check_attr_suffix]); p:=factor(false,[ef_type_only,ef_check_attr_suffix]);
if p.nodetype=typen then if p.nodetype=typen then
begin begin
typeSym:=ttypesym(ttypenode(p).typesym); typesym:=ttypesym(ttypenode(p).typesym);
od:=tobjectdef(ttypenode(p).typedef); od:=tobjectdef(ttypenode(p).typedef);
{ Check if the attribute class is related to TCustomAttribute } { Check if the attribute class is related to TCustomAttribute }
if not is_system_custom_attribute_descendant(od) then if not is_system_custom_attribute_descendant(od) then
incompatibletypes(od, system_custom_attribute_def); incompatibletypes(od,system_custom_attribute_def);
paran:=read_attr_paras;
{ Search the tprocdef of the constructor which has to be called. } { Search the tprocdef of the constructor which has to be called. }
constrSym:=find_create_constructor(od); constrsym:=find_create_constructor(od);
if constrSym.typ<>procsym then if constrsym.typ<>procsym then
internalerror(2018102301); internalerror(2018102301);
constrProcDef:=tprocsym(constrSym).find_procdef_bytype(potype_constructor);
{ Parse the attribute-parameters as if it is a list of parameters from pcalln:=ccallnode.create(paran,tprocsym(constrsym),od.symtable,cloadvmtaddrnode.create(p),[],nil);
a call to the constrProcDef constructor in an execution-block. } p:=nil;
p1:=cloadvmtaddrnode.create(ctypenode.create(od)); typecheckpass(pcalln);
again:=true;
oldblock_type:=block_type;
block_type:=bt_body;
do_member_read(od,false,constrProcDef.procsym,p1,again,[], nil);
{ Check the number of parameters } if pcalln.nodetype<>errorn then
if (tcallnode(p1).para_count<constrProcDef.minparacount) then begin
CGMessagePos1(p.fileinfo,parser_e_wrong_parameter_size,od.typename+'.'+constrProcDef.procsym.prettyname); { Add attribute to attribute list which will be added
to the property which is defined next. }
block_type:=oldblock_type; if not assigned(rtti_attrs_def) then
rtti_attrs_def:=trtti_attribute_list.create;
{ Add attribute to attribute list which will be added rtti_attrs_def.addattribute(typesym,pcalln);
to the property which is defined next. } end;
if not assigned(rtti_attrs_def) then
rtti_attrs_def:=trtti_attribute_list.create;
rtti_attrs_def.addattribute(typeSym,p1);
end end
else else
Message(type_e_type_id_expected); begin
Message(type_e_type_id_expected);
{ try to recover by nevertheless reading the parameters (if any) }
read_attr_paras.free;
end;
p.free; p.free;
consume(_RECKKLAMMER); consume(_RECKKLAMMER);