Adding dllimport, dllexport and external weak linkage types.
authorAnton Korobeynikov <asl@math.spbu.ru>
Thu, 14 Sep 2006 18:23:27 +0000 (18:23 +0000)
committerAnton Korobeynikov <asl@math.spbu.ru>
Thu, 14 Sep 2006 18:23:27 +0000 (18:23 +0000)
DLL* linkages got full (I hope) codegeneration support in C & both x86
assembler backends.
External weak linkage added for future use, we don't provide any
codegeneration, etc. support for it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30374 91177308-0d34-0410-b5e6-96231b3b80d8

30 files changed:
docs/BytecodeFormat.html
docs/LangRef.html
include/llvm/GlobalValue.h
lib/AsmParser/Lexer.l
lib/AsmParser/Lexer.l.cvs
lib/AsmParser/llvmAsmParser.y
lib/AsmParser/llvmAsmParser.y.cvs
lib/Bytecode/Reader/Reader.cpp
lib/Bytecode/Writer/Writer.cpp
lib/ExecutionEngine/ExecutionEngine.cpp
lib/ExecutionEngine/JIT/JITEmitter.cpp
lib/Linker/LinkArchives.cpp
lib/Linker/LinkModules.cpp
lib/Target/Alpha/AlphaAsmPrinter.cpp
lib/Target/CBackend/CBackend.cpp
lib/Target/CBackend/Writer.cpp
lib/Target/IA64/IA64AsmPrinter.cpp
lib/Target/Sparc/SparcAsmPrinter.cpp
lib/Target/X86/X86ATTAsmPrinter.cpp
lib/Target/X86/X86AsmPrinter.cpp
lib/Target/X86/X86AsmPrinter.h
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86IntelAsmPrinter.cpp
lib/Target/X86/X86Subtarget.h
lib/Transforms/IPO/GlobalOpt.cpp
lib/Transforms/IPO/SimplifyLibCalls.cpp
lib/VMCore/AsmWriter.cpp
lib/VMCore/Mangler.cpp
lib/VMCore/Verifier.cpp
tools/llvm2cpp/CppWriter.cpp

index 51177492a9ecd7885a565876c1f9edc00636d41a..2b856a71631134dce97a331b5f2011723c088d58 100644 (file)
@@ -1025,7 +1025,8 @@ follows. </td>
     <tr>
       <td><a href="#bit">bit(2-4)</a></td>
       <td class="td_left">Linkage type: 0=External, 1=Weak,
-2=Appending, 3=Internal, 4=LinkOnce</td>
+        2=Appending, 3=Internal, 4=LinkOnce, 5=DllImport, 
+        6=DllExport, 7=ExternWeak</td>
     </tr>
     <tr>
       <td><a href="#bit">bit(5-31)</a></td>
@@ -1136,13 +1137,16 @@ href="#uint32_vbr">uint32_vbr</a> that describes the function.</p>
       <td><a href="#bit">bit(4)</a></td>
       <td class="td_left">If this bit is set to 1, the indicated function is
       external, and there is no <a href="#functiondefs">Function Definiton
-      Block</a> in the bytecode file for the function.</td>
+      Block</a> in the bytecode file for the function. If the function is
+      external and has <tt>dllimport or extern_weak</tt> linkage additional
+      field in the extension word is used to indicate the actual linkage
+      type.</td>
     </tr>
     <tr>
       <td><a href="#bit">bit(5-30)</a></td>
       <td class="td_left">Type slot number of type for the function.</td>
     </tr>
-    <tr>
+                                      <tr>
       <td><a href="#bit">bit(31)</a></td>
       <td class="td_left">Indicates whether an extension word follows.</td>
     </tr>
@@ -1171,7 +1175,12 @@ follows with the following fields:</p>
       <td class="td_left">If this bit is set, a SectionID follows this vbr.</td>
     </tr>
     <tr>
-      <td><a href="#bit">bit(11-31)</a></td>
+      <td><a href="#bit">bit(11-12)</a></td>
+      <td class="td_left">Linkage type for external functions. 0 - External
+        linkage, 1 - DLLImport linkage, 2 - External weak linkage.</td>
+    </tr>
+    <tr>
+      <td><a href="#bit">bit(13-31)</a></td>
       <td class="td_left">Currently unassigned.</td>
     </tr>
   </tbody>
@@ -1410,8 +1419,8 @@ size<br>
     </tr>
     <tr>
       <td><a href="#uint32_vbr">uint32_vbr</a></td>
-      <td class="td_left">The linkage type of the function: 0=External,
-1=Weak, 2=Appending, 3=Internal, 4=LinkOnce<sup>1</sup></td>
+      <td class="td_left">The linkage type of the function: 0=External, 1=Weak,
+2=Appending, 3=Internal, 4=LinkOnce, 5=DllImport, 6=DllExport<sup>1</sup></td>
     </tr>
     <tr>
       <td><a href="#block">block</a></td>
index 232b4683323f6dc10f09a731200ea660d946bb17..5ae8472ffdda55b7ad5991b38ebc56bf9fd41491 100644 (file)
@@ -439,6 +439,35 @@ All Global Variables and Functions have one of the following types of linkage:
   visible, meaning that it participates in linkage and can be used to resolve
   external symbol references.
   </dd>
+
+  <dt><tt><b><a name="linkage_externweak">extern_weak</a></b></tt>: </dt>
+
+  <dd>"<tt>extern_weak</tt>" TBD
+  </dd>
+
+  <p>
+  The next two types of linkage are targeted for Microsoft Windows platform
+  only. They are designed to support importing (exporting) symbols from (to)
+  DLLs.
+  </p>
+
+  <dt><tt><b><a name="linkage_dllimport">dllimport</a></b></tt>: </dt>
+
+  <dd>"<tt>dllimport</tt>" linkage causes the compiler to reference a function
+    or variable via a global pointer to a pointer that is set up by the DLL
+    exporting the symbol. On Microsoft Windows targets, the pointer name is
+    formed by combining <code>_imp__</code> and the function or variable name.
+  </dd>
+
+  <dt><tt><b><a name="linkage_dllexport">dllexport</a></b></tt>: </dt>
+
+  <dd>"<tt>dllexport</tt>" linkage causes the compiler to provide a global
+    pointer to a pointer in a DLL, so that it can be referenced with the
+    <tt>dllimport</tt> attribute. On Microsoft Windows targets, the pointer
+    name is formed by combining <code>_imp__</code> and the function or variable
+    name.
+  </dd>
+
 </dl>
 
 <p><a name="linkage_external">For example, since the "<tt>.LC0</tt>"
