diff options
Diffstat (limited to 'lib')
26 files changed, 410 insertions, 86 deletions
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 (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)); diff --git a/lib/Target/Alpha/AlphaAsmPrinter.cpp b/lib/Target/Alpha/AlphaAsmPrinter.cpp index 2ce4865404..52e2bb6d34 100644 --- a/lib/Target/Alpha/AlphaAsmPrinter.cpp +++ b/lib/Target/Alpha/AlphaAsmPrinter.cpp @@ -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); diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 330a7bc53f..2aa36270bf 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -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()); diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index 330a7bc53f..2aa36270bf 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -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()); diff --git a/lib/Target/IA64/IA64AsmPrinter.cpp b/lib/Target/IA64/IA64AsmPrinter.cpp index 4a16777f9b..5fcc86f50e 100644 --- a/lib/Target/IA64/IA64AsmPrinter.cpp +++ b/lib/Target/IA64/IA64AsmPrinter.cpp @@ -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); |