Răsfoiți Sursa

* create the recorddef at the start when building an anonymous recorddef,
so that we can already refer to its def while we are sill parsing
individual elements

git-svn-id: branches/hlcgllvm@28750 -

Jonas Maebe 10 ani în urmă
părinte
comite
864b36fbe5
4 a modificat fișierele cu 42 adăugiri și 29 ștergeri
  1. 9 8
      compiler/aasmcnst.pas
  2. 4 1
      compiler/llvm/llvmdef.pas
  3. 12 9
      compiler/llvm/nllvmtcon.pas
  4. 17 11
      compiler/symdef.pas

+ 9 - 8
compiler/aasmcnst.pas

@@ -151,8 +151,8 @@ type
         b) the def of the record should be automatically constructed based on
            the types of the emitted fields
      }
-     procedure begin_anonymous_record; virtual;
-     function end_anonymous_record(const optionalname: string; packrecords: shortint): trecorddef; virtual;
+     procedure begin_anonymous_record(const optionalname: string; packrecords: shortint); virtual;
+     function end_anonymous_record: trecorddef; virtual;
 
      { The next group of routines are for constructing complex expressions.
        While parsing a typed constant these operators are encountered from
@@ -538,7 +538,7 @@ implementation
        current_asmdata.getdatalabel(result.lab);
        startlab:=result.lab;
        result.ofs:=0;
-       begin_anonymous_record;
+       begin_anonymous_record('$'+get_dynstring_rec_name(stringtype,false,len),sizeof(pint));
        string_symofs:=get_string_symofs(stringtype,false);
        { encoding }
        emit_tai(tai_const.create_16bit(encoding),u16inttype);
@@ -621,7 +621,7 @@ implementation
        datatcb.maybe_begin_aggregate(datadef);
        datatcb.emit_tai(tai_string.create_pchar(s,len+1),datadef);
        datatcb.maybe_end_aggregate(datadef);
-       ansistrrecdef:=datatcb.end_anonymous_record('$'+get_dynstring_rec_name(st_ansistring,false,len),sizeof(pint));
+       ansistrrecdef:=datatcb.end_anonymous_record;
        if NewSection then
          sectype:=sec_rodata_norel
        else
@@ -644,7 +644,7 @@ implementation
        strlength:=getlengthwidestring(pcompilerwidestring(data));
        if winlike then
          begin
-           datatcb.begin_anonymous_record;
+           datatcb.begin_anonymous_record('$'+get_dynstring_rec_name(st_widestring,true,strlength),sizeof(pint));
            current_asmdata.getdatalabel(result.lab);
            datatcb.emit_tai(Tai_const.Create_32bit(strlength*cwidechartype.size),s32inttype);
            { can we optimise by placing the string constant label at the
@@ -672,7 +672,7 @@ implementation
            { ending #0 }
            datatcb.emit_tai(Tai_const.Create_16bit(0),cwidechartype);
            datatcb.maybe_end_aggregate(datadef);
-           uniwidestrrecdef:=datatcb.end_anonymous_record('$'+get_dynstring_rec_name(st_widestring,winlike,strlength),sizeof(pint));
+           uniwidestrrecdef:=datatcb.end_anonymous_record;
          end
        else
          { code generation for other sizes must be written }
@@ -693,13 +693,14 @@ implementation
        { do nothing }
      end;
 
-   procedure ttai_lowleveltypedconstbuilder.begin_anonymous_record;
+
+   procedure ttai_lowleveltypedconstbuilder.begin_anonymous_record(const optionalname: string; packrecords: shortint);
      begin
        { do nothing }
      end;
 
 
-   function ttai_lowleveltypedconstbuilder.end_anonymous_record(const optionalname: string; packrecords: shortint): trecorddef;
+   function ttai_lowleveltypedconstbuilder.end_anonymous_record: trecorddef;
      begin
        { do nothing }
        result:=nil;

+ 4 - 1
compiler/llvm/llvmdef.pas

@@ -674,7 +674,10 @@ implementation
           internalerror(2014012002);
         res:=current_module.llvmdefs.FindOrAdd(@typename[1],length(typename));
         if not assigned(res^.Data) then
-          res^.Data:=crecorddef.create_global_from_deflist(typename,fieldtypes,packrecords);
+          begin
+            res^.Data:=crecorddef.create_global_internal(typename,packrecords);
+            trecorddef(res^.Data).add_fields_from_deflist(fieldtypes);
+          end;
         result:=trecorddef(res^.Data);
       end;
 

+ 12 - 9
compiler/llvm/nllvmtcon.pas

@@ -61,8 +61,8 @@ interface
       procedure emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef); override;
       procedure maybe_begin_aggregate(def: tdef); override;
       procedure maybe_end_aggregate(def: tdef); override;
-      procedure begin_anonymous_record; override;
-      function end_anonymous_record(const optionalname: string; packrecords: shortint): trecorddef; override;
+      procedure begin_anonymous_record(const optionalname: string; packrecords: shortint); override;
+      function end_anonymous_record: trecorddef; override;
       procedure queue_init(todef: tdef); override;
       procedure queue_vecn(def: tdef; const index: tconstexprint); override;
       procedure queue_subscriptn(def: tabstractrecorddef; vs: tfieldvarsym); override;
@@ -248,14 +248,17 @@ implementation
     end;
 
 
-  procedure tllvmtai_typedconstbuilder.begin_anonymous_record;
+  procedure tllvmtai_typedconstbuilder.begin_anonymous_record(const optionalname: string; packrecords: shortint);
+    var
+      recorddef: trecorddef;
     begin
       inherited;
-      begin_aggregate_intern(tck_record,nil);
+      recorddef:=crecorddef.create_global_internal(optionalname,packrecords);
+      begin_aggregate_intern(tck_record,recorddef);
     end;
 
 
-  function tllvmtai_typedconstbuilder.end_anonymous_record(const optionalname: string; packrecords: shortint): trecorddef;
+  function tllvmtai_typedconstbuilder.end_anonymous_record: trecorddef;
     var
       agg: tai_aggregatetypedconst;
       ele: tai_abstracttypedconst;
@@ -265,17 +268,17 @@ implementation
       if assigned(result) then
         exit;
       if not assigned(faggregates) or
-         (faggregates.count=0) then
+         (faggregates.count=0) or
+         (tai_aggregatetypedconst(faggregates[faggregates.count-1]).def.typ<>recorddef) then
         internalerror(2014080201);
       agg:=tai_aggregatetypedconst(faggregates[faggregates.count-1]);
       defs:=tfplist.create;
       for ele in agg do
         defs.add(ele.def);
-      result:=crecorddef.create_global_from_deflist(optionalname,defs,packrecords);
-      agg.def:=result;
+      result:=trecorddef(agg.def);
+      result.add_fields_from_deflist(defs);
       { already added to the asmlist if necessary }
       faggregates.count:=faggregates.count-1;
-      inherited;
     end;
 
 

+ 17 - 11
compiler/symdef.pas

@@ -298,7 +298,8 @@ interface
           variantrecdesc : pvariantrecdesc;
           isunion       : boolean;
           constructor create(const n:string; p:TSymtable);virtual;
-          constructor create_global_from_deflist(n: string; fieldtypes: tfplist; packrecords: shortint); virtual;
+          constructor create_global_internal(n: string; packrecords: shortint); virtual;
+          procedure add_fields_from_deflist(fieldtypes: tfplist);
           constructor ppuload(ppufile:tcompilerppufile);
           destructor destroy;override;
           function getcopy : tstoreddef;override;
@@ -3945,11 +3946,8 @@ implementation
       end;
 
 
-    constructor trecorddef.create_global_from_deflist(n: string; fieldtypes: tfplist; packrecords: shortint);
+    constructor trecorddef.create_global_internal(n: string; packrecords: shortint);
       var
-        i: longint;
-        hdef: tdef;
-        sym: tfieldvarsym;
         oldsymtablestack: tsymtablestack;
         definedname: boolean;
       begin
@@ -3965,12 +3963,6 @@ implementation
         symtable:=trecordsymtable.create(n,packrecords);
         symtable.defowner:=self;
         isunion:=false;
-        for i:=0 to fieldtypes.count-1 do
-          begin
-            sym:=cfieldvarsym.create('$f'+tostr(i),vs_value,tdef(fieldtypes[i]),[]);
-            symtable.insert(sym);
-            trecordsymtable(symtable).addfield(sym,vis_hidden);
-          end;
         inherited create(n,recorddef);
         if assigned(current_module.localsymtable) then
           begin
@@ -3990,6 +3982,20 @@ implementation
       end;
 
 
+    procedure trecorddef.add_fields_from_deflist(fieldtypes: tfplist);
+      var
+        i: longint;
+        sym: tfieldvarsym;
+      begin
+        for i:=0 to fieldtypes.count-1 do
+          begin
+            sym:=cfieldvarsym.create('$f'+tostr(i),vs_value,tdef(fieldtypes[i]),[]);
+            symtable.insert(sym);
+            trecordsymtable(symtable).addfield(sym,vis_hidden);
+          end;
+      end;
+
+
     constructor trecorddef.ppuload(ppufile:tcompilerppufile);
 
       procedure readvariantrecdesc(var variantrecdesc : pvariantrecdesc);