mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-29 14:40:25 +02:00
* create and push array def before the array range is parsed, this allows generic parameters to be used in the range definition, resolves #21592
git-svn-id: trunk@20725 -
This commit is contained in:
parent
7a07a6c544
commit
9fcff238f1
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -12310,6 +12310,7 @@ tests/webtbs/tw21472.pp svneol=native#text/pascal
|
|||||||
tests/webtbs/tw21551.pp svneol=native#text/plain
|
tests/webtbs/tw21551.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw2158.pp svneol=native#text/plain
|
tests/webtbs/tw2158.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw2159.pp svneol=native#text/plain
|
tests/webtbs/tw2159.pp svneol=native#text/plain
|
||||||
|
tests/webtbs/tw21592.pp svneol=native#text/pascal
|
||||||
tests/webtbs/tw21593.pp svneol=native#text/pascal
|
tests/webtbs/tw21593.pp svneol=native#text/pascal
|
||||||
tests/webtbs/tw2163.pp svneol=native#text/plain
|
tests/webtbs/tw2163.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw2176.pp svneol=native#text/plain
|
tests/webtbs/tw2176.pp svneol=native#text/plain
|
||||||
|
@ -1059,6 +1059,7 @@ implementation
|
|||||||
var
|
var
|
||||||
old_current_genericdef,
|
old_current_genericdef,
|
||||||
old_current_specializedef: tstoreddef;
|
old_current_specializedef: tstoreddef;
|
||||||
|
first,
|
||||||
old_parse_generic: boolean;
|
old_parse_generic: boolean;
|
||||||
begin
|
begin
|
||||||
old_current_genericdef:=current_genericdef;
|
old_current_genericdef:=current_genericdef;
|
||||||
@ -1067,8 +1068,28 @@ implementation
|
|||||||
|
|
||||||
current_genericdef:=nil;
|
current_genericdef:=nil;
|
||||||
current_specializedef:=nil;
|
current_specializedef:=nil;
|
||||||
arrdef:=nil;
|
first:=true;
|
||||||
|
arrdef:=tarraydef.create(0,0,s32inttype);
|
||||||
consume(_ARRAY);
|
consume(_ARRAY);
|
||||||
|
|
||||||
|
{ usage of specialized type inside its generic template }
|
||||||
|
if assigned(genericdef) then
|
||||||
|
current_specializedef:=arrdef
|
||||||
|
{ reject declaration of generic class inside generic class }
|
||||||
|
else if assigned(genericlist) then
|
||||||
|
current_genericdef:=arrdef;
|
||||||
|
symtablestack.push(arrdef.symtable);
|
||||||
|
insert_generic_parameter_types(arrdef,genericdef,genericlist);
|
||||||
|
{ there are two possibilties for the following to be true:
|
||||||
|
* the array declaration itself is generic
|
||||||
|
* the array is declared inside a generic
|
||||||
|
in both cases we need "parse_generic" and "current_genericdef"
|
||||||
|
so that e.g. specializations of another generic inside the
|
||||||
|
current generic can be used (either inline ones or "type" ones) }
|
||||||
|
parse_generic:=(df_generic in arrdef.defoptions) or old_parse_generic;
|
||||||
|
if parse_generic and not assigned(current_genericdef) then
|
||||||
|
current_genericdef:=old_current_genericdef;
|
||||||
|
|
||||||
{ open array? }
|
{ open array? }
|
||||||
if try_to_consume(_LECKKLAMMER) then
|
if try_to_consume(_LECKKLAMMER) then
|
||||||
begin
|
begin
|
||||||
@ -1136,17 +1157,23 @@ implementation
|
|||||||
pt.free;
|
pt.free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ if the array is already created add the new arrray
|
{ if we are not at the first dimension, add the new arrray
|
||||||
as element of the existing array, otherwise create a new array }
|
as element of the existing array, otherwise modify the existing array }
|
||||||
if assigned(arrdef) then
|
if not(first) then
|
||||||
begin
|
begin
|
||||||
arrdef.elementdef:=tarraydef.create(lowval.svalue,highval.svalue,indexdef);
|
arrdef.elementdef:=tarraydef.create(lowval.svalue,highval.svalue,indexdef);
|
||||||
|
{ push new symtable }
|
||||||
|
symtablestack.pop(arrdef.symtable);
|
||||||
arrdef:=tarraydef(arrdef.elementdef);
|
arrdef:=tarraydef(arrdef.elementdef);
|
||||||
|
symtablestack.push(arrdef.symtable);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
arrdef:=tarraydef.create(lowval.svalue,highval.svalue,indexdef);
|
arrdef.lowrange:=lowval.svalue;
|
||||||
|
arrdef.highrange:=highval.svalue;
|
||||||
|
arrdef.rangedef:=indexdef;
|
||||||
def:=arrdef;
|
def:=arrdef;
|
||||||
|
first:=false;
|
||||||
end;
|
end;
|
||||||
if is_packed then
|
if is_packed then
|
||||||
include(arrdef.arrayoptions,ado_IsBitPacked);
|
include(arrdef.arrayoptions,ado_IsBitPacked);
|
||||||
@ -1162,30 +1189,12 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if is_packed then
|
if is_packed then
|
||||||
Message(parser_e_packed_dynamic_open_array);
|
Message(parser_e_packed_dynamic_open_array);
|
||||||
arrdef:=tarraydef.create(0,-1,s32inttype);
|
arrdef.lowrange:=0;
|
||||||
|
arrdef.highrange:=-1;
|
||||||
|
arrdef.rangedef:=s32inttype;
|
||||||
include(arrdef.arrayoptions,ado_IsDynamicArray);
|
include(arrdef.arrayoptions,ado_IsDynamicArray);
|
||||||
def:=arrdef;
|
def:=arrdef;
|
||||||
end;
|
end;
|
||||||
if assigned(arrdef) then
|
|
||||||
begin
|
|
||||||
{ usage of specialized type inside its generic template }
|
|
||||||
if assigned(genericdef) then
|
|
||||||
current_specializedef:=arrdef
|
|
||||||
{ reject declaration of generic class inside generic class }
|
|
||||||
else if assigned(genericlist) then
|
|
||||||
current_genericdef:=arrdef;
|
|
||||||
symtablestack.push(arrdef.symtable);
|
|
||||||
insert_generic_parameter_types(arrdef,genericdef,genericlist);
|
|
||||||
{ there are two possibilties for the following to be true:
|
|
||||||
* the array declaration itself is generic
|
|
||||||
* the array is declared inside a generic
|
|
||||||
in both cases we need "parse_generic" and "current_genericdef"
|
|
||||||
so that e.g. specializations of another generic inside the
|
|
||||||
current generic can be used (either inline ones or "type" ones) }
|
|
||||||
parse_generic:=(df_generic in arrdef.defoptions) or old_parse_generic;
|
|
||||||
if parse_generic and not assigned(current_genericdef) then
|
|
||||||
current_genericdef:=old_current_genericdef;
|
|
||||||
end;
|
|
||||||
consume(_OF);
|
consume(_OF);
|
||||||
read_anon_type(tt2,true);
|
read_anon_type(tt2,true);
|
||||||
{ set element type of the last array definition }
|
{ set element type of the last array definition }
|
||||||
@ -1203,6 +1212,7 @@ implementation
|
|||||||
current_specializedef:=old_current_specializedef;
|
current_specializedef:=old_current_specializedef;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function procvar_dec(genericdef:tstoreddef;genericlist:TFPObjectList):tdef;
|
function procvar_dec(genericdef:tstoreddef;genericlist:TFPObjectList):tdef;
|
||||||
var
|
var
|
||||||
is_func:boolean;
|
is_func:boolean;
|
||||||
|
14
tests/webtbs/tw21592.pp
Normal file
14
tests/webtbs/tw21592.pp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{$MODE DELPHI}
|
||||||
|
|
||||||
|
type
|
||||||
|
TBytesOverlay<T> = array [0..SizeOf(T) - 1] of Byte;
|
||||||
|
{ Error: Identifier not found "T" }
|
||||||
|
|
||||||
|
var
|
||||||
|
a : TBytesOverlay<Byte>;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if sizeof(a)<>1 then
|
||||||
|
halt(1);
|
||||||
|
writeln('ok');
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user