index ca189b2cbe166d5a5d3f1bf497ee9d089fdc7a53..6aa830e62833a7b623fbd09f2df61811bb81d4d5 100644 (file)
@@ -28,12 +28,15 @@ class GlobalValue : public Constant {
   GlobalValue(const GlobalValue &);             // do not implement
 public:
   enum LinkageTypes {
-    ExternalLinkage,   /// Externally visible function
-    LinkOnceLinkage,   /// Keep one copy of named function when linking (inline)
-    WeakLinkage,       /// Keep one copy of named function when linking (weak)
-    AppendingLinkage,  /// Special purpose, only applies to global arrays
-    InternalLinkage,   /// Rename collisions when linking (static functions)
-    GhostLinkage       /// Stand-in functions for streaming fns from BC files
+    ExternalLinkage,     /// Externally visible function
+    LinkOnceLinkage,     /// Keep one copy of named function when linking (inline)
+    WeakLinkage,         /// Keep one copy of named function when linking (weak)
+    AppendingLinkage,    /// Special purpose, only applies to global arrays
+    InternalLinkage,     /// Rename collisions when linking (static functions)
+    DLLImportLinkage,    /// Function to be imported from DLL
+    DLLExportLinkage,    /// Function to be accessible from DLL
+    ExternalWeakLinkage, /// TBD: ExternalWeak linkage description
+    GhostLinkage         /// Stand-in functions for streaming fns from BC files    
   };
 protected:
   GlobalValue(const Type *Ty, ValueTy vty, Use *Ops, unsigned NumOps,
@@ -72,11 +75,14 @@ public:
     return reinterpret_cast<const PointerType*>(User::getType());
   }
 
-  bool hasExternalLinkage()  const { return Linkage == ExternalLinkage; }
-  bool hasLinkOnceLinkage()  const { return Linkage == LinkOnceLinkage; }
-  bool hasWeakLinkage()      const { return Linkage == WeakLinkage; }
-  bool hasAppendingLinkage() const { return Linkage == AppendingLinkage; }
-  bool hasInternalLinkage()  const { return Linkage == InternalLinkage; }
+  bool hasExternalLinkage()   const { return Linkage == ExternalLinkage; }
+  bool hasLinkOnceLinkage()   const { return Linkage == LinkOnceLinkage; }
+  bool hasWeakLinkage()       const { return Linkage == WeakLinkage; }
+  bool hasAppendingLinkage()  const { return Linkage == AppendingLinkage; }
+  bool hasInternalLinkage()   const { return Linkage == InternalLinkage; }
+  bool hasDLLImportLinkage()  const { return Linkage == DLLImportLinkage; }
+  bool hasDLLExportLinkage()  const { return Linkage == DLLExportLinkage; }
+  bool hasExternalWeakLinkage()  const { return Linkage == ExternalWeakLinkage; }
   void setLinkage(LinkageTypes LT) { Linkage = LT; }
   LinkageTypes getLinkage() const { return Linkage; }
 
index fd752459f0bba7dfd55b6b33390bc596c1b5b5f3..7c27f137bcb58b3aa34745db701bdcfe76bbdf89 100644 (file)
@@ -191,6 +191,9 @@ internal        { return INTERNAL; }
 linkonce        { return LINKONCE; }
 weak            { return WEAK; }
 appending       { return APPENDING; }
+dllimport       { return DLLIMPORT; }
+dllexport       { return DLLEXPORT; }
+extern_weak     { return EXTERN_WEAK; }
 uninitialized   { return EXTERNAL; }    /* Deprecated, turn into external */
 external        { return EXTERNAL; }
 implementation  { return IMPLEMENTATION; }
index fd752459f0bba7dfd55b6b33390bc596c1b5b5f3..7c27f137bcb58b3aa34745db701bdcfe76bbdf89 100644 (file)
@@ -191,6 +191,9 @@ internal        { return INTERNAL; }
 linkonce        { return LINKONCE; }
 weak            { return WEAK; }
 appending       { return APPENDING; }
+dllimport       { return DLLIMPORT; }
+dllexport       { return DLLEXPORT; }
+extern_weak     { return EXTERN_WEAK; }
 uninitialized   { return EXTERNAL; }    /* Deprecated, turn into external */
 external        { return EXTERNAL; }
 implementation  { return IMPLEMENTATION; }
index 7d6a9f7af36d55899eb721c5938d049787db52ef..af3a39d3d901f352894444644240f823a26d7846 100644 (file)
@@ -150,9 +150,10 @@ static struct PerModuleInfo {
 static struct PerFunctionInfo {
   Function *CurrentFunction;     // Pointer to current function being created
 
-  std::map<const Type*, ValueList> Values;   // Keep track of #'d definitions
+  std::map<const Type*, ValueList> Values; // Keep track of #'d definitions
   std::map<const Type*, ValueList> LateResolveValues;
-  bool isDeclare;                // Is this function a forward declararation?
+  bool isDeclare;                    // Is this function a forward declararation?
+  GlobalValue::LinkageTypes Linkage; // Linkage for forward declaration.
 
   /// BBForwardRefs - When we see forward references to basic blocks, keep
   /// track of them here.
@@ -163,6 +164,7 @@ static struct PerFunctionInfo {
   inline PerFunctionInfo() {
     CurrentFunction = 0;
     isDeclare = false;
+    Linkage = GlobalValue::ExternalLinkage;    
   }
 
   inline void FunctionStart(Function *M) {
@@ -184,6 +186,7 @@ static struct PerFunctionInfo {
     Values.clear();         // Clear out function local definitions
     CurrentFunction = 0;
     isDeclare = false;
+    Linkage = GlobalValue::ExternalLinkage;
   }
 } CurFun;  // Info for the current function...
 
@@ -998,7 +1001,8 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 
 %token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
 %token DECLARE GLOBAL CONSTANT SECTION VOLATILE
-%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK  APPENDING
+%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING
+%token DLLIMPORT DLLEXPORT EXTERN_WEAK
 %token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN
 %token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
 %token CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
@@ -1070,11 +1074,14 @@ OptAssign : Name '=' {
     CHECK_FOR_ERROR
   };
 
-OptLinkage : INTERNAL  { $$ = GlobalValue::InternalLinkage; } |
-             LINKONCE  { $$ = GlobalValue::LinkOnceLinkage; } |
-             WEAK      { $$ = GlobalValue::WeakLinkage; } |
-             APPENDING { $$ = GlobalValue::AppendingLinkage; } |
-             /*empty*/ { $$ = GlobalValue::ExternalLinkage; };
+OptLinkage : INTERNAL    { $$ = GlobalValue::InternalLinkage; } |
+             LINKONCE    { $$ = GlobalValue::LinkOnceLinkage; } |
+             WEAK        { $$ = GlobalValue::WeakLinkage; } |
+             APPENDING   { $$ = GlobalValue::AppendingLinkage; } |
+             DLLIMPORT   { $$ = GlobalValue::DLLImportLinkage; } |
+             DLLEXPORT   { $$ = GlobalValue::DLLExportLinkage; } |
+             EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } |
+             /*empty*/   { $$ = GlobalValue::ExternalLinkage; };
 
 OptCallingConv : /*empty*/      { $$ = CallingConv::C; } |
                  CCC_TOK        { $$ = CallingConv::C; } |
@@ -1728,8 +1735,24 @@ ConstPool : ConstPool OptAssign TYPE TypesV {
     CHECK_FOR_ERROR
   }
   | ConstPool OptAssign EXTERNAL GlobalType Types {
-    CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage,
-                                             $4, *$5, 0);
+    CurGV = ParseGlobalVariable($2,
+                                GlobalValue::ExternalLinkage, $4, *$5, 0);
+    delete $5;
+                                                   } GlobalVarAttributes {
+    CurGV = 0;
+    CHECK_FOR_ERROR
+  }
+  | ConstPool OptAssign DLLIMPORT GlobalType Types {
+    CurGV = ParseGlobalVariable($2,
+                                GlobalValue::DLLImportLinkage, $4, *$5, 0);
+    delete $5;
+                                                   } GlobalVarAttributes {
+    CurGV = 0;
+    CHECK_FOR_ERROR
+  }
+  | ConstPool OptAssign EXTERN_WEAK GlobalType Types {
+    CurGV = ParseGlobalVariable($2,
+                                GlobalValue::ExternalWeakLinkage, $4, *$5, 0);
     delete $5;
                                                    } GlobalVarAttributes {
     CurGV = 0;
@@ -1895,9 +1918,17 @@ FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
            AI != AE; ++AI)
         AI->setName("");
 
+    if (CurFun.isDeclare) {
+      Fn->setLinkage(CurFun.Linkage);      
+    }    
   } else  {  // Not already defined?
     Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName,
                       CurModule.CurrentModule);
+
+    if (CurFun.isDeclare) {
+      Fn->setLinkage(CurFun.Linkage);      
+    }    
+
     InsertValue(Fn, CurModule.Values);
   }
 
