Jelajahi Sumber

Merged revision(s) 32582-32583, 32635, 32637, 32639 from branches/svenbarth/packages:
pkgutil.pas, createimportlibfromexternals:
* findpackagewithsym: ignore other (weak) external symbols
........
pkgutil.pas, createimportlibfromexternals:
* import_proc_symbol: at least import the mangled name if there is no alias available
........
pkgutil.pas:
* exportabstractrecordsymproc & insert_export: don't try to export a typedef if it doesn't belong to the current symtable, happens for cross unit type aliases
........
psub.pas:
* read_proc: extract the code that creates an import library entry into its own function import_external_proc so that the same code can be used from other locations as well
........
Correctly handle external functions that are used from other units.

pkgutil.pas, createimportlibfromexternals:
* processasmsyms: also check the import name when checking for duplicates (just for safety, the cache check should have caught these already)
* processimportedsyms: if we have a routine imported from a library of whihc the symbol resides in a unit loaded from a package we need to import the routine ourselves instead of trying to import it from the package; also add an entry in the cache to speed up finding it again in processasmsyms()
........

git-svn-id: trunk@33519 -

svenbarth 9 tahun lalu
induk
melakukan
0a8d531b8d
2 mengubah file dengan 45 tambahan dan 23 penghapusan
  1. 17 5
      compiler/pkgutil.pas
  2. 28 18
      compiler/psub.pas

+ 17 - 5
compiler/pkgutil.pas

@@ -46,6 +46,7 @@ implementation
     cutils,
     globals,verbose,
     symtype,symconst,symsym,symdef,symbase,symtable,
+    psub,
     ppu,entfile,fpcp,
     export;
 
@@ -96,7 +97,7 @@ implementation
     end;
 
 
-  procedure exportabstractrecorddef(def:tabstractrecorddef); forward;
+  procedure exportabstractrecorddef(def:tabstractrecorddef;symtable:tsymtable); forward;
 
 
   procedure exportabstractrecordsymproc(sym:tobject;arg:pointer);
@@ -109,7 +110,7 @@ implementation
             case ttypesym(sym).typedef.typ of
               objectdef,
               recorddef:
-                exportabstractrecorddef(tabstractrecorddef(ttypesym(sym).typedef));
+                exportabstractrecorddef(tabstractrecorddef(ttypesym(sym).typedef),tsymtable(arg));
             end;
           end;
         procsym:
@@ -127,10 +128,13 @@ implementation
     end;
 
 
-  procedure exportabstractrecorddef(def:tabstractrecorddef);
+  procedure exportabstractrecorddef(def:tabstractrecorddef;symtable:tsymtable);
     var
       hp : texported_item;
     begin
+      { for cross unit type aliases this might happen }
+      if def.owner<>symtable then
+        exit;
       def.symtable.SymList.ForEachCall(@exportabstractrecordsymproc,def.symtable);
       { don't export generics or their nested types }
       if df_generic in def.defoptions then
@@ -166,7 +170,7 @@ implementation
             case ttypesym(sym).typedef.typ of
               recorddef,
               objectdef:
-                exportabstractrecorddef(tabstractrecorddef(ttypesym(sym).typedef));
+                exportabstractrecorddef(tabstractrecorddef(ttypesym(sym).typedef),tsymtable(arg));
             end;
           end;
         procsym:
@@ -538,6 +542,9 @@ implementation
         item : TCmdStrListItem;
       begin
         item := TCmdStrListItem(pd.aliasnames.first);
+        if not assigned(item) then
+          { at least import the mangled name }
+          current_module.addexternalimport(pkg.pplfilename,pd.mangledname,pd.mangledname,0,false,false);
         while assigned(item) do
           begin
             current_module.addexternalimport(pkg.pplfilename,item.str,item.str,0,false,false);
@@ -600,7 +607,12 @@ implementation
                               for l:=0 to tprocsym(sym).procdeflist.count-1 do
                                 begin
                                   pd:=tprocdef(tprocsym(sym).procdeflist[l]);
-                                  import_proc_symbol(pd,pkgentry^.package);
+                                  if [po_external,po_has_importdll]*pd.procoptions=[po_external,po_has_importdll] then
+                                    { if we use an external procedure of another unit we
+                                      need to import it ourselves from the correct library }
+                                    import_external_proc(pd)
+                                  else
+                                    import_proc_symbol(pd,pkgentry^.package);
                                 end;
                             end;
                           else

+ 28 - 18
compiler/psub.pas

@@ -85,6 +85,8 @@ interface
       true) }
     procedure read_proc(isclassmethod:boolean; usefwpd: tprocdef;isgeneric:boolean);
 
+    procedure import_external_proc(pd:tprocdef);
+
     procedure generate_specialization_procs;
 
 
@@ -2160,24 +2162,7 @@ implementation
              { Handle imports }
              if (po_external in pd.procoptions) then
                begin
-                 { Import DLL specified? }
-                 if assigned(pd.import_dll) then
-                   begin
-                     if assigned (pd.import_name) then
-                       current_module.AddExternalImport(pd.import_dll^,
-                         pd.import_name^,proc_get_importname(pd),
-                         pd.import_nr,false,false)
-                     else
-                       current_module.AddExternalImport(pd.import_dll^,
-                         proc_get_importname(pd),proc_get_importname(pd),
-                         pd.import_nr,false,true);
-                   end
-                 else
-                   begin
-                     { add import name to external list for DLL scanning }
-                     if tf_has_dllscanner in target_info.flags then
-                       current_module.dllscannerinputlist.Add(proc_get_importname(pd),pd);
-                   end;
+                 import_external_proc(pd);
 {$ifdef cpuhighleveltarget}
                  { it's hard to factor this out in a virtual method, because the
                    generic version (the one inside this ifdef) doesn't fit in
@@ -2223,6 +2208,31 @@ implementation
       end;
 
 
+    procedure import_external_proc(pd:tprocdef);
+      begin
+        if not (po_external in pd.procoptions) then
+          internalerror(2015121101);
+
+        { Import DLL specified? }
+        if assigned(pd.import_dll) then
+          begin
+            if assigned (pd.import_name) then
+              current_module.AddExternalImport(pd.import_dll^,
+                pd.import_name^,proc_get_importname(pd),
+                pd.import_nr,false,false)
+            else
+              current_module.AddExternalImport(pd.import_dll^,
+                proc_get_importname(pd),proc_get_importname(pd),
+                pd.import_nr,false,true);
+          end
+        else
+          begin
+            { add import name to external list for DLL scanning }
+            if tf_has_dllscanner in target_info.flags then
+              current_module.dllscannerinputlist.Add(proc_get_importname(pd),pd);
+          end;
+      end;
+
 {****************************************************************************
                              DECLARATION PARSING
 ****************************************************************************}