소스 검색

pexpr.pas:
* extend factor() with the ability to deal with an already parsed "specialize"

git-svn-id: trunk@31768 -

svenbarth 10 년 전
부모
커밋
35d8a51730
4개의 변경된 파일23개의 추가작업 그리고 21개의 파일을 삭제
  1. 14 12
      compiler/pexpr.pas
  2. 2 2
      compiler/pgenutil.pas
  3. 6 6
      compiler/pinline.pas
  4. 1 1
      compiler/pstatmnt.pas

+ 14 - 12
compiler/pexpr.pas

@@ -38,7 +38,7 @@ interface
     function comp_expr(accept_equal,typeonly:boolean):tnode;
 
     { reads a single factor }
-    function factor(getaddr,typeonly:boolean) : tnode;
+    function factor(getaddr,typeonly,hadspecialize:boolean) : tnode;
 
     procedure string_dec(var def: tdef; allowtypedef: boolean);
 
@@ -750,7 +750,7 @@ implementation
                   consume(_LKLAMMER);
                   in_args:=true;
                   { don't turn procsyms into calls (getaddr = true) }
-                  p1:=factor(true,false);
+                  p1:=factor(true,false,false);
                   p2:=geninlinenode(l,false,p1);
                   consume(_RKLAMMER);
                   statement_syssym:=p2;
@@ -2567,7 +2567,7 @@ implementation
 
   {$maxfpuregisters 0}
 
-    function factor(getaddr,typeonly:boolean) : tnode;
+    function factor(getaddr,typeonly,hadspecialize:boolean) : tnode;
 
          {---------------------------------------------
                          Factor_read_id
@@ -2611,14 +2611,16 @@ implementation
            tokenpos:=current_filepos;
            p1:=nil;
 
-           allowspecialize:=not (m_delphi in current_settings.modeswitches) and (block_type in [bt_type,bt_var_type,bt_const_type]);
+           allowspecialize:=not (m_delphi in current_settings.modeswitches) and
+                            not hadspecialize and
+                            (block_type in [bt_type,bt_var_type,bt_const_type]);
            if allowspecialize and (token=_ID) and (idtoken=_SPECIALIZE) then
              begin
                consume(_ID);
                isspecialize:=true;
              end
            else
-             isspecialize:=false;
+             isspecialize:=hadspecialize;
 
            { first check for identifier }
            if token<>_ID then
@@ -3453,14 +3455,14 @@ implementation
                  { support both @<x> and @(<x>) }
                  if try_to_consume(_LKLAMMER) then
                   begin
-                    p1:=factor(true,false);
+                    p1:=factor(true,false,false);
                     { inside parentheses a full expression is allowed, see also tests\webtbs\tb27517.pp }
                     if token<>_RKLAMMER then
                       p1:=sub_expr(opcompare,true,false,p1);
                     consume(_RKLAMMER);
                   end
                  else
-                  p1:=factor(true,false);
+                  p1:=factor(true,false,false);
                  if token in postfixoperator_tokens then
                   begin
                     again:=true;
@@ -3503,7 +3505,7 @@ implementation
              _PLUS :
                begin
                  consume(_PLUS);
-                 p1:=factor(false,false);
+                 p1:=factor(false,false,false);
                  p1:=cunaryplusnode.create(p1);
                end;
 
@@ -3550,7 +3552,7 @@ implementation
              _OP_NOT :
                begin
                  consume(_OP_NOT);
-                 p1:=factor(false,false);
+                 p1:=factor(false,false,false);
                  p1:=cnotnode.create(p1);
                end;
 
@@ -3576,7 +3578,7 @@ implementation
                }
                consume(_OBJCPROTOCOL);
                consume(_LKLAMMER);
-               p1:=factor(false,false);
+               p1:=factor(false,false,false);
                consume(_RKLAMMER);
                p1:=cinlinenode.create(in_objc_protocol_x,false,p1);
              end;
@@ -3698,7 +3700,7 @@ implementation
         if pred_level=highest_precedence then
           begin
             if factornode=nil then
-              p1:=factor(false,typeonly)
+              p1:=factor(false,typeonly,false)
             else
               p1:=factornode;
           end
@@ -3713,7 +3715,7 @@ implementation
              filepos:=current_tokenpos;
              consume(token);
              if pred_level=highest_precedence then
-               p2:=factor(false,false)
+               p2:=factor(false,false,false)
              else
                p2:=sub_expr(succ(pred_level),true,typeonly,nil);
              case oldt of

+ 2 - 2
compiler/pgenutil.pas

@@ -327,7 +327,7 @@ uses
               consume(_COMMA);
             block_type:=bt_type;
             tmpparampos:=current_filepos;
-            typeparam:=factor(false,true);
+            typeparam:=factor(false,true,false);
             if typeparam.nodetype=typen then
               begin
                 if tstoreddef(typeparam.resultdef).is_generic and
@@ -453,7 +453,7 @@ uses
               repeat
                 if not first then
                   begin
-                    pt2:=factor(false,true);
+                    pt2:=factor(false,true,false);
                     pt2.free;
                   end;
                 first:=false;

+ 6 - 6
compiler/pinline.pas

@@ -167,7 +167,7 @@ implementation
             if is_typeparam(p.resultdef) then
               begin
                  p.free;
-                 p:=factor(false,false);
+                 p:=factor(false,false,false);
                  p.free;
                  consume(_RKLAMMER);
                  new_dispose_statement:=cnothingnode.create;
@@ -178,7 +178,7 @@ implementation
               begin
                  Message1(type_e_pointer_type_expected,p.resultdef.typename);
                  p.free;
-                 p:=factor(false,false);
+                 p:=factor(false,false,false);
                  p.free;
                  consume(_RKLAMMER);
                  new_dispose_statement:=cerrornode.create;
@@ -189,7 +189,7 @@ implementation
               begin
                  Message(parser_e_pointer_to_class_expected);
                  p.free;
-                 new_dispose_statement:=factor(false,false);
+                 new_dispose_statement:=factor(false,false,false);
                  consume_all_until(_RKLAMMER);
                  consume(_RKLAMMER);
                  exit;
@@ -199,7 +199,7 @@ implementation
             if is_class(classh) then
               begin
                  Message(parser_e_no_new_or_dispose_for_classes);
-                 new_dispose_statement:=factor(false,false);
+                 new_dispose_statement:=factor(false,false,false);
                  consume_all_until(_RKLAMMER);
                  consume(_RKLAMMER);
                  exit;
@@ -354,7 +354,7 @@ implementation
                          while (token=_COMMA) and assigned(variantdesc) do
                            begin
                              consume(_COMMA);
-                             p2:=factor(false,false);
+                             p2:=factor(false,false,false);
                              do_typecheckpass(p2);
                              if p2.nodetype=ordconstn then
                                begin
@@ -421,7 +421,7 @@ implementation
         if target_info.system in systems_managed_vm then
           message(parser_e_feature_unsupported_for_vm);
         consume(_LKLAMMER);
-        p1:=factor(false,false);
+        p1:=factor(false,false,false);
         if p1.nodetype<>typen then
          begin
            Message(type_e_type_id_expected);

+ 1 - 1
compiler/pstatmnt.pas

@@ -541,7 +541,7 @@ implementation
          { parse loop header }
          consume(_FOR);
 
-         hloopvar:=factor(false,false);
+         hloopvar:=factor(false,false,false);
          valid_for_loopvar(hloopvar,true);
 
          if try_to_consume(_ASSIGNMENT) then