Browse Source

pexpr.pas:
* extend handle_specialize_inline_specialization() with the ability to handle generic functions
* have handle_factor_typenode() and postfixoperators() make use of this extension

git-svn-id: trunk@31856 -

svenbarth 10 years ago
parent
commit
9dcfec8c63
1 changed files with 96 additions and 28 deletions
  1. 96 28
      compiler/pexpr.pas

+ 96 - 28
compiler/pexpr.pas

@@ -1377,27 +1377,64 @@ implementation
       end;
       end;
 
 
 
 
-    function handle_specialize_inline_specialization(var srsym:tsym;out srsymtable:tsymtable):boolean;
+    function handle_specialize_inline_specialization(var srsym:tsym;out srsymtable:tsymtable;out spezcontext:tspecializationcontext):boolean;
       var
       var
         spezdef : tdef;
         spezdef : tdef;
       begin
       begin
         result:=false;
         result:=false;
+        spezcontext:=nil;
+        srsymtable:=nil;
         if not assigned(srsym) then
         if not assigned(srsym) then
           message1(sym_e_id_no_member,orgpattern)
           message1(sym_e_id_no_member,orgpattern)
         else
         else
-          if srsym.typ<>typesym then
+          if not (srsym.typ in [typesym,procsym]) then
             message(type_e_type_id_expected)
             message(type_e_type_id_expected)
           else
           else
             begin
             begin
-              spezdef:=ttypesym(srsym).typedef;
-              generate_specialization(spezdef,false,'');
-              if spezdef<>generrordef then
-                begin
-                  srsym:=spezdef.typesym;
-                  srsymtable:=srsym.owner;
-                  check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
-                  result:=true;
-                end
+              if srsym.typ=typesym then
+                spezdef:=ttypesym(srsym).typedef
+              else
+                spezdef:=tdef(tprocsym(srsym).procdeflist[0]);
+              spezdef:=generate_specialization_phase1(spezcontext,spezdef);
+              case spezdef.typ of
+                errordef:
+                  begin
+                    spezcontext.free;
+                    spezcontext:=nil;
+                    srsym:=generrorsym;
+                  end;
+                procdef:
+                  begin
+                    if block_type<>bt_body then
+                      begin
+                        message(parser_e_illegal_expression);
+                        spezcontext.free;
+                        spezcontext:=nil;
+                        srsym:=generrorsym;
+                      end
+                    else
+                      begin
+                        srsym:=tprocdef(spezdef).procsym;
+                        srsymtable:=srsym.owner;
+                        result:=true;
+                      end;
+                  end;
+                objectdef,
+                recorddef,
+                arraydef,
+                procvardef:
+                  begin
+                    spezdef:=generate_specialization_phase2(spezcontext,tstoreddef(spezdef),false,'');
+                    spezcontext.free;
+                    spezcontext:=nil;
+                    srsym:=spezdef.typesym;
+                    srsymtable:=srsym.owner;
+                    check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
+                    result:=true;
+                  end;
+                else
+                  internalerror(2015070302);
+              end;
             end;
             end;
       end;
       end;
 
 
@@ -1407,7 +1444,9 @@ implementation
         srsym : tsym;
         srsym : tsym;
         srsymtable : tsymtable;
         srsymtable : tsymtable;
         isspecialize : boolean;
         isspecialize : boolean;
+        spezcontext : tspecializationcontext;
       begin
       begin
