Explorar el Código

* generate construction function for the attributes used in a unit using a more straight forward approach
ToDo: "collect" attributes of same type and same argument list and generate constructor only once for them

git-svn-id: trunk@42394 -

svenbarth hace 6 años
padre
commit
ced3885dbb

+ 5 - 0
compiler/fmodule.pas

@@ -207,6 +207,9 @@ interface
         { contains a list of specializations for which the method bodies need
         { contains a list of specializations for which the method bodies need
           to be generated }
           to be generated }
         pendingspecializations : TFPHashObjectList;
         pendingspecializations : TFPHashObjectList;
+        { list of attributes that are used and thus need their construction
+          functions generated }
+        used_rtti_attrs: tfpobjectlist;
 
 
         { this contains a list of units that needs to be waited for until the
         { this contains a list of units that needs to be waited for until the
           unit can be finished (code generated, etc.); this is needed to handle
           unit can be finished (code generated, etc.); this is needed to handle
@@ -611,6 +614,7 @@ implementation
         pendingspecializations:=tfphashobjectlist.create(false);
         pendingspecializations:=tfphashobjectlist.create(false);
         waitingforunit:=tfpobjectlist.create(false);
         waitingforunit:=tfpobjectlist.create(false);
         waitingunits:=tfpobjectlist.create(false);
         waitingunits:=tfpobjectlist.create(false);
+        used_rtti_attrs:=tfpobjectlist.create(false);
         globalsymtable:=nil;
         globalsymtable:=nil;
         localsymtable:=nil;
         localsymtable:=nil;
         globalmacrosymtable:=nil;
         globalmacrosymtable:=nil;
@@ -709,6 +713,7 @@ implementation
         pendingspecializations.free;
         pendingspecializations.free;
         waitingforunit.free;
         waitingforunit.free;
         waitingunits.free;
         waitingunits.free;
+        used_rtti_attrs.free;
         stringdispose(asmprefix);
         stringdispose(asmprefix);
         stringdispose(deprecatedmsg);
         stringdispose(deprecatedmsg);
         stringdispose(namespace);
         stringdispose(namespace);

+ 3 - 1
compiler/ncgrtti.pas

@@ -1871,7 +1871,9 @@ implementation
 
 
           tbltcb.emit_procdef_const(tprocdef(tcallnode(attr.constructorcall).procdefinition));
           tbltcb.emit_procdef_const(tprocdef(tcallnode(attr.constructorcall).procdefinition));
 
 
-          tbltcb.emit_tai(tai_const.Createname(attr.symbolname,AT_DATA_FORCEINDIRECT,0),cpointerdef.getreusable(ttypesym(attr.typesym).typedef));
+          if not assigned(attr.constructorpd) then
+            internalerror(2019071004);
+          tbltcb.emit_procdef_const(tprocdef(attr.constructorpd));
 
 
           write_args(tbltcb,attr);
           write_args(tbltcb,attr);
 
 

+ 0 - 1
compiler/pdecl.pas

@@ -1052,7 +1052,6 @@ implementation
                       this object }
                       this object }
                     if assigned(rtti_attrs_def) then
                     if assigned(rtti_attrs_def) then
                       begin
                       begin
-                        add_synthetic_rtti_function_declarations(rtti_attrs_def,hdef.typesym.Name);
                         trtti_attribute_list.bind(rtti_attrs_def,tobjectdef(hdef).rtti_attribute_list);
                         trtti_attribute_list.bind(rtti_attrs_def,tobjectdef(hdef).rtti_attribute_list);
                       end;
                       end;
 
 

+ 0 - 1
compiler/pdecobj.pas

@@ -216,7 +216,6 @@ implementation
           end;
           end;
         if assigned(rtti_attrs_def) then
         if assigned(rtti_attrs_def) then
           begin
           begin
-            add_synthetic_rtti_function_declarations(rtti_attrs_def,current_structdef.RttiName+'_'+p.RealName);
             trtti_attribute_list.bind(rtti_attrs_def,p.rtti_attribute_list);
             trtti_attribute_list.bind(rtti_attrs_def,p.rtti_attribute_list);
           end;
           end;
 
 

+ 6 - 0
compiler/pmodules.pas

@@ -1217,6 +1217,9 @@ type
          add_synthetic_method_implementations(current_module.globalsymtable);
          add_synthetic_method_implementations(current_module.globalsymtable);
          add_synthetic_method_implementations(current_module.localsymtable);
          add_synthetic_method_implementations(current_module.localsymtable);
 
 
+         { generate construction functions for all attributes in the unit }
+         generate_attr_constrs(current_module.used_rtti_attrs);
+
          { if the unit contains ansi/widestrings, initialization and
          { if the unit contains ansi/widestrings, initialization and
            finalization code must be forced }
            finalization code must be forced }
          force_init_final:=tglobalsymtable(current_module.globalsymtable).needs_init_final or
          force_init_final:=tglobalsymtable(current_module.globalsymtable).needs_init_final or
@@ -2236,6 +2239,9 @@ type
            the compiler }
            the compiler }
          add_synthetic_method_implementations(current_module.localsymtable);
          add_synthetic_method_implementations(current_module.localsymtable);
 
 