@@ -1948,11 +1979,15 @@ Function : BasicBlockList END {
   CHECK_FOR_ERROR
 };
 
-FunctionProto : DECLARE { CurFun.isDeclare = true; } FunctionHeaderH {
-  $$ = CurFun.CurrentFunction;
-  CurFun.FunctionDone();
-  CHECK_FOR_ERROR
-};
+FnDeclareLinkage: /*default*/ |
+                  DLLIMPORT   { CurFun.Linkage = GlobalValue::DLLImportLinkage } |
+                  EXTERN_WEAK { CurFun.Linkage = GlobalValue::DLLImportLinkage };
+  
+FunctionProto : DECLARE { CurFun.isDeclare = true; } FnDeclareLinkage FunctionHeaderH {
+    $$ = CurFun.CurrentFunction;
+    CurFun.FunctionDone();
+    CHECK_FOR_ERROR
+  };
 
 //===----------------------------------------------------------------------===//
 //                        Rules to match Basic Blocks
index 7d6a9f7af36d55899eb721c5938d049787db52ef..af3a39d3d901f352894444644240f823a26d7846 100644 (file)
@@ -150,9 +150,10 @@ static struct PerModuleInfo {
 static struct PerFunctionInfo {
   Function *CurrentFunction;     // Pointer to current function being created
 
-  std::map<const Type*, ValueList> Values;   // Keep track of #'d definitions
+  std::map<const Type*, ValueList> Values; // Keep track of #'d definitions
   std::map<const Type*, ValueList> LateResolveValues;
-  bool isDeclare;                // Is this function a forward declararation?
+  bool isDeclare;                    // Is this function a forward declararation?
+  GlobalValue::LinkageTypes Linkage; // Linkage for forward declaration.
 
   /// BBForwardRefs - When we see forward references to basic blocks, keep
   /// track of them here.
@@ -163,6 +164,7 @@ static struct PerFunctionInfo {
   inline PerFunctionInfo() {
     CurrentFunction = 0;
     isDeclare = false;
+    Linkage = GlobalValue::ExternalLinkage;    
   }
 
   inline void FunctionStart(Function *M) {
@@ -184,6 +186,7 @@ static struct PerFunctionInfo {
     Values.clear();         // Clear out function local definitions
     CurrentFunction = 0;
     isDeclare = false;
+    Linkage = GlobalValue::ExternalLinkage;
   }
 } CurFun;  // Info for the current function...
 
@@ -998,7 +1001,8 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 
 %token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
 %token DECLARE GLOBAL CONSTANT SECTION VOLATILE
-%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK  APPENDING
+%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING
+%token DLLIMPORT DLLEXPORT EXTERN_WEAK
 %token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN
 %token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
 %token CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
@@ -1070,11 +1074,14 @@ OptAssign : Name '=' {
     CHECK_FOR_ERROR
   };
 
-OptLinkage : INTERNAL  { $$ = GlobalValue::InternalLinkage; } |
-             LINKONCE  { $$ = GlobalValue::LinkOnceLinkage; } |
-             WEAK      { $$ = GlobalValue::WeakLinkage; } |
-             APPENDING { $$ = GlobalValue::AppendingLinkage; } |
-             /*empty*/ { $$ = GlobalValue::ExternalLinkage; };
+OptLinkage : INTERNAL    { $$ = GlobalValue::InternalLinkage; } |
+             LINKONCE    { $$ = GlobalValue::LinkOnceLinkage; } |
+             WEAK        { $$ = GlobalValue::WeakLinkage; } |
+             APPENDING   { $$ = GlobalValue::AppendingLinkage; } |
+             DLLIMPORT   { $$ = GlobalValue::DLLImportLinkage; } |
+             DLLEXPORT   { $$ = GlobalValue::DLLExportLinkage; } |
+             EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } |
+             /*empty*/   { $$ = GlobalValue::ExternalLinkage; };
 
 OptCallingConv : /*empty*/      { $$ = CallingConv::C; } |
                  CCC_TOK        { $$ = CallingConv::C; } |
@@ -1728,8 +1735,24 @@ ConstPool : ConstPool OptAssign TYPE TypesV {
     CHECK_FOR_ERROR
   }
   | ConstPool OptAssign EXTERNAL GlobalType Types {
-    CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage,
-                                             $4, *$5, 0);
+    CurGV = ParseGlobalVariable($2,
+                                GlobalValue::ExternalLinkage, $4, *$5, 0);
+    delete $5;
+                                                   } GlobalVarAttributes {
+    CurGV = 0;
+    CHECK_FOR_ERROR
+  }
+  | ConstPool OptAssign DLLIMPORT GlobalType Types {
+    CurGV = ParseGlobalVariable($2,
+                                GlobalValue::DLLImportLinkage, $4, *$5, 0);
+    delete $5;
+                                                   } GlobalVarAttributes {
+    CurGV = 0;
+    CHECK_FOR_ERROR
+  }
+  | ConstPool OptAssign EXTERN_WEAK GlobalType Types {
+    CurGV = ParseGlobalVariable($2,
+                                GlobalValue::ExternalWeakLinkage, $4, *$5, 0);
     delete $5;
                                                    } GlobalVarAttributes {
     CurGV = 0;
@@ -1895,9 +1918,17 @@ FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
            AI != AE; ++AI)
         AI->setName("");
 
+    if (CurFun.isDeclare) {
+      Fn->setLinkage(CurFun.Linkage);      
+    }    
   } else  {  // Not already defined?
     Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName,
                       CurModule.CurrentModule);
+
+    if (CurFun.isDeclare) {
+      Fn->setLinkage(CurFun.Linkage);      
+    }    
+
     InsertValue(Fn, CurModule.Values);
   }
 
@@ -1948,11 +1979,15 @@ Function : BasicBlockList END {
   CHECK_FOR_ERROR
 };
 
-FunctionProto : DECLARE { CurFun.isDeclare = true; } FunctionHeaderH {
-  $$ = CurFun.CurrentFunction;
-  CurFun.FunctionDone();
-  CHECK_FOR_ERROR
-};
+FnDeclareLinkage: /*default*/ |
+                  DLLIMPORT   { CurFun.Linkage = GlobalValue::DLLImportLinkage } |
+                  EXTERN_WEAK { CurFun.Linkage = GlobalValue::DLLImportLinkage };
+  
+FunctionProto : DECLARE { CurFun.isDeclare = true; } FnDeclareLinkage FunctionHeaderH {
+    $$ = CurFun.CurrentFunction;
+    CurFun.FunctionDone();
+    CHECK_FOR_ERROR
+  };
 
 //===----------------------------------------------------------------------===//
 //                        Rules to match Basic Blocks
