Browse Source

* support DefaultHandler and anonymous inheritance fixed
for message methods

peter 22 years ago
parent
commit
830ea4e876
5 changed files with 185 additions and 20 deletions
  1. 6 2
      compiler/ncal.pas
  2. 6 2
      compiler/node.pas
  3. 32 14
      compiler/pexpr.pas
  4. 36 1
      compiler/symdef.pas
  5. 105 1
      compiler/symtable.pas

+ 6 - 2
compiler/ncal.pas

@@ -1742,7 +1742,7 @@ type
                         do this ugly hack in Delphi mode as it looks more
                         do this ugly hack in Delphi mode as it looks more
                         like a bug. It's also not documented }
                         like a bug. It's also not documented }
                       if (m_delphi in aktmodeswitches) and
                       if (m_delphi in aktmodeswitches) and
-                         (nf_auto_inherited in flags) and
+                         (nf_anon_inherited in flags) and
                          (symtableprocentry.owner.symtabletype=objectsymtable) and
                          (symtableprocentry.owner.symtabletype=objectsymtable) and
                          (po_overload in symtableprocentry.first_procdef.procoptions) and
                          (po_overload in symtableprocentry.first_procdef.procoptions) and
                          (symtableprocentry.procdef_count>=2) then
                          (symtableprocentry.procdef_count>=2) then
@@ -2395,7 +2395,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.129  2003-03-17 15:54:22  peter
+  Revision 1.130  2003-03-17 16:54:41  peter
+    * support DefaultHandler and anonymous inheritance fixed
+      for message methods
+
+  Revision 1.129  2003/03/17 15:54:22  peter
     * store symoptions also for procdef
     * store symoptions also for procdef
     * check symoptions (private,public) when calculating possible
     * check symoptions (private,public) when calculating possible
       overload candidates
       overload candidates

+ 6 - 2
compiler/node.pas

@@ -222,7 +222,7 @@ interface
          { flags used by tcallnode }
          { flags used by tcallnode }
          nf_return_value_used,
          nf_return_value_used,
          nf_static_call,
          nf_static_call,
-         nf_auto_inherited,
+         nf_anon_inherited,
 
 
          { flags used by tcallparanode }
          { flags used by tcallparanode }
          nf_varargs_para,  { belongs this para to varargs }
          nf_varargs_para,  { belongs this para to varargs }
@@ -976,7 +976,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.49  2003-01-04 15:54:03  daniel
+  Revision 1.50  2003-03-17 16:54:41  peter
+    * support DefaultHandler and anonymous inheritance fixed
+      for message methods
+
+  Revision 1.49  2003/01/04 15:54:03  daniel
     * Fixed mark_write for @ operator
     * Fixed mark_write for @ operator
       (can happen when compiling @procvar:=nil (Delphi mode construction))
       (can happen when compiling @procvar:=nil (Delphi mode construction))
 
 

+ 32 - 14
compiler/pexpr.pas

@@ -91,7 +91,7 @@ implementation
 
 
     const
     const
       got_addrn  : boolean = false;
       got_addrn  : boolean = false;
-      auto_inherited : boolean = false;
+      anon_inherited : boolean = false;
 
 
 
 
 
 
@@ -671,7 +671,7 @@ implementation
          if not(getaddr) then
          if not(getaddr) then
            begin
            begin
              para:=nil;
              para:=nil;
-             if auto_inherited then
+             if anon_inherited then
               begin
               begin
                 hst:=symtablestack;
                 hst:=symtablestack;
                 while assigned(hst) and (hst.symtabletype<>parasymtable) do
                 while assigned(hst) and (hst.symtabletype<>parasymtable) do
@@ -1780,24 +1780,33 @@ implementation
                consume(_INHERITED);
                consume(_INHERITED);
                if assigned(procinfo._class) then
                if assigned(procinfo._class) then
                 begin
                 begin
+                  classh:=procinfo._class.childof;
                   { if inherited; only then we need the method with
                   { if inherited; only then we need the method with
                     the same name }
                     the same name }
                   if token=_SEMICOLON then
                   if token=_SEMICOLON then
                    begin
                    begin
                      hs:=aktprocsym.name;
                      hs:=aktprocsym.name;
-                     auto_inherited:=true
+                     anon_inherited:=true;
+                     { For message methods we need to search using the message
+                       number or string }
+                     if (po_msgint in aktprocsym.first_procdef.procoptions) then
+                      sym:=searchsym_in_class_by_msgint(classh,aktprocsym.first_procdef.messageinf.i)
+                     else
+                      if (po_msgstr in aktprocsym.first_procdef.procoptions) then
+                       sym:=searchsym_in_class_by_msgstr(classh,aktprocsym.first_procdef.messageinf.str)
+                     else
+                      sym:=searchsym_in_class(classh,hs);
                    end
                    end
                   else
                   else
                    begin
                    begin
                      hs:=pattern;
                      hs:=pattern;
                      consume(_ID);
                      consume(_ID);
