When checking whether the current specialization was already done before we also need to check the globalsymtable if we're currently in the implementation section. Otherwise the specialization will be generated twice and will result in a "duplicate identifier" error. This fixes mantis .

git-svn-id: trunk@19818 -
This commit is contained in:
svenbarth 2011-12-11 16:03:55 +00:00
parent 5ffba57b51
commit fca525a85b
5 changed files with 118 additions and 2 deletions

3
.gitattributes vendored
View File

@ -11955,6 +11955,9 @@ tests/webtbs/tw20796b.pp svneol=native#text/pascal
tests/webtbs/tw20796c.pp svneol=native#text/pascal
tests/webtbs/tw20821.pp svneol=native#text/pascal
tests/webtbs/tw20836.pp svneol=native#text/pascal
tests/webtbs/tw20872a.pp svneol=native#text/pascal
tests/webtbs/tw20872b.pp svneol=native#text/pascal
tests/webtbs/tw20872c.pp svneol=native#text/pascal
tests/webtbs/tw2109.pp svneol=native#text/plain
tests/webtbs/tw2110.pp svneol=native#text/plain
tests/webtbs/tw2128.pp svneol=native#text/plain

View File

@ -83,6 +83,7 @@ uses
old_current_genericdef,old_current_specializedef : tstoreddef;
tempst : tglobalsymtable;
old_block_type: tblock_type;
hashedid: thashedidstring;
begin
{ retrieve generic def that we are going to replace }
genericdef:=tstoreddef(tt);
@ -306,13 +307,28 @@ uses
{ Can we reuse an already specialized type? }
if not assigned(tt) then
begin
srsym:=tsym(specializest.find(uspecializename));
hashedid.id:=uspecializename;
srsym:=tsym(specializest.findwithhash(hashedid));
if assigned(srsym) then
begin
if srsym.typ<>typesym then
internalerror(200710171);
tt:=ttypesym(srsym).typedef;
end;
end
else
{ the generic could have been specialized in the globalsymtable
already, so search there as well }
if specializest<>current_module.globalsymtable then
begin
srsym:=tsym(current_module.globalsymtable.findwithhash(hashedid));
if assigned(srsym) then
begin
if srsym.typ<>typesym then
internalerror(2011121101);
tt:=ttypesym(srsym).typedef;
end;
end;
end;
if not assigned(tt) then

30
tests/webtbs/tw20872a.pp Normal file
View File

@ -0,0 +1,30 @@
unit tw20872a;
{$MODE delphi}
interface
type
TWrapper<TValue> = class end;
TTestClass = class
strict private
FWrapper: TWrapper<Integer>; { Using inline specialization }
public
constructor Create;
destructor Destroy; override;
end;
implementation
constructor TTestClass.Create;
begin
FWrapper := TWrapper<Integer>.Create; { Duplicate identifier error here }
end;
destructor TTestClass.Destroy;
begin
FWrapper.Free;
end;
end.

32
tests/webtbs/tw20872b.pp Normal file
View File

@ -0,0 +1,32 @@
unit tw20872b;
{$MODE delphi}
interface
type
TWrapper<TValue> = class end;
TTestClass = class
strict private
type TSpecializedWrapper = TWrapper<Integer>;
strict private
FWrapper: TSpecializedWrapper; { Using traditional workaround }
public
constructor Create;
destructor Destroy; override;
end;
implementation
constructor TTestClass.Create;
begin
FWrapper := TWrapper<Integer>.Create; { Duplicate identifier error here }
end;
destructor TTestClass.Destroy;
begin
FWrapper.Free;
end;
end.

35
tests/webtbs/tw20872c.pp Normal file
View File

@ -0,0 +1,35 @@
unit tw20872c;
{$MODE delphi}
interface
type
TWrapper<TValue> = class end;
TTestClass = class
strict private
type TSpecializedWrapper = TWrapper<Integer>;
strict private
FWrapper: TSpecializedWrapper; { Using traditional workaround }
public
constructor Create;
destructor Destroy; override;
end;
implementation
constructor TTestClass.Create;
type
TLocalSpecializedWrapper =
TWrapper<Integer>; { Duplicate identifier error here }
begin
FWrapper := TLocalSpecializedWrapper.Create;
end;
destructor TTestClass.Destroy;
begin
FWrapper.Free;
end;
end.