diff options
30 files changed, 477 insertions, 103 deletions
diff --git a/docs/BytecodeFormat.html b/docs/BytecodeFormat.html index 51177492a9..2b856a7163 100644 --- a/docs/BytecodeFormat.html +++ b/docs/BytecodeFormat.html @@ -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> diff --git a/docs/LangRef.html b/docs/LangRef.html index 232b468332..5ae8472ffd 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -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>" diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index ca189b2cbe..6aa830e628 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -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; } diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l index fd752459f0..7c27f137bc 100644 --- a/lib/AsmParser/Lexer.l +++ b/lib/AsmParser/Lexer.l @@ -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; } diff --git a/lib/AsmParser/Lexer.l.cvs b/lib/AsmParser/Lexer.l.cvs index fd752459f0..7c27f137bc 100644 --- a/lib/AsmParser/Lexer.l.cvs +++ b/lib/AsmParser/Lexer.l.cvs @@ -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; } diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 7d6a9f7af3..af3a39d3d9 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -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 diff --git a/lib/AsmParser/llvmAsmParser.y.cvs b/lib/AsmParser/llvmAsmParser.y.cvs index 7d6a9f7af3..af3a39d3d9 100644 --- a/lib/AsmParser/llvmAsmParser.y.cvs +++ b/lib/AsmParser/llvmAsmParser.y.cvs @@ -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 diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 60c8e4f9db..ac6418d7a7 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -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); diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index 2fb05f147a..48cccda8f4 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -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. diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 9ad6b57ecd..067f24de8b 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -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 diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index 6e60caf332..264caae2c9 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -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) diff --git a/lib/Linker/LinkArchives.cpp b/lib/Linker/LinkArchives.cpp index e115b93ad2..15d261e25b 100644 --- a/lib/Linker/LinkArchives.cpp +++ b/lib/Linker/LinkArchives.cpp @@ -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... diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 3c87177df3..90b45028bc 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -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 (D |