-                     auto_inherited:=false;
+                     anon_inherited:=false;
+                     sym:=searchsym_in_class(classh,hs);
                    end;
                    end;
-                  classh:=procinfo._class.childof;
-                  sym:=searchsym_in_class(classh,hs);
-                  check_hints(sym);
                   if assigned(sym) then
                   if assigned(sym) then
                    begin
                    begin
+                     check_hints(sym);
                      if sym.typ=procsym then
                      if sym.typ=procsym then
                       begin
                       begin
                         htype.setdef(classh);
                         htype.setdef(classh);
@@ -1806,15 +1815,20 @@ implementation
                      do_member_read(false,sym,p1,again);
                      do_member_read(false,sym,p1,again);
                      { Add flag to indicate that inherited is used }
                      { Add flag to indicate that inherited is used }
                      if p1.nodetype=calln then
                      if p1.nodetype=calln then
-                       include(p1.flags,nf_auto_inherited);
+                       include(p1.flags,nf_anon_inherited);
                    end
                    end
                   else
                   else
                    begin
                    begin
-                     if auto_inherited then
+                     if anon_inherited then
                       begin
                       begin
-                        { we didn't find a member in the parents so
-                          we do nothing. This is compatible with delphi (PFV) }
-                        p1:=cnothingnode.create;
+                        { we didn't find a member in the parents call the
+                          DefaultHandler }
+                        sym:=searchsym_in_class(classh,'DEFAULTHANDLER');
+                        if not assigned(sym) or
+                           (sym.typ<>procsym) then
+                          internalerror(200303171);
+                        p1:=nil;
+                        do_proc_call(sym,sym.owner,false,again,p1);
                       end
                       end
                      else
                      else
                       begin
                       begin
@@ -1824,7 +1838,7 @@ implementation
                      again:=false;
                      again:=false;
                    end;
                    end;
                   { turn auto inheriting off }
                   { turn auto inheriting off }
-                  auto_inherited:=false;
+                  anon_inherited:=false;
                 end
                 end
                else
                else
                  begin
                  begin
@@ -2326,7 +2340,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.102  2003-01-30 21:46:57  peter
+  Revision 1.103  2003-03-17 16:54:41  peter
+    * support DefaultHandler and anonymous inheritance fixed
+      for message methods
+
+  Revision 1.102  2003/01/30 21:46:57  peter
     * self fixes for static methods (merged)
     * self fixes for static methods (merged)
 
 
   Revision 1.101  2003/01/16 22:12:22  peter
   Revision 1.101  2003/01/16 22:12:22  peter

+ 36 - 1
compiler/symdef.pas

@@ -546,6 +546,7 @@ interface
           function  is_methodpointer:boolean;override;
           function  is_methodpointer:boolean;override;
           function  is_addressonly:boolean;override;
           function  is_addressonly:boolean;override;
           function  is_visible_for_proc(currprocdef:tprocdef):boolean;
           function  is_visible_for_proc(currprocdef:tprocdef):boolean;
+          function  is_visible_for_object(currobjdef:tobjectdef):boolean;
           { debug }
           { debug }
 {$ifdef GDB}
 {$ifdef GDB}
           function  stabstring : pchar;override;
           function  stabstring : pchar;override;
@@ -3672,6 +3673,36 @@ implementation
       end;
       end;
 
 
 
 