index 60c8e4f9db8d8c58748f0444ec9c1ba56bb0b9dd..ac6418d7a7d0f7c391558b14945b79f92556404f 100644 (file)
@@ -1791,6 +1791,9 @@ void BytecodeReader::ParseFunctionBody(Function* F) {
   case 2: Linkage = GlobalValue::AppendingLinkage; break;
   case 3: Linkage = GlobalValue::InternalLinkage; break;
   case 4: Linkage = GlobalValue::LinkOnceLinkage; break;
+  case 5: Linkage = GlobalValue::DLLImportLinkage; break;
+  case 6: Linkage = GlobalValue::DLLExportLinkage; break;
+  case 7: Linkage = GlobalValue::ExternalWeakLinkage; break;
   default:
     error("Invalid linkage type for Function.");
     Linkage = GlobalValue::InternalLinkage;
@@ -2047,6 +2050,9 @@ void BytecodeReader::ParseModuleGlobalInfo() {
     case 2: Linkage = GlobalValue::AppendingLinkage; break;
     case 3: Linkage = GlobalValue::InternalLinkage;  break;
     case 4: Linkage = GlobalValue::LinkOnceLinkage;  break;
+    case 5: Linkage = GlobalValue::DLLImportLinkage;  break;
+    case 6: Linkage = GlobalValue::DLLExportLinkage;  break;
+    case 7: Linkage = GlobalValue::ExternalWeakLinkage;  break;
     default:
       error("Unknown linkage type: " + utostr(LinkageID));
       Linkage = GlobalValue::InternalLinkage;
@@ -2129,6 +2135,14 @@ void BytecodeReader::ParseModuleGlobalInfo() {
       
       if (ExtWord & (1 << 10))  // Has a section ID.
         SectionID[Func] = read_vbr_uint();
+
+      // Parse external declaration linkage
+      switch ((ExtWord >> 11) & 3) {
+       case 0: break;
+       case 1: Func->setLinkage(Function::DLLImportLinkage); break;
+       case 2: Func->setLinkage(Function::ExternalWeakLinkage); break;        
+       default: assert(0 && "Unsupported external linkage");        
+      }      
     }
     
     Func->setCallingConv(CC-1);
index 2fb05f147a6f7bad6282391f112dd993254f426d..48cccda8f40676d0aa97208a161a9d9123fc99d7 100644 (file)
@@ -938,11 +938,14 @@ void BytecodeWriter::outputConstants(bool isFunction) {
 static unsigned getEncodedLinkage(const GlobalValue *GV) {
   switch (GV->getLinkage()) {
   default: assert(0 && "Invalid linkage!");
-  case GlobalValue::ExternalLinkage:  return 0;
-  case GlobalValue::WeakLinkage:      return 1;
-  case GlobalValue::AppendingLinkage: return 2;
-  case GlobalValue::InternalLinkage:  return 3;
-  case GlobalValue::LinkOnceLinkage:  return 4;
+  case GlobalValue::ExternalLinkage:     return 0;
+  case GlobalValue::WeakLinkage:         return 1;
+  case GlobalValue::AppendingLinkage:    return 2;
+  case GlobalValue::InternalLinkage:     return 3;
+  case GlobalValue::LinkOnceLinkage:     return 4;
+  case GlobalValue::DLLImportLinkage:    return 5;
+  case GlobalValue::DLLExportLinkage:    return 6;
+  case GlobalValue::ExternalWeakLinkage: return 7;
   }
 }
 
@@ -973,7 +976,7 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
       unsigned oSlot = ((unsigned)Slot << 5) | (getEncodedLinkage(I) << 2) |
                         (I->hasInitializer() << 1) | (unsigned)I->isConstant();
       output_vbr(oSlot);
-    } else {
+    } else {  
       unsigned oSlot = ((unsigned)Slot << 5) | (3 << 2) |
                         (0 << 1) | (unsigned)I->isConstant();
       output_vbr(oSlot);
@@ -1018,16 +1021,30 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
     if (I->isExternal())   // If external, we don't have an FunctionInfo block.
       ID |= 1 << 4;
     
-    if (I->getAlignment() || I->hasSection() || (CC & ~15) != 0)
+    if (I->getAlignment() || I->hasSection() || (CC & ~15) != 0 ||
+        (I->isExternal() && I->hasDLLImportLinkage()) ||
+        (I->isExternal() && I->hasExternalWeakLinkage())
+       )
       ID |= 1 << 31;       // Do we need an extension word?
     
     output_vbr(ID);
     
     if (ID & (1 << 31)) {
       // Extension byte: bits 0-4 = alignment, bits 5-9 = top nibble of calling
-      // convention, bit 10 = hasSectionID.
+      // convention, bit 10 = hasSectionID., bits 11-12 = external linkage type
+      unsigned extLinkage = 0;
+
+      if (I->isExternal()) {
+        if (I->hasDLLImportLinkage()) {
+          extLinkage = 1;
+        } else if (I->hasExternalWeakLinkage()) {
+          extLinkage = 2;
+        }
+      }
+
       ID = (Log2_32(I->getAlignment())+1) | ((CC >> 4) << 5) | 
-           (I->hasSection() << 10);
+        (I->hasSection() << 10) |
+        ((extLinkage & 3) << 11);
       output_vbr(ID);
       
       // Give section names unique ID's.
index 9ad6b57ecd734f5151e9f0505d5d862c3a55f429..067f24de8b4ebc648c28a2a276840b2af6bb2a57 100644 (file)
@@ -657,7 +657,9 @@ void ExecutionEngine::emitGlobals() {
         }
         
         // If the existing global is strong, never replace it.
-        if (GVEntry->hasExternalLinkage())
+        if (GVEntry->hasExternalLinkage() ||
+            GVEntry->hasDLLImportLinkage() ||
+            GVEntry->hasDLLExportLinkage())
           continue;
         
         // Otherwise, we know it's linkonce/weak, replace it if this is a strong
index 6e60caf332e42e25c7c00125fcf0a6cec609bdc9..264caae2c9b394c3ca6fb6720f597c483ea06a19 100644 (file)
@@ -542,7 +542,7 @@ void *JITResolver::getFunctionStub(Function *F) {
   // Call the lazy resolver function unless we already KNOW it is an external
   // function, in which case we just skip the lazy resolution step.
   void *Actual = (void*)(intptr_t)LazyResolverFn;
-  if (F->isExternal() && F->hasExternalLinkage())
+  if (F->isExternal())
     Actual = TheJIT->getPointerToFunction(F);
 
   // Otherwise, codegen a new stub.  For now, the stub will call the lazy
@@ -738,7 +738,7 @@ void *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference,
   void *ResultPtr = TheJIT->getPointerToGlobalIfAvailable(F);
   if (ResultPtr) return ResultPtr;
 
-  if (F->hasExternalLinkage() && F->isExternal()) {
+  if (F->isExternal()) {
     // If this is an external function pointer, we can force the JIT to
     // 'compile' it, which really just adds it to the map.
     if (DoesntNeedStub)
index e115b93ad28b7f60d4ba69dc7b70369db62c6582..15d261e25bd8df77c9b138fcf10e229344a02bf6 100644 (file)
@@ -65,16 +65,22 @@ GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) {
     if (I->hasName()) {
       if (I->isExternal())
         UndefinedSymbols.insert(I->getName());
-      else if (!I->hasInternalLinkage())
+      else if (!I->hasInternalLinkage()) {
+        assert(!I->hasDLLImportLinkage()
+               && "Found dllimported non-external symbol!");
         DefinedSymbols.insert(I->getName());
+      }      
     }
   for (Module::global_iterator I = M->global_begin(), E = M->global_end();
        I != E; ++I)
     if (I->hasName()) {
       if (I->isExternal())
         UndefinedSymbols.insert(I->getName());
-      else if (!I->hasInternalLinkage())
+      else if (!I->hasInternalLinkage()) {
+        assert(!I->hasDLLImportLinkage()
+               && "Found dllimported non-external symbol!");
         DefinedSymbols.insert(I->getName());
+      }      
     }
 
   // Prune out any defined symbols from the undefined symbols set...
index 3c87177df3d64f55f5df3c681c9e407bcc0609d0..90b45028bc11e8b7f2eefdc3b95f9a843a4a357c 100644 (file)
@@ -359,9 +359,16 @@ static bool GetLinkageResult(GlobalValue *Dest, GlobalValue *Src,
   } else if (Src->isExternal()) {
     // If Src is external or if both Src & Drc are external..  Just link the
     // external globals, we aren't adding anything.
-    LinkFromSrc = false;
-    LT = Dest->getLinkage();
-  } else if (Dest->isExternal()) {
+    if (Src->hasDLLImportLinkage()) {
+      if (Dest->isExternal()) {
+        LinkFromSrc = true;
+        LT = Src->getLinkage();
+      }      
+    } else {
+      LinkFromSrc = false;
+      LT = Dest->getLinkage();
+    }
+  } else if (Dest->isExternal() && !Dest->hasDLLImportLinkage()) {
     // If Dest is external but Src is not:
     LinkFromSrc = true;
     LT = Src->getLinkage();
@@ -372,7 +379,7 @@ static bool GetLinkageResult(GlobalValue *Dest, GlobalValue *Src,
     LinkFromSrc = true; // Special cased.
     LT = Src->getLinkage();
   } else if (Src->hasWeakLinkage() || Src->hasLinkOnceLinkage()) {
-    // At this point we know that Dest has LinkOnce, External or Weak linkage.
+    // At this point we know that Dest has LinkOnce, External, Weak, DLL* linkage.
     if (Dest->hasLinkOnceLinkage() && Src->hasWeakLinkage()) {
       LinkFromSrc = true;
       LT = Src->getLinkage();
@@ -381,11 +388,16 @@ static bool GetLinkageResult(GlobalValue *Dest, GlobalValue *Src,
       LT = Dest->getLinkage();
     }
   } else if (Dest->hasWeakLinkage() || Dest->hasLinkOnceLinkage()) {
-    // At this point we know that Src has External linkage.
+    // At this point we know that Src has External or DLL* linkage.
     LinkFromSrc = true;
     LT = GlobalValue::ExternalLinkage;
   } else {
-    assert(Dest->hasExternalLinkage() && Src->hasExternalLinkage() &&
+    assert((Dest->hasExternalLinkage() ||
+            Dest->hasDLLImportLinkage() ||
+            Dest->hasDLLExportLinkage()) &&
+           (Src->hasExternalLinkage() ||
+            Src->hasDLLImportLinkage() ||
+            Src->hasDLLExportLinkage()) &&
            "Unexpected linkage type!");
     return Error(Err, "Linking globals named '" + Src->getName() +
                  "': symbol multiply defined!");
@@ -425,7 +437,8 @@ static bool LinkGlobals(Module *Dest, Module *Src,
     if (DGV && DGV->hasInternalLinkage())
       DGV = 0;
 
-    assert(SGV->hasInitializer() || SGV->hasExternalLinkage() &&
+    assert(SGV->hasInitializer() ||
+           SGV->hasExternalLinkage() || SGV->hasDLLImportLinkage() &&
            "Global must either be external or have an initializer!");
 
     GlobalValue::LinkageTypes NewLinkage;
@@ -565,7 +578,7 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
 //
 static bool LinkFunctionProtos(Module *Dest, const Module *Src,
                                std::map<const Value*, Value*> &ValueMap,
-                             std::map<std::string, GlobalValue*> &GlobalsByName,
+                               std::map<std::string, GlobalValue*> &GlobalsByName,
                                std::string *Err) {
   SymbolTable *ST = (SymbolTable*)&Dest->getSymbolTable();
 
@@ -604,12 +617,19 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src,
     } else if (SF->isExternal()) {
       // If SF is external or if both SF & DF are external..  Just link the
       // external functions, we aren't adding anything.
-      ValueMap.insert(std::make_pair(SF, DF));
-    } else if (DF->isExternal()) {   // If DF is external but SF is not...
+      if (SF->hasDLLImportLinkage()) {
+        if (DF->isExternal()) {
+          ValueMap.insert(std::make_pair(SF, DF));
+          DF->setLinkage(SF->getLinkage());          
+        }        
+      } else {
+        ValueMap.insert(std::make_pair(SF, DF));
+      }      
+    } else if (DF->isExternal() && !DF->hasDLLImportLinkage()) {
+      // If DF is external but SF is not...
       // Link the external functions, update linkage qualifiers
       ValueMap.insert(std::make_pair(SF, DF));
       DF->setLinkage(SF->getLinkage());
-
     } else if (SF->hasWeakLinkage() || SF->hasLinkOnceLinkage()) {
       // At this point we know that DF has LinkOnce, Weak, or External linkage.
       ValueMap.insert(std::make_pair(SF, DF));
index 2ce4865404bd00a15e3f811806077ec6f20b588b..52e2bb6d349aec28c669f631caf55063536cdcd5 100644 (file)
@@ -258,6 +258,14 @@ bool AlphaAsmPrinter::doFinalization(Module &M) {
         case GlobalValue::GhostLinkage:
           std::cerr << "GhostLinkage cannot appear in AlphaAsmPrinter!\n";
           abort();
+        case GlobalValue::DLLImportLinkage:
+          std::cerr << "DLLImport linkage is not supported by this target!\n";
+          abort();
+        case GlobalValue::DLLExportLinkage:
+          std::cerr << "DLLExport linkage is not supported by this target!\n";
+          abort();
+        default:
+          assert(0 && "Unknown linkage type!");
         }
 
         EmitAlignment(Align);
index 330a7bc53f8ae922ef4a2d19354959fe79127441..2aa36270bf2dc61329d91c0e56c5de73888f1c08 100644 (file)
@@ -1054,7 +1054,11 @@ bool CWriter::doInitialization(Module &M) {
         Out << "extern ";
         printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
         Out << ";\n";
-      }
+      } else if (I->hasDLLImportLinkage()) {
+        Out << "__declspec(dllimport) ";
+        printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
+        Out << ";\n";        
+      }      
     }
   }
 
@@ -1118,6 +1122,11 @@ bool CWriter::doInitialization(Module &M) {
         
         if (I->hasInternalLinkage())
           Out << "static ";
+        else if (I->hasDLLImportLinkage())
+          Out << "__declspec(dllimport) ";
+        else if (I->hasDLLExportLinkage())
+          Out << "__declspec(dllexport) ";
+            
         printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
         if (I->hasLinkOnceLinkage())
           Out << " __attribute__((common))";
@@ -1267,6 +1276,8 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
   bool isCStructReturn = F->getCallingConv() == CallingConv::CSRet;
   
   if (F->hasInternalLinkage()) Out << "static ";
+  if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) ";
+  if (F->hasDLLExportLinkage()) Out << "__declspec(dllexport) ";  
 
   // Loop over the arguments, printing them...
   const FunctionType *FT = cast<FunctionType>(F->getFunctionType());
index 330a7bc53f8ae922ef4a2d19354959fe79127441..2aa36270bf2dc61329d91c0e56c5de73888f1c08 100644 (file)
@@ -1054,7 +1054,11 @@ bool CWriter::doInitialization(Module &M) {
         Out << "extern ";
         printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
         Out << ";\n";
-      }
+      } else if (I->hasDLLImportLinkage()) {
+        Out << "__declspec(dllimport) ";
+        printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
+        Out << ";\n";        
+      }      
     }
   }
 
@@ -1118,6 +1122,11 @@ bool CWriter::doInitialization(Module &M) {
         
         if (I->hasInternalLinkage())
           Out << "static ";
+        else if (I->hasDLLImportLinkage())
+          Out << "__declspec(dllimport) ";
+        else if (I->hasDLLExportLinkage())
+          Out << "__declspec(dllexport) ";
+            
         printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
         if (I->hasLinkOnceLinkage())
           Out << " __attribute__((common))";
@@ -1267,6 +1276,8 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
   bool isCStructReturn = F->getCallingConv() == CallingConv::CSRet;
   
   if (F->hasInternalLinkage()) Out << "static ";
+  if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) ";
+  if (F->hasDLLExportLinkage()) Out << "__declspec(dllexport) ";  
 
   // Loop over the arguments, printing them...
   const FunctionType *FT = cast<FunctionType>(F->getFunctionType());
index 4a16777f9bbbd3c72f5032686e377652ee90aeaf..5fcc86f50e795e38c9dc89e259a4a348db2e02a0 100644 (file)
@@ -306,6 +306,14 @@ bool IA64AsmPrinter::doFinalization(Module &M) {
           case GlobalValue::GhostLinkage:
             std::cerr << "GhostLinkage cannot appear in IA64AsmPrinter!\n";
             abort();
+          case GlobalValue::DLLImportLinkage:
+            std::cerr << "DLLImport linkage is not supported by this target!\n";
+            abort();
+          case GlobalValue::DLLExportLinkage:
+            std::cerr << "DLLExport linkage is not supported by this target!\n";
+            abort();
+          default:
+            assert(0 && "Unknown linkage type!");            
         }
         
         EmitAlignment(Align);
index 1e6efcbeaf288de5cfd46417ea7c42a340fe212f..f8efc9ee545653acfd3d2e2d7d9d4f1c2b0bcf66 100644 (file)
@@ -271,6 +271,14 @@ bool SparcAsmPrinter::doFinalization(Module &M) {
         case GlobalValue::GhostLinkage:
           std::cerr << "Should not have any unmaterialized functions!\n";
           abort();
+        case GlobalValue::DLLImportLinkage:
+          std::cerr << "DLLImport linkage is not supported by this target!\n";
+          abort();
+        case GlobalValue::DLLExportLinkage:
+          std::cerr << "DLLExport linkage is not supported by this target!\n";
+          abort();
+        default:
+          assert(0 && "Unknown linkage type!");          
         }
 
         O << "\t.align " << Align << "\n";
index b17cde18de28a2a8e4ed58c66a6520274bcdab7f..1ce24fda0cffe35b9944d65e3ca43b55d409e742 100755 (executable)
@@ -48,10 +48,13 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
     SwitchToTextSection(TAI->getTextSection(), F);
     EmitAlignment(4, F);     // FIXME: This should be parameterized somewhere.
     break;
+  case Function::DLLExportLinkage:
+    DLLExportedFns.insert(Mang->makeNameProper(F->getName(), ""));
+    //FALLS THROUGH
   case Function::ExternalLinkage:
     SwitchToTextSection(TAI->getTextSection(), F);
     EmitAlignment(4, F);     // FIXME: This should be parameterized somewhere.
-    O << "\t.globl\t" << CurrentFnName << "\n";
+    O << "\t.globl\t" << CurrentFnName << "\n";    
     break;
   case Function::WeakLinkage:
   case Function::LinkOnceLinkage:
@@ -179,8 +182,9 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
     if (!isMemOp && !isCallOp) O << '$';
 
-    GlobalValue *GV = MO.getGlobal();
+    GlobalValue *GV = MO.getGlobal();    
     std::string Name = Mang->getValueName(GV);
+    
     bool isExt = (GV->isExternal() || GV->hasWeakLinkage() ||
                   GV->hasLinkOnceLinkage());
     if (X86PICStyle == PICStyle::Stub &&
@@ -196,13 +200,27 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
           GVStubs.insert(Name);
           O << "L" << Name << "$non_lazy_ptr";
         }
-      } else
+      } else {
+        if (GV->hasDLLImportLinkage()) {
+          // FIXME: This should be fixed with full support of stdcall & fastcall
+          // CC's
+          O << "__imp_";          
+        } 
         O << Name;
+      }
+      
       if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_)
         O << "-\"L" << getFunctionNumber() << "$pb\"";
-    } else
+    } else {
+      if (GV->hasDLLImportLinkage()) {
+        // FIXME: This should be fixed with full support of stdcall & fastcall
+        // CC's
+        O << "__imp_";          
+      }       
       O << Name;
-
+   
+    }
+    
     int Offset = MO.getOffset();
     if (Offset > 0)
       O << "+" << Offset;
index b634d13ea4a66ccc3a9f7d7110994c9c8b02914f..08dc7b26502765921ef477b38774063f1f373979 100644 (file)
@@ -112,6 +112,9 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
       case GlobalValue::AppendingLinkage:
         // FIXME: appending linkage variables should go into a section of
         // their name or something.  For now, just emit them as external.
+      case GlobalValue::DLLExportLinkage:
+        DLLExportedGVs.insert(Mang->makeNameProper(I->getName(),""));
+        // FALL THROUGH
       case GlobalValue::ExternalLinkage:
         // If external or appending, declare as a global symbol
         O << "\t.globl " << name << "\n";
@@ -134,6 +137,27 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
     }
   }
   
+  // Output linker support code for dllexported globals
+  if (DLLExportedGVs.begin() != DLLExportedGVs.end()) {
+    SwitchToDataSection(".section .drectve", 0);    
+  }
+
+  for (std::set<std::string>::iterator i = DLLExportedGVs.begin(),
+         e = DLLExportedGVs.end();
+         i != e; ++i) {
+    O << "\t.ascii \" -export:" << *i << ",data\"\n";
+  }    
+
+  if (DLLExportedFns.begin() != DLLExportedFns.end()) {
+    SwitchToDataSection(".section .drectve", 0);    
+  }
+
+  for (std::set<std::string>::iterator i = DLLExportedFns.begin(),
+         e = DLLExportedFns.end();
+         i != e; ++i) {
+    O << "\t.ascii \" -export:" << *i << "\"\n";
+  }    
   if (Subtarget->isTargetDarwin()) {
     SwitchToDataSection("", 0);
 
index 6db9e45dc3b2acca4b0959c229f5a657f279b278..ae03ca5382d4eea05bf8415501a9bddbaed524f6 100755 (executable)
@@ -63,6 +63,9 @@ struct VISIBILITY_HIDDEN X86SharedAsmPrinter : public AsmPrinter {
   // Necessary for Darwin to print out the apprioriate types of linker stubs
   std::set<std::string> FnStubs, GVStubs, LinkOnceStubs;
 
+  // Necessary for dllexport support
+  std::set<std::string> DLLExportedFns, DLLExportedGVs;
+  
   inline static bool isScale(const MachineOperand &MO) {
     return MO.isImmediate() &&
           (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 ||
index dfd7aa590445c02a8b98f713125309166c0fd12f..166345c2b210fcfea181df5385a108570f1c03cf 100644 (file)
@@ -1964,6 +1964,15 @@ static bool DarwinGVRequiresExtraLoad(GlobalValue *GV) {
           (GV->isExternal() && !GV->hasNotBeenReadFromBytecode()));
 }
 
+/// WinndowsGVRequiresExtraLoad - true if accessing the GV requires an extra
+/// load. For Windows, dllimported variables (not functions!) are indirect,
+/// loading the value at address GV rather then the value of GV itself. This
+/// means that the GlobalAddress must be in the base or index register of the
+/// address, not the GV offset field.
+static bool WindowsGVRequiresExtraLoad(GlobalValue *GV) {
+  return (isa<GlobalVariable>((Value*)GV) && GV->hasDLLImportLinkage());  
+}
+
 /// isUndefOrInRange - Op is either an undef node or a ConstantSDNode.  Return
 /// true if Op is undef or if its value falls within the specified range (L, H].
 static bool isUndefOrInRange(SDOperand Op, unsigned Low, unsigned Hi) {
@@ -3376,7 +3385,14 @@ X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
         DarwinGVRequiresExtraLoad(GV))
       Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(),
                            Result, DAG.getSrcValue(NULL));
+  } else if (Subtarget->isTargetCygwin() || Subtarget->isTargetWindows()) {
+    // FIXME: What's about PIC?
+    if (WindowsGVRequiresExtraLoad(GV)) {
+      Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(),
+                           Result, DAG.getSrcValue(NULL));      
+    }    
   }
+  
 
   return Result;
 }
