Ver Fonte

Partial merge of r28851 (aside the parts that requires the global assembler symbols)

Generate the import library for each used package.

pkgutil.pas:
  - remove function createimportlibfromexports
  + new function createimportlibfromexternals which uses the imported unit symbols of a unit to generate the correct import library for each used package used in a program or library
pmodules.pas, proc_program:
  * move the generation of the import library further down until all tables were generated of which entries might reside in a package
  * use createimportlibfromexternals to generate the import library for the program/library
-- Diese und die folgenden Zeilen werden ignoriert --

M    pmodules.pas
M    pkgutil.pas

git-svn-id: trunk@33493 -
svenbarth há 9 anos atrás
pai
commit
9d1938a713
2 ficheiros alterados com 121 adições e 13 exclusões
  1. 113 9
      compiler/pkgutil.pas
  2. 8 4
      compiler/pmodules.pas

+ 113 - 9
compiler/pkgutil.pas

@@ -27,9 +27,9 @@ unit pkgutil;
 interface
 
   uses
-    fmodule;
+    fmodule,fpkg;
 
-  procedure createimportlibfromexports;
+  procedure createimportlibfromexternals(pkg:tpackage);
   Function RewritePPU(const PPUFn,PPLFn:String):Boolean;
   procedure export_unit(u:tmodule);
   procedure load_packages;
@@ -42,7 +42,7 @@ implementation
     cutils,cclasses,
     globals,verbose,
     symtype,symconst,symsym,symdef,symbase,symtable,
-    ppu,entfile,fpcp,fpkg,
+    ppu,entfile,fpcp,
     export;
 
   procedure procexport(const s : string);
@@ -406,17 +406,121 @@ implementation
     end;
 
 
-  procedure createimportlibfromexports;
+  procedure createimportlibfromexternals(pkg:tpackage);
     var
-      hp : texported_item;
+      alreadyloaded : tfpobjectlist;
+
+
+    procedure import_proc_symbol(pd:tprocdef;pkg:tpackage);
+      var
+        item : TCmdStrListItem;
+      begin
+        item := TCmdStrListItem(pd.aliasnames.first);
+        while assigned(item) do
+          begin
+            current_module.addexternalimport(pkg.pplfilename,item.str,item.str,0,false,false);
+            item := TCmdStrListItem(item.next);
+          end;
+       end;
+
+
+    procedure processimportedsyms(syms:tfpobjectlist);
+      var
+        i,j,k,l : longint;
+        pkgentry : ppackageentry;
+        sym : TSymEntry;
+        srsymtable : tsymtable;
+        module : tmodule;
+        unitentry : pcontainedunit;
+        name : tsymstr;
+        pd : tprocdef;
+      begin
+        for i:=0 to syms.count-1 do
+          begin
+            sym:=tsymentry(syms[i]);
+            if not (sym.typ in [staticvarsym,procsym]) then
+              continue;
+            if alreadyloaded.indexof(sym)>=0 then
+              continue;
+            { determine the unit of the symbol }
+            srsymtable:=sym.owner;
+            while not (srsymtable.symtabletype in [staticsymtable,globalsymtable]) do
+              srsymtable:=srsymtable.defowner.owner;
+            module:=tmodule(loaded_units.first);
+            while assigned(module) do
+              begin
+                if (module.globalsymtable=srsymtable) or (module.localsymtable=srsymtable) then
+                  break;
+                module:=tmodule(module.next);
+              end;
+            if not assigned(module) then
+              internalerror(2014101001);
+            if (uf_in_library and module.flags)=0 then
+              { unit is not part of a package, so no need to handle it }
+              continue;
+            { loaded by a package? }
+            for j:=0 to packagelist.count-1 do
+              begin
+                pkgentry:=ppackageentry(packagelist[j]);
+                for k:=0 to pkgentry^.package.containedmodules.count-1 do
+                  begin
+                    unitentry:=pcontainedunit(pkgentry^.package.containedmodules[k]);
+                    if unitentry^.module=module then
+                      begin
+                        case sym.typ of
+                          staticvarsym:
+                            begin
+                              name:=tstaticvarsym(sym).mangledname;
+                              current_module.addexternalimport(pkgentry^.package.pplfilename,name,name+suffix_indirect,0,true,false);
+                            end;
+                          procsym:
+                            begin
+                              for l:=0 to tprocsym(sym).procdeflist.count-1 do
+                                begin
+                                  pd:=tprocdef(tprocsym(sym).procdeflist[l]);
+                                  import_proc_symbol(pd,pkgentry^.package);
+                                end;
+                            end;
+                          else
+                            internalerror(2014101001);
+                        end;
+                        alreadyloaded.add(sym);
+                      end;
+                  end;
+              end;
+          end;
+      end;
+
+
+    var
+      unitentry : pcontainedunit;
+      module : tmodule;
     begin
-      hp:=texported_item(current_module._exports.first);
-      while assigned(hp) do
+      { check each external asm symbol of each unit of the package whether it is
+        contained in the unit of a loaded package (and thus an import entry
+        is needed) }
+      if assigned(pkg) then
+        begin
+          { ToDo }
+        end
+      else
         begin
-          current_module.AddExternalImport(current_module.realmodulename^,hp.name^,hp.name^,hp.index,hp.is_var,false);
-          hp:=texported_item(hp.next);
+          alreadyloaded:=tfpobjectlist.create(false);
+          { we were called from a program/library }
+
+          module:=tmodule(loaded_units.first);
+          while assigned(module) do
+            begin
+              //if not assigned(module.package) then
+              if (uf_in_library and module.flags)=0 then
+                processimportedsyms(module.unitimportsyms);
+              module:=tmodule(module.next);
+            end;
+
+          alreadyloaded.free;
         end;
     end;
 
+
 end.
 

+ 8 - 4
compiler/pmodules.pas

@@ -2088,10 +2088,6 @@ type
          { if an Objective-C module, generate rtti and module info }
          MaybeGenerateObjectiveCImageInfo(nil,current_module.localsymtable);
 
-         { generate imports }
-         if current_module.ImportLibraryList.Count>0 then
-           importlib.generatelib;
-
          { generate debuginfo }
          if (cs_debuginfo in current_settings.moduleswitches) then
            current_debuginfo.inserttypeinfo;
@@ -2126,6 +2122,14 @@ type
          { create callframe info }
          create_dwarf_frame;
 
+         { create import library for all packages }
+         if packagelist.count>0 then
+           createimportlibfromexternals(nil);
+
+         { generate imports }
+         if current_module.ImportLibraryList.Count>0 then
+           importlib.generatelib;
+
          { insert own objectfile }
          insertobjectfile;