+    function tprocdef.is_visible_for_object(currobjdef:tobjectdef):boolean;
+      begin
+        is_visible_for_object:=false;
+
+        { private symbols are allowed when we are in the same
+          module as they are defined }
+        if (sp_private in symoptions) and
+           (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
+           (owner.defowner.owner.unitid<>0) then
+          exit;
+
+        { protected symbols are vissible in the module that defines them and
+          also visible to related objects }
+        if (sp_protected in symoptions) and
+           (
+            (
+             (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
+             (owner.defowner.owner.unitid<>0)
+            ) and
+            not(
+                assigned(currobjdef) and
+                currobjdef.is_related(tobjectdef(owner.defowner))
+               )
+           ) then
+          exit;
+
+        is_visible_for_object:=true;
+      end;
+
+
     function tprocdef.getsymtable(t:tgetsymtable):tsymtable;
     function tprocdef.getsymtable(t:tgetsymtable):tsymtable;
       begin
       begin
         case t of
         case t of
@@ -5693,7 +5724,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.130  2003-03-17 15:54:22  peter
+  Revision 1.131  2003-03-17 16:54:41  peter
+    * support DefaultHandler and anonymous inheritance fixed
+      for message methods
+
+  Revision 1.130  2003/03/17 15:54:22  peter
     * store symoptions also for procdef
     * store symoptions also for procdef
     * check symoptions (private,public) when calculating possible
     * check symoptions (private,public) when calculating possible
       overload candidates
       overload candidates

+ 105 - 1
compiler/symtable.pas

@@ -221,6 +221,8 @@ interface
     function  searchsym(const s : stringid;var srsym:tsym;var srsymtable:tsymtable):boolean;
     function  searchsym(const s : stringid;var srsym:tsym;var srsymtable:tsymtable):boolean;
     function  searchsymonlyin(p : tsymtable;const s : stringid):tsym;
     function  searchsymonlyin(p : tsymtable;const s : stringid):tsym;
     function  searchsym_in_class(classh:tobjectdef;const s : stringid):tsym;
     function  searchsym_in_class(classh:tobjectdef;const s : stringid):tsym;
+    function  searchsym_in_class_by_msgint(classh:tobjectdef;i:longint):tsym;
+    function  searchsym_in_class_by_msgstr(classh:tobjectdef;const s:string):tsym;
     function  searchsystype(const s: stringid; var srsym: ttypesym): boolean;
     function  searchsystype(const s: stringid; var srsym: ttypesym): boolean;
     function  searchsysvar(const s: stringid; var srsym: tvarsym; var symowner: tsymtable): boolean;
     function  searchsysvar(const s: stringid; var srsym: tvarsym; var symowner: tsymtable): boolean;
     function  search_class_member(pd : tobjectdef;const s : string):tsym;
     function  search_class_member(pd : tobjectdef;const s : string):tsym;
@@ -2076,6 +2078,104 @@ implementation
       end;
       end;
 
 
 
 
+    function  searchsym_in_class_by_msgint(classh:tobjectdef;i:longint):tsym;
+      var
+        topclassh  : tobjectdef;
+        def        : tdef;
+        sym        : tsym;
+      begin
+         { when the class passed is defined in this unit we
+           need to use the scope of that class. This is a trick
+           that can be used to access protected members in other
+           units. At least kylix supports it this way (PFV) }
+         if assigned(classh) and
+            (classh.owner.symtabletype in [globalsymtable,staticsymtable]) and
+            (classh.owner.unitid=0) then
+           topclassh:=classh
+         else
+           topclassh:=nil;
+         sym:=nil;
+         def:=nil;
+         while assigned(classh) do
+          begin
+            def:=tdef(classh.symtable.defindex.first);
+            while assigned(def) do
+             begin
+               if (def.deftype=procdef) and
+                  (po_msgint in tprocdef(def).procoptions) and
+                  (tprocdef(def).messageinf.i=i) then
+                begin
+                  sym:=tprocdef(def).procsym;
+                  if assigned(topclassh) then
+                   begin
+                     if tprocdef(def).is_visible_for_object(topclassh) then
+                      break;
+                   end
+                  else
+                   begin
+                     if tprocdef(def).is_visible_for_proc(aktprocdef) then
+                      break;
+                   end;
+                end;
+               def:=tdef(def.indexnext);
+             end;
+            if assigned(sym) then
+             break;
+            classh:=classh.childof;
+          end;
+         searchsym_in_class_by_msgint:=sym;
+      end;
+
+
+    function  searchsym_in_class_by_msgstr(classh:tobjectdef;const s:string):tsym;
+      var
+        topclassh  : tobjectdef;
+        def        : tdef;
+        sym        : tsym;
+      begin
+         { when the class passed is defined in this unit we
+           need to use the scope of that class. This is a trick
+           that can be used to access protected members in other
+           units. At least kylix supports it this way (PFV) }
+         if assigned(classh) and
+            (classh.owner.symtabletype in [globalsymtable,staticsymtable]) and
+            (classh.owner.unitid=0) then
+           topclassh:=classh
+         else
+           topclassh:=nil;
+         sym:=nil;
+         def:=nil;
+         while assigned(classh) do
+          begin
+            def:=tdef(classh.symtable.defindex.first);
+            while assigned(def) do
+             begin
+               if (def.deftype=procdef) and
+                  (po_msgstr in tprocdef(def).procoptions) and
+                  (tprocdef(def).messageinf.str=s) then
+                begin
+                  sym:=tprocdef(def).procsym;
+                  if assigned(topclassh) then
+                   begin
+                     if tprocdef(def).is_visible_for_object(topclassh) then
+                      break;
+                   end
+                  else
+                   begin
+                     if tprocdef(def).is_visible_for_proc(aktprocdef) then
+                      break;
+                   end;
+                end;
+               def:=tdef(def.indexnext);
+             end;
+            if assigned(sym) then
+             break;
+            classh:=classh.childof;
+          end;
+         searchsym_in_class_by_msgstr:=sym;
+      end;
+
+
     function searchsystype(const s: stringid; var srsym: ttypesym): boolean;
     function searchsystype(const s: stringid; var srsym: ttypesym): boolean;
       var
       var
         symowner: tsymtable;
         symowner: tsymtable;
@@ -2350,7 +2450,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.89  2002-12-29 14:57:50  peter
+  Revision 1.90  2003-03-17 16:54:41  peter
+    * support DefaultHandler and anonymous inheritance fixed
+      for message methods
+
+  Revision 1.89  2002/12/29 14:57:50  peter
     * unit loading changed to first register units and load them
     * unit loading changed to first register units and load them
       afterwards. This is needed to support uses xxx in yyy correctly
       afterwards. This is needed to support uses xxx in yyy correctly
     * unit dependency check fixed
     * unit dependency check fixed