+         spezcontext:=nil;
          if sym=nil then
          if sym=nil then
            sym:=hdef.typesym;
            sym:=hdef.typesym;
          { allow Ordinal(Value) for type declarations since it
          { allow Ordinal(Value) for type declarations since it
@@ -1455,7 +1494,7 @@ implementation
                  if isspecialize then
                  if isspecialize then
                    begin
                    begin
                      consume(_ID);
                      consume(_ID);
-                     if not handle_specialize_inline_specialization(srsym,srsymtable) then
+                     if not handle_specialize_inline_specialization(srsym,srsymtable,spezcontext) then
                        begin
                        begin
                          result.free;
                          result.free;
                          result:=cerrornode.create;
                          result:=cerrornode.create;
@@ -1468,7 +1507,9 @@ implementation
                      consume(_ID);
                      consume(_ID);
                    end;
                    end;
                  if result.nodetype<>errorn then
                  if result.nodetype<>errorn then
-                   do_member_read(tabstractrecorddef(hdef),false,srsym,result,again,[],nil);
+                   do_member_read(tabstractrecorddef(hdef),false,srsym,result,again,[],spezcontext)
+                 else
+                   spezcontext.free;
                end
                end
              else
              else
               begin
               begin
@@ -1495,7 +1536,7 @@ implementation
                 if isspecialize then
                 if isspecialize then
                   begin
                   begin
                     consume(_ID);
                     consume(_ID);
-                    if not handle_specialize_inline_specialization(srsym,srsymtable) then
+                    if not handle_specialize_inline_specialization(srsym,srsymtable,spezcontext) then
                       begin
                       begin
                         result.free;
                         result.free;
                         result:=cerrornode.create;
                         result:=cerrornode.create;
@@ -1512,7 +1553,9 @@ implementation
                       Message1(sym_e_id_no_member,orgpattern);
                       Message1(sym_e_id_no_member,orgpattern);
                   end;
                   end;
                 if (result.nodetype<>errorn) and assigned(srsym) then
                 if (result.nodetype<>errorn) and assigned(srsym) then
-                  do_member_read(tabstractrecorddef(hdef),getaddr,srsym,result,again,[],nil);
+                  do_member_read(tabstractrecorddef(hdef),getaddr,srsym,result,again,[],spezcontext)
+                else
+                  spezcontext.free;
               end;
               end;
            end
            end
          else
          else
@@ -1860,6 +1903,8 @@ implementation
      intval : qword;
      intval : qword;
      code : integer;
      code : integer;
      strdef : tdef;
      strdef : tdef;
+     spezcontext : tspecializationcontext;
+     old_current_filepos : tfileposinfo;
     label
     label
      skipreckklammercheck,
      skipreckklammercheck,
      skippointdefcheck;
      skippointdefcheck;
@@ -1868,6 +1913,7 @@ implementation
      again:=true;
      again:=true;
      while again do
      while again do
       begin
       begin
+        spezcontext:=nil;
         { we need the resultdef }
         { we need the resultdef }
         do_typecheckpass_changed(p1,nodechanged);
         do_typecheckpass_changed(p1,nodechanged);
         result:=result or nodechanged;
         result:=result or nodechanged;
@@ -2222,7 +2268,7 @@ implementation
                                begin
                                begin
                                  searchsym_in_record(structh,pattern,srsym,srsymtable);
                                  searchsym_in_record(structh,pattern,srsym,srsymtable);
                                  consume(_ID);
                                  consume(_ID);
-                                 if handle_specialize_inline_specialization(srsym,srsymtable) then
+                                 if handle_specialize_inline_specialization(srsym,srsymtable,spezcontext) then
                                    erroroutp1:=false;
                                    erroroutp1:=false;
                                end;
                                end;
                            end
                            end
@@ -2248,7 +2294,7 @@ implementation
                              p1:=cerrornode.create;
                              p1:=cerrornode.create;
                            end
                            end
                          else
                          else
-                           do_member_read(structh,getaddr,srsym,p1,again,[],nil);
+                           do_member_read(structh,getaddr,srsym,p1,again,[],spezcontext);
                        end
                        end
                      else
                      else
                      consume(_ID);
                      consume(_ID);
@@ -2359,21 +2405,43 @@ implementation
                       if token=_ID then
                       if token=_ID then
                         begin
                         begin
                           structh:=tobjectdef(tclassrefdef(p1.resultdef).pointeddef);
                           structh:=tobjectdef(tclassrefdef(p1.resultdef).pointeddef);
-                          searchsym_in_class(tobjectdef(structh),tobjectdef(structh),pattern,srsym,srsymtable,[ssf_search_helper]);
-                          if assigned(srsym) then
+                          if isspecialize then
                             begin
                             begin
-                              check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
+                              { consume the specialize }
                               consume(_ID);
                               consume(_ID);
-                              do_member_read(structh,getaddr,srsym,p1,again,[],nil);
+                              if token<>_ID then
+                                consume(_ID)
+                              else
+                                begin
+                                  searchsym_in_class(tobjectdef(structh),tobjectdef(structh),pattern,srsym,srsymtable,[ssf_search_helper]);
+                                  consume(_ID);
+                                  if handle_specialize_inline_specialization(srsym,srsymtable,spezcontext) then
+                                    erroroutp1:=false;
+                                end;
                             end
                             end
                           else
                           else
                             begin
                             begin
-                              Message1(sym_e_id_no_member,orgpattern);
-                              p1.destroy;
-                              p1:=cerrornode.create;
-                              { try to clean up }
-                              consume(_ID);
+                              searchsym_in_class(tobjectdef(structh),tobjectdef(structh),pattern,srsym,srsymtable,[ssf_search_helper]);
+                              if assigned(srsym) then
+                                begin
+                                  check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
+                                  consume(_ID);
+                                  erroroutp1:=false;
+                                end
+                              else
+                                begin
+                                  Message1(sym_e_id_no_member,orgpattern);
+                                  { try to clean up }
+                                  consume(_ID);
+                                end;
                             end;
                             end;
+                          if erroroutp1 then
+                            begin
+                              p1.free;
+                              p1:=cerrornode.create;
+                            end
+                          else
+                            do_member_read(structh,getaddr,srsym,p1,again,[],spezcontext);
                         end
                         end
                       else { Error }
                       else { Error }
                         Consume(_ID);
                         Consume(_ID);
@@ -2395,7 +2463,7 @@ implementation
                                 begin
                                 begin
                                   searchsym_in_class(tobjectdef(structh),tobjectdef(structh),pattern,srsym,srsymtable,[ssf_search_helper]);
                                   searchsym_in_class(tobjectdef(structh),tobjectdef(structh),pattern,srsym,srsymtable,[ssf_search_helper]);
                                   consume(_ID);
                                   consume(_ID);
-                                  if handle_specialize_inline_specialization(srsym,srsymtable) then
+                                  if handle_specialize_inline_specialization(srsym,srsymtable,spezcontext) then
                                     erroroutp1:=false;
                                     erroroutp1:=false;
                                 end;
                                 end;
                             end
                             end
@@ -2421,7 +2489,7 @@ implementation
                               p1:=cerrornode.create;
                               p1:=cerrornode.create;
                             end
                             end
                           else
                           else
-                            do_member_read(structh,getaddr,srsym,p1,again,[],nil);
+                            do_member_read(structh,getaddr,srsym,p1,again,[],spezcontext);
                         end
                         end
                       else { Error }
                       else { Error }
                         Consume(_ID);
                         Consume(_ID);