mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 17:09:09 +02:00
compiler: don't create enum defs for specializations declarations. Enums are stored in the unit symtables and generic declarations already add them there. Therefore specializations should search for enum defs declared by generics and use them instead of own.
git-svn-id: trunk@16686 -
This commit is contained in:
parent
360d102ea4
commit
7c33505916
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -9415,6 +9415,7 @@ tests/test/tgeneric23.pp svneol=native#text/pascal
|
||||
tests/test/tgeneric24.pp svneol=native#text/pascal
|
||||
tests/test/tgeneric25.pp svneol=native#text/pascal
|
||||
tests/test/tgeneric26.pp svneol=native#text/pascal
|
||||
tests/test/tgeneric27.pp svneol=native#text/pascal
|
||||
tests/test/tgeneric3.pp svneol=native#text/plain
|
||||
tests/test/tgeneric4.pp svneol=native#text/plain
|
||||
tests/test/tgeneric5.pp svneol=native#text/plain
|
||||
|
@ -1240,10 +1240,13 @@ implementation
|
||||
hdef : tdef;
|
||||
pd : tabstractprocdef;
|
||||
is_func,
|
||||
enumdupmsg, first : boolean;
|
||||
enumdupmsg, first, is_specialize : boolean;
|
||||
newtype : ttypesym;
|
||||
oldlocalswitches : tlocalswitches;
|
||||
bitpacking: boolean;
|
||||
stitem: psymtablestackitem;
|
||||
sym: tsym;
|
||||
st: tsymtable;
|
||||
begin
|
||||
def:=nil;
|
||||
case token of
|
||||
@ -1258,8 +1261,37 @@ implementation
|
||||
{ allow negativ value_str }
|
||||
l:=int64(-1);
|
||||
enumdupmsg:=false;
|
||||
aktenumdef:=tenumdef.create;
|
||||
{ check that we are not adding an enum from specialization
|
||||
we can't just use current_specializedef because of inner types
|
||||
like specialize array of record }
|
||||
is_specialize:=false;
|
||||
stitem:=symtablestack.stack;
|
||||
while assigned(stitem) do
|
||||
begin
|
||||
{ check records, classes and arrays because they can be specialized }
|
||||
if stitem^.symtable.symtabletype in [recordsymtable,ObjectSymtable,arraysymtable] then
|
||||
begin
|
||||
is_specialize:=is_specialize or (df_specialization in tstoreddef(stitem^.symtable.defowner).defoptions);
|
||||
stitem:=stitem^.next;
|
||||
end
|
||||
else
|
||||
break;
|
||||
end;
|
||||
if not is_specialize then
|
||||
aktenumdef:=tenumdef.create
|
||||
else
|
||||
aktenumdef:=nil;
|
||||
repeat
|
||||
{ if it is a specialization then search the first enum member
|
||||
and get the member owner instead of just created enumdef }
|
||||
if not assigned(aktenumdef) then
|
||||
begin
|
||||
searchsym(pattern,sym,st);
|
||||
if sym.typ=enumsym then
|
||||
aktenumdef:=tenumsym(sym).definition
|
||||
else
|
||||
internalerror(201101021);
|
||||
end;
|
||||
s:=orgpattern;
|
||||
defpos:=current_tokenpos;
|
||||
consume(_ID);
|
||||
@ -1303,12 +1335,16 @@ implementation
|
||||
else
|
||||
inc(l.svalue);
|
||||
first:=false;
|
||||
storepos:=current_tokenpos;
|
||||
current_tokenpos:=defpos;
|
||||
tenumsymtable(aktenumdef.symtable).insert(tenumsym.create(s,aktenumdef,longint(l.svalue)));
|
||||
if not (cs_scopedenums in current_settings.localswitches) then
|
||||
tstoredsymtable(aktenumdef.owner).insert(tenumsym.create(s,aktenumdef,longint(l.svalue)));
|
||||
current_tokenpos:=storepos;
|
||||
{ don't generate enum members is this is a specialization because aktenumdef is copied from the generic type }
|
||||
if not is_specialize then
|
||||
begin
|
||||
storepos:=current_tokenpos;
|
||||
current_tokenpos:=defpos;
|
||||
tenumsymtable(aktenumdef.symtable).insert(tenumsym.create(s,aktenumdef,longint(l.svalue)));
|
||||
if not (cs_scopedenums in current_settings.localswitches) then
|
||||
tstoredsymtable(aktenumdef.owner).insert(tenumsym.create(s,aktenumdef,longint(l.svalue)));
|
||||
current_tokenpos:=storepos;
|
||||
end;
|
||||
until not try_to_consume(_COMMA);
|
||||
def:=aktenumdef;
|
||||
consume(_RKLAMMER);
|
||||
|
@ -1,4 +1,4 @@
|
||||
program project1;
|
||||
program tgeneric24;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$apptype console}
|
||||
|
23
tests/test/tgeneric27.pp
Normal file
23
tests/test/tgeneric27.pp
Normal file
@ -0,0 +1,23 @@
|
||||
program tgeneric27;
|
||||
|
||||
{ check that specialization does not add enum members to the static symtable and reuses the generic enum definintion }
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
type
|
||||
generic TRecArr<T> = array[0..1] of record
|
||||
case enum:(one, two, three) of
|
||||
one: (F: Integer);
|
||||
two: (Z: Byte);
|
||||
three: (Y: PChar);
|
||||
end;
|
||||
|
||||
var
|
||||
A: specialize TRecArr<Integer>;
|
||||
B: specialize TRecArr<String>;
|
||||
begin
|
||||
A[0].enum := one;
|
||||
B[0].enum := one;
|
||||
if A[0].enum <> B[0].enum then
|
||||
halt(1);
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user