Explorar el Código

Added a flag set to TSymtable that tells whether it contains a class helper symbol, which is currently only used for static- and globalsymtables.

symconst.pas: added new enum tsymtableoption with set tsymtableoptions; currently it contains only sto_has_classhelper, but refactoring tstoredsymtable.b_needs_init_final is on the todo list
ppu.pas: added a new entry type that will hold the symtable options (91)
symbase.pas: added a new field "tableoptions" to TSymtable which will hold the flags of the symtable (only saved by tstoredsymtable)
symdef.pas: when a tobjectdef is created as a odt_classhelper or odt_objccategory the flag sto_has_classhelper is added to its owning global- or staticsymtable
symtable.pas: 
* load and write the symtable's options as a small set to an entry before the definition entries
* tabstractlocalsymtable needed to annoy me by not calling "inherited writeppu" which does the same as tabstractsymtable did before
* search_last_objectpascal_classhelper: check whether the static- or globalsymtable contains a class helper at all; if not then just continue with the next
utils/ppudump.pas:
* added reading of symtableoptions entry (as readsymtableoptions) based on the reading of tsym options
* added the reading of symtableoptions before every read of the contents of a TSymtable (definitions, symbols)

git-svn-id: branches/svenbarth/classhelpers@16845 -
svenbarth hace 14 años
padre
commit
e19bcfae38
Se han modificado 6 ficheros con 95 adiciones y 5 borrados
  1. 1 0
      compiler/ppu.pas
  2. 1 0
      compiler/symbase.pas
  3. 6 0
      compiler/symconst.pas
  4. 13 0
      compiler/symdef.pas
  5. 13 5
      compiler/symtable.pas
  6. 61 0
      compiler/utils/ppudump.pp

+ 1 - 0
compiler/ppu.pas

@@ -131,6 +131,7 @@ const
   ibmoduleoptions   = 85;
 
   ibmainname       = 90;
+  ibsymtableoptions = 91;
   { target-specific things }
   iblinkotherframeworks = 100;
 

+ 1 - 0
compiler/symbase.pas

@@ -97,6 +97,7 @@ interface
           refcount  : smallint;
           currentvisibility : tvisibility;
           currentlyoptional : boolean;
+          tableoptions : tsymtableoptions;
           { level of symtable, used for nested procedures }
           symtablelevel : byte;
           symtabletype  : TSymtabletype;

+ 6 - 0
compiler/symconst.pas

@@ -455,6 +455,12 @@ type
                              in array                        }
   );
 
+  { options for symtables }
+  tsymtableoption = (
+    sto_has_classhelper    { contains at least one class
+                             helper symbol }
+  );
+  tsymtableoptions = set of tsymtableoption;
 
   { definition contains the informations about a type }
   tdeftyp = (abstractdef,

+ 13 - 0
compiler/symdef.pas

@@ -4148,11 +4148,24 @@ implementation
 ***************************************************************************}
 
    constructor tobjectdef.create(ot:tobjecttyp;const n:string;c:tobjectdef);
+
+       procedure update_unit_symtable_options;
+         var
+           st: tsymtable;
+         begin
+           st:=owner;
+           while not(st.symtabletype in [globalsymtable,staticsymtable]) do
+             st:=st.defowner.owner;
+           if objecttype in [odt_classhelper,odt_objccategory] then
+             include(st.tableoptions,sto_has_classhelper);
+         end;
+
      begin
         inherited create(n,objectdef);
         fcurrent_dispid:=0;
         objecttype:=ot;
         childof:=nil;
+        update_unit_symtable_options;
         symtable:=tObjectSymtable.create(self,n,current_settings.packrecords);
         { create space for vmt !! }
         vmtentries:=TFPList.Create;

+ 13 - 5
compiler/symtable.pas

@@ -350,6 +350,11 @@ implementation
 
     procedure tstoredsymtable.ppuload(ppufile:tcompilerppufile);
       begin
