From 9fcff238f11a55187ccdce5772f53c7cdc4a614f Mon Sep 17 00:00:00 2001 From: florian <florian@freepascal.org> Date: Fri, 6 Apr 2012 20:35:18 +0000 Subject: [PATCH] * 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 - --- .gitattributes | 1 + compiler/ptype.pas | 62 ++++++++++++++++++++++++----------------- tests/webtbs/tw21592.pp | 14 ++++++++++ 3 files changed, 51 insertions(+), 26 deletions(-) create mode 100644 tests/webtbs/tw21592.pp diff --git a/.gitattributes b/.gitattributes index d4b020fcf8..307e70d59a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -12310,6 +12310,7 @@ tests/webtbs/tw21472.pp svneol=native#text/pascal tests/webtbs/tw21551.pp svneol=native#text/plain tests/webtbs/tw2158.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/tw2163.pp svneol=native#text/plain tests/webtbs/tw2176.pp svneol=native#text/plain diff --git a/compiler/ptype.pas b/compiler/ptype.pas index eb662085f4..6222a11168 100644 --- a/compiler/ptype.pas +++ b/compiler/ptype.pas @@ -1059,6 +1059,7 @@ implementation var old_current_genericdef, old_current_specializedef: tstoreddef; + first, old_parse_generic: boolean; begin old_current_genericdef:=current_genericdef; @@ -1067,8 +1068,28 @@ implementation current_genericdef:=nil; current_specializedef:=nil; - arrdef:=nil; + first:=true; + arrdef:=tarraydef.create(0,0,s32inttype); 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? } if try_to_consume(_LECKKLAMMER) then begin @@ -1136,17 +1157,23 @@ implementation pt.free; end; - { if the array is already created add the new arrray - as element of the existing array, otherwise create a new array } - if assigned(arrdef) then + { if we are not at the first dimension, add the new arrray + as element of the existing array, otherwise modify the existing array } + if not(first) then begin arrdef.elementdef:=tarraydef.create(lowval.svalue,highval.svalue,indexdef); + { push new symtable } + symtablestack.pop(arrdef.symtable); arrdef:=tarraydef(arrdef.elementdef); + symtablestack.push(arrdef.symtable); end else begin - arrdef:=tarraydef.create(lowval.svalue,highval.svalue,indexdef); + arrdef.lowrange:=lowval.svalue; + arrdef.highrange:=highval.svalue; + arrdef.rangedef:=indexdef; def:=arrdef; + first:=false; end; if is_packed then include(arrdef.arrayoptions,ado_IsBitPacked); @@ -1162,30 +1189,12 @@ implementation begin if is_packed then 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); def:=arrdef; 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); read_anon_type(tt2,true); { set element type of the last array definition } @@ -1203,6 +1212,7 @@ implementation current_specializedef:=old_current_specializedef; end; + function procvar_dec(genericdef:tstoreddef;genericlist:TFPObjectList):tdef; var is_func:boolean; diff --git a/tests/webtbs/tw21592.pp b/tests/webtbs/tw21592.pp new file mode 100644 index 0000000000..538e9d7ae4 --- /dev/null +++ b/tests/webtbs/tw21592.pp @@ -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.