index 24dbb15941db55990d63f020ec54289245464ab2..44a218ca1ebbb76fa36b0b2cbd60dead8005e057 100755 (executable)
@@ -35,10 +35,23 @@ bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   EmitConstantPool(MF.getConstantPool());
 
   // Print out labels for the function.
-  SwitchToTextSection("_text", MF.getFunction());
-  EmitAlignment(4);
-  if (MF.getFunction()->getLinkage() == GlobalValue::ExternalLinkage)
+  const Function* F = MF.getFunction();
+  switch (F->getLinkage()) {
+  default: assert(0 && "Unsupported linkage type!");
+  case Function::InternalLinkage:
+    SwitchToTextSection("_text", F);
+    EmitAlignment(4);
+    break;    
+  case Function::DLLExportLinkage:
+    DLLExportedFns.insert(CurrentFnName);
+    //FALLS THROUGH
+  case Function::ExternalLinkage:
     O << "\tpublic " << CurrentFnName << "\n";
+    SwitchToTextSection("_text", F);
+    EmitAlignment(4);
+    break;    
+  }
+  
   O << CurrentFnName << "\tproc near\n";
   
   // Print out code for the function.
@@ -118,8 +131,15 @@ void X86IntelAsmPrinter::printOp(const MachineOperand &MO,
   case MachineOperand::MO_GlobalAddress: {
     bool isCallOp = Modifier && !strcmp(Modifier, "call");
     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
+    GlobalValue *GV = MO.getGlobal();    
+
     if (!isMemOp && !isCallOp) O << "OFFSET ";
-    O << Mang->getValueName(MO.getGlobal());
+    if (GV->hasDLLImportLinkage()) {
+      // FIXME: This should be fixed with full support of stdcall & fastcall
+      // CC's
+      O << "__imp_";          
+    } 
+    O << Mang->getValueName(GV);
     int Offset = MO.getOffset();
     if (Offset > 0)
       O << " + " << Offset;
@@ -350,6 +370,9 @@ bool X86IntelAsmPrinter::doFinalization(Module &M) {
       // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
       // are also available.
       break;
+    case GlobalValue::DLLExportLinkage:
+      DLLExportedGVs.insert(name);
+      // FALL THROUGH
     case GlobalValue::ExternalLinkage:
       O << "\tpublic " << name << "\n";
       // FALL THROUGH
@@ -371,6 +394,34 @@ bool X86IntelAsmPrinter::doFinalization(Module &M) {
     if (bCustomSegment)
       O << name << "?\tends\n";
   }
+
+    // Output linker support code for dllexported globals
+  if ((DLLExportedGVs.begin() != DLLExportedGVs.end()) ||
+      (DLLExportedFns.begin() != DLLExportedFns.end())) {
+    SwitchToDataSection("", 0);
+    O << "; WARNING: The following code is valid only with MASM v8.x and (possible) higher\n"
+      << "; This version of MASM is usually shipped with Microsoft Visual Studio 2005\n"
+      << "; or (possible) further versions. Unfortunately, there is no way to support\n"
+      << "; dllexported symbols in the earlier versions of MASM in fully automatic way\n\n";
+    O << "_drectve\t segment info alias('.drectve')\n";
+  }
+
+  for (std::set<std::string>::iterator i = DLLExportedGVs.begin(),
+         e = DLLExportedGVs.end();
+         i != e; ++i) {
+    O << "\t db ' /EXPORT:" << *i << ",data'\n";
+  }    
+
+  for (std::set<std::string>::iterator i = DLLExportedFns.begin(),
+         e = DLLExportedFns.end();
+         i != e; ++i) {
+    O << "\t db ' /EXPORT:" << *i << "'\n";
+  }    
+
+  if ((DLLExportedGVs.begin() != DLLExportedGVs.end()) ||
+      (DLLExportedFns.begin() != DLLExportedFns.end())) {
+    O << "_drectve\t ends\n";    
+  }
   
   // Bypass X86SharedAsmPrinter::doFinalization().
   AsmPrinter::doFinalization(M);
index 224ebcd308138ac60ade516dcbe541e6685a3ea7..6e0d1dbae6e1df9ef7d05340026a316ee2f41e24 100644 (file)
@@ -99,6 +99,8 @@ public:
 
   bool isTargetDarwin() const { return TargetType == isDarwin; }
   bool isTargetELF() const { return TargetType == isELF; }
+  bool isTargetWindows() const { return TargetType == isWindows; }
+  bool isTargetCygwin() const { return TargetType == isCygwin; }  
 };
 } // End llvm namespace
 
index 8324b432e893b8e917fc7bd242f40635e2a08093..609bd94aa1a6969b211414afdbd1aa8032c7d117 100644 (file)
@@ -1245,7 +1245,7 @@ static Constant *getVal(std::map<Value*, Constant*> &ComputedValues,
 static bool isSimpleEnoughPointerToCommit(Constant *C) {
   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
     if (!GV->hasExternalLinkage() && !GV->hasInternalLinkage())
-      return false;  // do not allow weak/linkonce linkage.
+      return false;  // do not allow weak/linkonce/dllimport/dllexport linkage.
     return !GV->isExternal();  // reject external globals.
   }
   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
@@ -1254,7 +1254,7 @@ static bool isSimpleEnoughPointerToCommit(Constant *C) {
         isa<GlobalVariable>(CE->getOperand(0))) {
       GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0));
       if (!GV->hasExternalLinkage() && !GV->hasInternalLinkage())
-        return false;  // do not allow weak/linkonce linkage.
+        return false;  // do not allow weak/linkonce/dllimport/dllexport linkage.
       return GV->hasInitializer() &&
              ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE);
     }