+        { load the table's flags }
+        if ppufile.readentry<>ibsymtableoptions then
+          Message(unit_f_ppu_read_error);
+        ppufile.getsmallset(tableoptions);
+
         { load definitions }
         loaddefs(ppufile);
 
@@ -360,6 +365,10 @@ implementation
 
     procedure tstoredsymtable.ppuwrite(ppufile:tcompilerppufile);
       begin
+         { write the table's flags }
+         ppufile.putsmallset(tableoptions);
+         ppufile.writeentry(ibsymtableoptions);
+
          { write definitions }
          writedefs(ppufile);
 
@@ -1270,10 +1279,7 @@ implementation
          oldtyp:=ppufile.entrytyp;
          ppufile.entrytyp:=subentryid;
 
-         { write definitions }
-         writedefs(ppufile);
-         { write symbols }
-         writesyms(ppufile);
+         inherited ppuwrite(ppufile);
 
          ppufile.entrytyp:=oldtyp;
       end;
@@ -2440,7 +2446,9 @@ implementation
         while assigned(stackitem) do
           begin
             srsymtable:=stackitem^.symtable;
-            if srsymtable.symtabletype in [staticsymtable,globalsymtable] then
+            { only check symtables that contain a class helper }
+            if (srsymtable.symtabletype in [staticsymtable,globalsymtable]) and
+                (sto_has_classhelper in srsymtable.tableoptions) then
               begin
                 { we need to search from last to first }
                 for i:=srsymtable.symlist.count-1 downto 0 do

+ 61 - 0
compiler/utils/ppudump.pp

@@ -426,6 +426,51 @@ end;
                              Read Routines
 ****************************************************************************}
 
+procedure readsymtableoptions(const s: string);
+type
+  tsymtableoption = (
+    sto_has_classhelper    { contains at least one class
+                             helper symbol }
+  );
+  tsymtableoptions = set of tsymtableoption;
+  tsymtblopt=record
+    mask : tsymtableoption;
+    str  : string[30];
+  end;
+const
+  symtblopts=1;
+  symtblopt : array[1..symtblopts] of tsymtblopt=(
+     (mask:sto_has_classhelper;   str:'Has class helper')
+  );
+var
+  options : tsymtableoptions;
+  first : boolean;
+  i : integer;
+begin
+  if ppufile.readentry<>ibsymtableoptions then
+    exit;
+  ppufile.getsmallset(options);
+  if space<>'' then
+   writeln(space,'------ ',s,' ------');
+  write(space,'Symtable options: ');
+  if options<>[] then
+   begin
+     first:=true;
+     for i:=1 to symtblopts do
+      if (symtblopt[i].mask in options) then
+       begin
+         if first then
+           first:=false
+         else
+           write(', ');
+         write(symtblopt[i].str);
+       end;
+   end
+  else
+   write('none');
+  writeln;
+end;
+
 Procedure ReadLinkContainer(const prefix:string);
 {
   Read a serie of strings and write to the screen starting every line
@@ -1977,6 +2022,7 @@ begin
              writeln(space,'            Range : ',getaint,' to ',getaint);
              write  (space,'          Options : ');
              readarraydefoptions;
+             readsymtableoptions('symbols');
              readdefinitions('symbols');
              readsymbols('symbols');
            end;
@@ -2038,11 +2084,13 @@ begin
               Writeln('!! Entry has more information stored');
              space:='    '+space;
              { parast }
+             readsymtableoptions('parast');
              readdefinitions('parast');
              readsymbols('parast');
              { localst }
              if (po_has_inlininginfo in procoptions) then
               begin
+                readsymtableoptions('localst');
                 readdefinitions('localst');
                 readsymbols('localst');
               end;
@@ -2060,6 +2108,7 @@ begin
               Writeln('!! Entry has more information stored');
              space:='    '+space;
              { parast }
+             readsymtableoptions('parast');
              readdefinitions('parast');
              readsymbols('parast');
              delete(space,1,4);
@@ -2110,6 +2159,7 @@ begin
               Writeln('!! Entry has more information stored');
              {read the record definitions and symbols}
              space:='    '+space;
+             readsymtableoptions('fields');
              readdefinitions('fields');
              readsymbols('fields');
              Delete(space,1,4);
@@ -2192,6 +2242,7 @@ begin
                begin
                  {read the record definitions and symbols}
                  space:='    '+space;
+                 readsymtableoptions('fields');
                  readdefinitions('fields');
                  readsymbols('fields');
                  Delete(space,1,4);
@@ -2236,6 +2287,7 @@ begin
              else
                begin
                  space:='    '+space;
+                 readsymtableoptions('elements');
                  readdefinitions('elements');
                  readsymbols('elements');
                  delete(space,1,4);
@@ -2543,6 +2595,10 @@ begin
    end
   else
    ppufile.skipuntilentry(ibendinterface);
+  Writeln;
+  Writeln('Interface symtable');
+  Writeln('----------------------');
+  readsymtableoptions('interface');
 {read the definitions}
   if (verbose and v_defs)<>0 then
    begin
@@ -2578,6 +2634,7 @@ begin
     end;
   if boolean(ppufile.getbyte) then
     begin
+      readsymtableoptions('interface macro');
       {skip the definition section for macros (since they are never used) }
       ppufile.skipuntilentry(ibenddefs);
       {read the macro symbols}
@@ -2600,6 +2657,10 @@ begin
   else
    ppufile.skipuntilentry(ibendimplementation);
   {read the static symtable}
+  Writeln;
+  Writeln('Implementation symtable');
+  Writeln('----------------------');
+  readsymtableoptions('implementation');
   if (ppufile.header.flags and uf_local_symtable)<>0 then
    begin
      if (verbose and v_defs)<>0 then