+         { generate construction functions for all attributes in the program }
+         generate_attr_constrs(current_module.used_rtti_attrs);
+
          { should we force unit initialization? }
          { should we force unit initialization? }
          force_init_final:=tstaticsymtable(current_module.localsymtable).needs_init_final;
          force_init_final:=tstaticsymtable(current_module.localsymtable).needs_init_final;
          if force_init_final or cnodeutils.force_init then
          if force_init_final or cnodeutils.force_init then

+ 58 - 3
compiler/symcreat.pas

@@ -27,7 +27,7 @@ unit symcreat;
 interface
 interface
 
 
   uses
   uses
-    finput,tokens,scanner,globtype,
+    finput,tokens,scanner,globtype,cclasses,
     aasmdata,
     aasmdata,
     symconst,symbase,symtype,symdef,symsym,
     symconst,symbase,symtype,symdef,symsym,
     node;
     node;
@@ -124,14 +124,15 @@ interface
   procedure call_through_new_name(orgpd: tprocdef; const newname: TSymStr);
   procedure call_through_new_name(orgpd: tprocdef; const newname: TSymStr);
 
 
   function generate_pkg_stub(pd:tprocdef):tnode;
   function generate_pkg_stub(pd:tprocdef):tnode;
+  procedure generate_attr_constrs(attrs:tfpobjectlist);
 
 
 
 
 
 
 implementation
 implementation
 
 
   uses
   uses
-    cutils,cclasses,globals,verbose,systems,comphook,fmodule,constexp,
-    symtable,defutil,symutil,
+    cutils,globals,verbose,systems,comphook,fmodule,constexp,
+    symtable,defutil,symutil,procinfo,
     pbase,pdecobj,pdecsub,psub,ptconst,pparautl,
     pbase,pdecobj,pdecsub,psub,ptconst,pparautl,
 {$ifdef jvm}
 {$ifdef jvm}
     pjvm,jvmdef,
     pjvm,jvmdef,
@@ -1491,5 +1492,59 @@ implementation
         result:=cnothingnode.create;
         result:=cnothingnode.create;
     end;
     end;
 
 
+  procedure generate_attr_constrs(attrs:tfpobjectlist);
+    var
+      ps : tprocsym;
+      pd : tprocdef;
+      pi : tcgprocinfo;
+      i : sizeint;
+      attr : trtti_attribute;
+    begin
+      if attrs.count=0 then
+        exit;
+      { if this isn't set then this unit shouldn't have any attributes }
+      if not assigned(class_tcustomattribute) then
+        internalerror(2019071003);
+      for i:=0 to attrs.count-1 do
+        begin
+          attr:=trtti_attribute(attrs[i]);
+          {Generate a procsym for main}
+          ps:=cprocsym.create('$rttiattrconstr$'+tostr(i));
+          { always register the symbol }
+          ps.register_sym;
+          { the RTTI always references this symbol }
+          inc(ps.refs);
+          current_module.localsymtable.insert(ps);
+          pd:=cprocdef.create(normal_function_level,true);
+          { always register the def }
+          pd.register_def;
+          pd.procsym:=ps;
+          ps.ProcdefList.Add(pd);
+          { set procdef options }
+          pd.proctypeoption:=potype_function;
+          pd.proccalloption:=pocall_default;
+          include(pd.procoptions,po_hascallingconvention);
+          pd.returndef:=class_tcustomattribute;
+          insert_funcret_para(pd);
+          pd.calcparas;
+          pd.forwarddef:=false;
+          pd.setmangledname(ps.name);
+          pd.aliasnames.insert(pd.mangledname);
+          handle_calling_convention(pd,hcc_default_actions_impl);
+          { set procinfo and current_procinfo.procdef }
+          pi:=tcgprocinfo(cprocinfo.create(nil));
+          pi.procdef:=pd;
+          { we always do a call, namely to the constructor }
+          include(pi.flags,pi_do_call);
+          insert_funcret_local(pd);
+          pi.code:=cassignmentnode.create(
+                      cloadnode.create(pd.funcretsym,pd.localst),
+                      attr.constructorcall.getcopy
+                    );
+          pi.generate_code;
+          attr.constructorpd:=pd;
+        end;
+    end;
+
 end.
 end.
 
 

+ 2 - 0
compiler/symdef.pas

@@ -63,6 +63,7 @@ interface
        trtti_attribute = class
        trtti_attribute = class
           typesym         : tsym;
           typesym         : tsym;
           constructorcall : tnode;
           constructorcall : tnode;
+          constructorpd   : tdef;
           paras           : array of tnode;
           paras           : array of tnode;
           symbolname      : string;
           symbolname      : string;
           destructor destroy;override;
           destructor destroy;override;
@@ -2915,6 +2916,7 @@ implementation
           exit;
           exit;
         if dangling.is_bound then
         if dangling.is_bound then
           internalerror(2019071002);
           internalerror(2019071002);
+        current_module.used_rtti_attrs.concatlistcopy(dangling.rtti_attributes);
         dangling.is_bound:=true;
         dangling.is_bound:=true;
         owned:=dangling;
         owned:=dangling;
         dangling:=nil;
         dangling:=nil;