浏览代码

* 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 -
svenbarth 6 年之前
父节点
当前提交
db37146f12
共有 1 个文件被更改,包括 46 次插入33 次删除
  1. 46 33
      compiler/pdecl.pas

+ 46 - 33
compiler/pdecl.pas

@@ -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;
-        again : boolean;
+        p,paran,pcalln : tnode;
         od : tobjectdef;
         od : tobjectdef;
-        constrSym : tsymentry;
-        constrProcDef : tprocdef;
-        typeSym : ttypesym;
-        oldblock_type : tblock_type;
+        constrsym : tsymentry;
+        typesym : ttypesym;
       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);
-            if constrSym.typ<>procsym then
+            constrsym:=find_create_constructor(od);
+            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
-              a call to the constrProcDef constructor in an execution-block. }
-            p1:=cloadvmtaddrnode.create(ctypenode.create(od));
-            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 (tcallnode(p1).para_count<constrProcDef.minparacount) then
-               CGMessagePos1(p.fileinfo,parser_e_wrong_parameter_size,od.typename+'.'+constrProcDef.procsym.prettyname);
-
-            block_type:=oldblock_type;
-
-            { Add attribute to attribute list which will be added
-              to the property which is defined next. }
-            if not assigned(rtti_attrs_def) then
-              rtti_attrs_def:=trtti_attribute_list.create;
-            rtti_attrs_def.addattribute(typeSym,p1);
+
+            pcalln:=ccallnode.create(paran,tprocsym(constrsym),od.symtable,cloadvmtaddrnode.create(p),[],nil);
+            p:=nil;
+            typecheckpass(pcalln);
+
+            if pcalln.nodetype<>errorn then
+              begin
+                { Add attribute to attribute list which will be added
+                  to the property which is defined next. }
+                if not assigned(rtti_attrs_def) then
+                  rtti_attrs_def:=trtti_attribute_list.create;
+                rtti_attrs_def.addattribute(typesym,pcalln);
+              end;
           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);