Browse Source

fcl-passrc: resolver: for e in TArrEnum do

git-svn-id: trunk@37767 -
Mattias Gaertner 7 years ago
parent
commit
b1a45494d3
2 changed files with 39 additions and 2 deletions
  1. 32 2
      packages/fcl-passrc/src/pasresolver.pp
  2. 7 0
      packages/fcl-passrc/tests/tcresolver.pas

+ 32 - 2
packages/fcl-passrc/src/pasresolver.pp

@@ -5294,14 +5294,34 @@ begin
     try
       OrigStartResolved:=StartResolved;
       if StartResolved.IdentEl is TPasType then
+        begin
         // e.g. for e in TEnum do
-        InRange:=EvalTypeRange(StartResolved.TypeEl,[])
+        TypeEl:=ResolveAliasType(StartResolved.TypeEl);
+        if TypeEl is TPasArrayType then
+          begin
+          if length(TPasArrayType(TypeEl).Ranges)=1 then
+            InRange:=Eval(TPasArrayType(TypeEl).Ranges[0],[refConst]);
+          end;
+        if InRange=nil then
+          InRange:=EvalTypeRange(TypeEl,[]);
+        {$IFDEF VerbosePasResolver}
+        if InRange<>nil then
+          writeln('TPasResolver.ResolveImplForLoop in type: InRange=',InRange.AsDebugString)
+        else
+          writeln('TPasResolver.ResolveImplForLoop in type: InRange=nil');
+        {$ENDIF}
+        end
       else if rrfReadable in StartResolved.Flags then
         begin
         // value  (variable or expression)
         bt:=StartResolved.BaseType;
         if bt=btSet then
-          InRange:=EvalTypeRange(StartResolved.TypeEl,[])
+          begin
+          if StartResolved.ExprEl<>nil then
+            InRange:=Eval(StartResolved.ExprEl,[refAutoConst])
+          else
+            InRange:=EvalTypeRange(StartResolved.TypeEl,[]);
+          end
         else if bt=btContext then
           begin
           TypeEl:=ResolveAliasType(StartResolved.TypeEl);
@@ -5360,15 +5380,25 @@ begin
               RaiseNotYetImplemented(20171109200954,Loop.StartExpr);
             end;
             if (VarRangeInt.RangeStart>InRangeInt.RangeStart) then
+              begin
+              {$IFDEF VerbosePasResolver}
+              writeln('TPasResolver.ResolveImplForLoop VarRange=',VarRangeInt.AsDebugString,' ',InRangeInt.AsDebugString);
+              {$ENDIF}
               fExprEvaluator.EmitRangeCheckConst(20171109201428,
                 InRangeInt.ElementAsString(InRangeInt.RangeStart),
                 VarRangeInt.ElementAsString(VarRangeInt.RangeStart),
                 VarRangeInt.ElementAsString(VarRangeInt.RangeEnd),Loop.VariableName,mtError);
+              end;
             if (VarRangeInt.RangeEnd<InRangeInt.RangeEnd) then
+              begin
+              {$IFDEF VerbosePasResolver}
+              writeln('TPasResolver.ResolveImplForLoop VarRange=',VarRangeInt.AsDebugString,' ',InRangeInt.AsDebugString);
+              {$ENDIF}
               fExprEvaluator.EmitRangeCheckConst(20171109201429,
                 InRangeInt.ElementAsString(InRangeInt.RangeEnd),
                 VarRangeInt.ElementAsString(VarRangeInt.RangeStart),
                 VarRangeInt.ElementAsString(VarRangeInt.RangeEnd),Loop.VariableName,mtError);
+              end;
             EnumeratorFound:=true;
             end;
           else

+ 7 - 0
packages/fcl-passrc/tests/tcresolver.pas

@@ -3357,6 +3357,8 @@ begin
   '  TEnumRg = green..blue;',
   '  TSetOfEnum = set of TEnum;',
   '  TSetOfEnumRg = set of TEnumRg;',
+  '  TArrOfEnum = array[TEnum] of byte;',
+  '  TArrOfEnumRg = array[TEnumRg] of byte;',
   'var',
   '  e: TEnum;',
   '  er: TEnumRg;',
@@ -3365,8 +3367,13 @@ begin
   '  for e in TEnumRg do;',
   '  for e in TSetOfEnum do;',
   '  for e in TSetOfEnumRg do;',
+  '  for e in [red..green] do;',
+  '  for e in TArrOfEnum do;',
+  '  for e in TArrOfEnumRg do;',
   '  for er in TEnumRg do;',
   '  for er in TSetOfEnumRg do;',
+  '  for er in [green..blue] do;',
+  '  for er in TArrOfEnumRg do;',
   '']);
   ParseProgram;
 end;