* 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 -
This commit is contained in:
Jonas Maebe 2014-10-06 20:53:12 +00:00
parent 6cc74cd115
commit 864b36fbe5
4 changed files with 42 additions and 29 deletions

View File

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

View File

@ -674,7 +674,10 @@ implementation
internalerror(2014012002); internalerror(2014012002);
res:=current_module.llvmdefs.FindOrAdd(@typename[1],length(typename)); res:=current_module.llvmdefs.FindOrAdd(@typename[1],length(typename));
if not assigned(res^.Data) then 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); result:=trecorddef(res^.Data);
end; end;

View File

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

View File

@ -298,7 +298,8 @@ interface
variantrecdesc : pvariantrecdesc; variantrecdesc : pvariantrecdesc;
isunion : boolean; isunion : boolean;
constructor create(const n:string; p:TSymtable);virtual; 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); constructor ppuload(ppufile:tcompilerppufile);
destructor destroy;override; destructor destroy;override;
function getcopy : tstoreddef;override; function getcopy : tstoreddef;override;
@ -3945,11 +3946,8 @@ implementation
end; end;
constructor trecorddef.create_global_from_deflist(n: string; fieldtypes: tfplist; packrecords: shortint); constructor trecorddef.create_global_internal(n: string; packrecords: shortint);
var var
i: longint;
hdef: tdef;
sym: tfieldvarsym;
oldsymtablestack: tsymtablestack; oldsymtablestack: tsymtablestack;
definedname: boolean; definedname: boolean;
begin begin
@ -3965,12 +3963,6 @@ implementation
symtable:=trecordsymtable.create(n,packrecords); symtable:=trecordsymtable.create(n,packrecords);
symtable.defowner:=self; symtable.defowner:=self;
isunion:=false; 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); inherited create(n,recorddef);
if assigned(current_module.localsymtable) then if assigned(current_module.localsymtable) then
begin begin
@ -3990,6 +3982,20 @@ implementation
end; 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); constructor trecorddef.ppuload(ppufile:tcompilerppufile);
procedure readvariantrecdesc(var variantrecdesc : pvariantrecdesc); procedure readvariantrecdesc(var variantrecdesc : pvariantrecdesc);