index 79cdf28e0a4bfeeb02b241cade09828b81eb540c..9f9c52788bc5c4101fc7cab3d1330f322c4924de 100644 (file)
@@ -178,8 +178,10 @@ public:
         // All the "well-known" functions are external and have external linkage
         // because they live in a runtime library somewhere and were (probably)
         // not compiled by LLVM.  So, we only act on external functions that
-        // have external linkage and non-empty uses.
-        if (!FI->isExternal() || !FI->hasExternalLinkage() || FI->use_empty())
+        // have external or dllimport linkage and non-empty uses.
+        if (!FI->isExternal() ||
+            !(FI->hasExternalLinkage() || FI->hasDLLImportLinkage()) ||
+            FI->use_empty())
           continue;
 
         // Get the optimization class that pertains to this function
index f3bcfb53ba5cc6b9d56ecc20cc10d47aa1cfb229..b6f5fb37a3e6b480c1b54c8154a0e27e09625721 100644 (file)
@@ -845,14 +845,21 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
   if (GV->hasName()) Out << getLLVMName(GV->getName()) << " = ";
 
   if (!GV->hasInitializer())
-    Out << "external ";
+    switch (GV->getLinkage()) {
+     case GlobalValue::DLLImportLinkage:   Out << "dllimport "; break;
+     case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break;
+     default: Out << "external "; break;
+    }
   else
     switch (GV->getLinkage()) {
-    case GlobalValue::InternalLinkage:  Out << "internal "; break;
-    case GlobalValue::LinkOnceLinkage:  Out << "linkonce "; break;
-    case GlobalValue::WeakLinkage:      Out << "weak "; break;
-    case GlobalValue::AppendingLinkage: Out << "appending "; break;
-    case GlobalValue::ExternalLinkage: break;
+    case GlobalValue::InternalLinkage:     Out << "internal "; break;
+    case GlobalValue::LinkOnceLinkage:     Out << "linkonce "; break;
+    case GlobalValue::WeakLinkage:         Out << "weak "; break;
+    case GlobalValue::AppendingLinkage:    Out << "appending "; break;
+    case GlobalValue::DLLImportLinkage:    Out << "dllimport "; break;
+    case GlobalValue::DLLExportLinkage:    Out << "dllexport "; break;     
+    case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break;
+    case GlobalValue::ExternalLinkage:     break;
     case GlobalValue::GhostLinkage:
       std::cerr << "GhostLinkage not allowed in AsmWriter!\n";
       abort();
@@ -937,13 +944,20 @@ void AssemblyWriter::printFunction(const Function *F) {
   if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out);
 
   if (F->isExternal())
-    Out << "declare ";
+    switch (F->getLinkage()) {
+    case GlobalValue::DLLImportLinkage:    Out << "declare dllimport "; break;
+    case GlobalValue::ExternalWeakLinkage: Out << "declare extern_weak "; break;
+    default: Out << "declare ";
+    }
   else
     switch (F->getLinkage()) {
-    case GlobalValue::InternalLinkage:  Out << "internal "; break;
-    case GlobalValue::LinkOnceLinkage:  Out << "linkonce "; break;
-    case GlobalValue::WeakLinkage:      Out << "weak "; break;
-    case GlobalValue::AppendingLinkage: Out << "appending "; break;
+    case GlobalValue::InternalLinkage:     Out << "internal "; break;
+    case GlobalValue::LinkOnceLinkage:     Out << "linkonce "; break;
+    case GlobalValue::WeakLinkage:         Out << "weak "; break;
+    case GlobalValue::AppendingLinkage:    Out << "appending "; break;
+    case GlobalValue::DLLImportLinkage:    Out << "dllimport "; break;
+    case GlobalValue::DLLExportLinkage:    Out << "dllexport "; break;
+    case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break;      
     case GlobalValue::ExternalLinkage: break;
     case GlobalValue::GhostLinkage:
       std::cerr << "GhostLinkage not allowed in AsmWriter!\n";
index 8715498b9cd54acd87afd28b4bab947ce7e16665..b3211a315306034d7555f726fc47724e61cbdf5e 100644 (file)
@@ -162,11 +162,16 @@ void Mangler::InsertName(GlobalValue *GV,
     ExistingValue = GV;
   } else {
     // If GV is external but the existing one is static, mangle the existing one
-    if (GV->hasExternalLinkage() && !ExistingValue->hasExternalLinkage()) {
+    if ((GV->hasExternalLinkage() || GV->hasDLLImportLinkage()) &&
+        !(ExistingValue->hasExternalLinkage() || ExistingValue->hasDLLImportLinkage())) {
       MangledGlobals.insert(ExistingValue);
       ExistingValue = GV;
-    } else if (GV->hasExternalLinkage() && ExistingValue->hasExternalLinkage()&&
-               GV->isExternal() && ExistingValue->isExternal()) {
+    } else if ((GV->hasExternalLinkage() ||
+                GV->hasDLLImportLinkage()) &&
+               (ExistingValue->hasExternalLinkage() ||
+                ExistingValue->hasDLLImportLinkage()) &&
+               GV->isExternal() &&
+               ExistingValue->isExternal()) {
       // If the two globals both have external inkage, and are both external,
       // don't mangle either of them, we just have some silly type mismatch.
     } else {
index 606a43f075149f16ab79f0f0722806038cc2183c..cbef68b7dc35d951673edd40b66f1e18a1f59ed6 100644 (file)
@@ -257,8 +257,16 @@ namespace {  // Anonymous namespace for class
 
 
 void Verifier::visitGlobalValue(GlobalValue &GV) {
-  Assert1(!GV.isExternal() || GV.hasExternalLinkage(),
-          "Global is external, but doesn't have external linkage!", &GV);
+  Assert1(!GV.isExternal() ||
+          GV.hasExternalLinkage() ||
+          GV.hasDLLImportLinkage() ||
+          GV.hasExternalWeakLinkage(),
+  "Global is external, but doesn't have external or dllimport or weak linkage!",
+          &GV);
+
+  Assert1(!GV.hasDLLImportLinkage() || GV.isExternal(),
+          "Global is marked as dllimport, but not external", &GV);
+  
   Assert1(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV),
           "Only global variables can have appending linkage!", &GV);
 
index 0438a7e5d69df68f2ce2288de62ed5c9bb98a8df..66ed5b257c72e5bc98545169e78d25bce275d96b 100644 (file)
@@ -284,6 +284,12 @@ CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) {
       Out << "GlobalValue::AppendingLinkage"; break;
     case GlobalValue::ExternalLinkage: 
       Out << "GlobalValue::ExternalLinkage"; break;
+    case GlobalValue::DLLImportLinkage: 
+      Out << "GlobalValue::DllImportLinkage"; break;
+    case GlobalValue::DLLExportLinkage: 
+      Out << "GlobalValue::DllExportLinkage"; break;
+    case GlobalValue::ExternalWeakLinkage: 
+      Out << "GlobalValue::ExternalWeakLinkage"; break;
     case GlobalValue::GhostLinkage:
       Out << "GlobalValue::GhostLinkage"; break;
   }