From 4ad02e726d9b634372b037d4b352d8b63bb9e849 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 16 Apr 2003 20:28:45 +0000 Subject: [PATCH] Add new linkage types to support a real frontend git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5786 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Function.h | 4 +- include/llvm/GlobalValue.h | 23 +++- include/llvm/GlobalVariable.h | 2 +- lib/Analysis/DataStructure/Parallelize.cpp | 3 +- lib/AsmParser/Lexer.l | 2 + lib/AsmParser/ParserInternals.h | 2 +- lib/AsmParser/llvmAsmParser.y | 33 +++-- lib/Bytecode/Reader/ConstantReader.cpp | 3 +- lib/Bytecode/Reader/Reader.cpp | 13 +- lib/Linker/LinkModules.cpp | 125 ++++++++++-------- lib/Target/SparcV9/SparcV9PreSelection.cpp | 3 +- lib/Transforms/IPO/ExtractFunction.cpp | 8 +- lib/Transforms/IPO/Internalize.cpp | 4 +- lib/Transforms/IPO/MutateStructTypes.cpp | 3 +- lib/Transforms/IPO/Parallelize.cpp | 3 +- lib/Transforms/IPO/PoolAllocate.cpp | 3 +- .../Instrumentation/EmitFunctions.cpp | 3 +- .../ProfilePaths/ProfilePaths.cpp | 13 +- .../Instrumentation/TraceValues.cpp | 3 +- lib/Transforms/Utils/CloneFunction.cpp | 2 +- lib/Transforms/Utils/CloneModule.cpp | 13 +- lib/Transforms/Utils/Linker.cpp | 125 ++++++++++-------- lib/VMCore/AsmWriter.cpp | 25 +++- lib/VMCore/Function.cpp | 8 +- lib/VMCore/Linker.cpp | 125 ++++++++++-------- lib/VMCore/Module.cpp | 7 +- 26 files changed, 334 insertions(+), 224 deletions(-) diff --git a/include/llvm/Function.h b/include/llvm/Function.h index 885824d4f7e..fe8216210d0 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -71,8 +71,8 @@ public: /// function is automatically inserted into the end of the function list for /// the module. /// - Function(const FunctionType *Ty, bool isInternal, const std::string &N = "", - Module *M = 0); + Function(const FunctionType *Ty, LinkageTypes Linkage, + const std::string &N = "", Module *M = 0); ~Function(); // Specialize setName to handle symbol table majik... diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index af2ff23c82e..13ad9237182 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -16,12 +16,19 @@ class Module; class GlobalValue : public User { GlobalValue(const GlobalValue &); // do not implement +public: + enum LinkageTypes { + ExternalLinkage, // Externally visible function + LinkOnceLinkage, // Keep one copy of named function when linking (inline) + AppendingLinkage, // Special purpose, only applies to global arrays + InternalLinkage // Rename collisions when linking (static functions) + }; protected: - GlobalValue(const Type *Ty, ValueTy vty, bool hasInternalLinkage, + GlobalValue(const Type *Ty, ValueTy vty, LinkageTypes linkage, const std::string &name = "") - : User(Ty, vty, name), HasInternalLinkage(hasInternalLinkage), Parent(0) {} + : User(Ty, vty, name), Linkage(linkage), Parent(0) {} - bool HasInternalLinkage; // Is this value accessable externally? + LinkageTypes Linkage; // The linkage of this global Module *Parent; public: ~GlobalValue() {} @@ -31,10 +38,12 @@ public: return (const PointerType*)User::getType(); } - /// Internal Linkage - True if the global value is inaccessible to - bool hasInternalLinkage() const { return HasInternalLinkage; } - bool hasExternalLinkage() const { return !HasInternalLinkage; } - void setInternalLinkage(bool HIL) { HasInternalLinkage = HIL; } + bool hasExternalLinkage() const { return Linkage == ExternalLinkage; } + bool hasLinkOnceLinkage() const { return Linkage == LinkOnceLinkage; } + bool hasAppendingLinkage() const { return Linkage == AppendingLinkage; } + bool hasInternalLinkage() const { return Linkage == InternalLinkage; } + void setLinkage(LinkageTypes LT) { Linkage = LT; } + LinkageTypes getLinkage() const { return Linkage; } /// isExternal - Return true if the primary definition of this global value is /// outside of the current translation unit... diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h index a534d19008b..6fb74a3dbef 100644 --- a/include/llvm/GlobalVariable.h +++ b/include/llvm/GlobalVariable.h @@ -35,7 +35,7 @@ public: /// GlobalVariable ctor - If a parent module is specified, the global is /// automatically inserted into the end of the specified modules global list. /// - GlobalVariable(const Type *Ty, bool isConstant, bool isInternal, + GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage, Constant *Initializer = 0, const std::string &Name = "", Module *Parent = 0); diff --git a/lib/Analysis/DataStructure/Parallelize.cpp b/lib/Analysis/DataStructure/Parallelize.cpp index 08c800eb1c7..46fbcc7d855 100644 --- a/lib/Analysis/DataStructure/Parallelize.cpp +++ b/lib/Analysis/DataStructure/Parallelize.cpp @@ -137,7 +137,8 @@ Cilkifier::Cilkifier(Module& M) DummySyncFunc = new Function(FunctionType::get( Type::VoidTy, std::vector(), /*isVararg*/ false), - /*isInternal*/ false, DummySyncFuncName, &M); + GlobalValue::ExternalLinkage, DummySyncFuncName, + &M); } void Cilkifier::TransformFunc(Function* F, diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l index 7776c90a90a..f342d2fe342 100644 --- a/lib/AsmParser/Lexer.l +++ b/lib/AsmParser/Lexer.l @@ -155,6 +155,8 @@ global { return GLOBAL; } constant { return CONSTANT; } const { return CONST; } internal { return INTERNAL; } +linkonce { return LINKONCE; } +appending { return APPENDING; } uninitialized { return EXTERNAL; } /* Deprecated, turn into external */ external { return EXTERNAL; } implementation { return IMPLEMENTATION; } diff --git a/lib/AsmParser/ParserInternals.h b/lib/AsmParser/ParserInternals.h index 496e37a5db4..667c08b2420 100644 --- a/lib/AsmParser/ParserInternals.h +++ b/lib/AsmParser/ParserInternals.h @@ -177,7 +177,7 @@ struct BBPlaceHolderHelper : public BasicBlock { struct MethPlaceHolderHelper : public Function { MethPlaceHolderHelper(const Type *Ty) - : Function(cast(Ty), true) {} + : Function(cast(Ty), InternalLinkage) {} }; typedef PlaceholderValue ValuePlaceHolder; diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index a25aaf805de..b26565180bb 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -522,8 +522,7 @@ static bool setValueName(Value *V, char *NameStr) { EGV->setInitializer(GV->getInitializer()); if (GV->isConstant()) EGV->setConstant(true); - if (GV->hasInternalLinkage()) - EGV->setInternalLinkage(true); + EGV->setLinkage(GV->getLinkage()); delete GV; // Destroy the duplicate! return true; // They are equivalent! @@ -624,6 +623,7 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) { std::vector > *JumpTable; std::vector *ConstVector; + GlobalValue::LinkageTypes Linkage; int64_t SInt64Val; uint64_t UInt64Val; int SIntVal; @@ -654,7 +654,8 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) { %type IndexList // For GEP derived indices %type TypeListI ArgTypeListI %type JumpTable -%type GlobalType OptInternal // GLOBAL or CONSTANT? Intern? +%type GlobalType // GLOBAL or CONSTANT? +%type OptLinkage // ValueRef - Unresolved reference to a definition or BB %type ValueRef ConstValueRef SymbolicValueRef @@ -684,7 +685,8 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) { %token IMPLEMENTATION TRUE FALSE BEGINTOK ENDTOK DECLARE GLOBAL CONSTANT -%token TO EXCEPT DOTDOTDOT NULL_TOK CONST INTERNAL OPAQUE NOT EXTERNAL +%token TO EXCEPT DOTDOTDOT NULL_TOK CONST INTERNAL LINKONCE APPENDING +%token OPAQUE NOT EXTERNAL // Basic Block Terminating Operators %token RET BR SWITCH @@ -748,7 +750,10 @@ OptAssign : VAR_ID '=' { $$ = 0; }; -OptInternal : INTERNAL { $$ = true; } | /*empty*/ { $$ = false; }; +OptLinkage : INTERNAL { $$ = GlobalValue::InternalLinkage; } | + LINKONCE { $$ = GlobalValue::LinkOnceLinkage; } | + APPENDING { $$ = GlobalValue::AppendingLinkage; } | + /*empty*/ { $$ = GlobalValue::ExternalLinkage; }; //===----------------------------------------------------------------------===// // Types includes all predefined types... except void, because it can only be @@ -982,7 +987,8 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr // Create a placeholder for the global variable reference... GlobalVariable *GV = new GlobalVariable(PT->getElementType(), - false, true); + false, + GlobalValue::ExternalLinkage); // Keep track of the fact that we have a forward ref to recycle it CurModule.GlobalRefs.insert(make_pair(make_pair(PT, $2), GV)); @@ -1136,7 +1142,7 @@ ConstPool : ConstPool OptAssign CONST ConstVal { } | ConstPool FunctionProto { // Function prototypes can be in const pool } - | ConstPool OptAssign OptInternal GlobalType ConstVal { + | ConstPool OptAssign OptLinkage GlobalType ConstVal { const Type *Ty = $5->getType(); // Global declarations appear in Constant Pool Constant *Initializer = $5; @@ -1159,7 +1165,7 @@ ConstPool : ConstPool OptAssign CONST ConstVal { | ConstPool OptAssign EXTERNAL GlobalType Types { const Type *Ty = *$5; // Global declarations appear in Constant Pool - GlobalVariable *GV = new GlobalVariable(Ty, $4, false); + GlobalVariable *GV = new GlobalVariable(Ty,$4,GlobalValue::ExternalLinkage); if (!setValueName(GV, $2)) { // If not redefining... CurModule.CurrentModule->getGlobalList().push_back(GV); int Slot = InsertValue(GV, CurModule.Values); @@ -1255,7 +1261,7 @@ FunctionHeaderH : TypesV FuncName '(' ArgList ')' { AI->setName(""); } else { // Not already defined? - Fn = new Function(FT, false, FunctionName); + Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName); InsertValue(Fn, CurModule.Values); CurModule.DeclareNewGlobalValue(Fn, ValID::create($2)); } @@ -1288,13 +1294,12 @@ FunctionHeaderH : TypesV FuncName '(' ArgList ')' { BEGIN : BEGINTOK | '{'; // Allow BEGIN or '{' to start a function -FunctionHeader : OptInternal FunctionHeaderH BEGIN { +FunctionHeader : OptLinkage FunctionHeaderH BEGIN { $$ = CurMeth.CurrentFunction; - // Make sure that we keep track of the internal marker, even if there was - // a previous "declare". - if ($1) - $$->setInternalLinkage(true); + // Make sure that we keep track of the linkage type even if there was a + // previous "declare". + $$->setLinkage($1); // Resolve circular types before we parse the body of the function. ResolveTypes(CurMeth.LateResolveTypes); diff --git a/lib/Bytecode/Reader/ConstantReader.cpp b/lib/Bytecode/Reader/ConstantReader.cpp index d2818ef3164..d1c8644ddd4 100644 --- a/lib/Bytecode/Reader/ConstantReader.cpp +++ b/lib/Bytecode/Reader/ConstantReader.cpp @@ -352,7 +352,8 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, // Create a placeholder for the global variable reference... GlobalVariable *GVar = - new GlobalVariable(PT->getElementType(), false, true); + new GlobalVariable(PT->getElementType(), false, + GlobalValue::InternalLinkage); // Keep track of the fact that we have a forward ref to recycle it GlobalRefs.insert(std::make_pair(std::make_pair(PT, Slot), GVar)); diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 805b7e7292b..fb561aa16ce 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -307,7 +307,8 @@ bool BytecodeParser::ParseFunction(const uchar *&Buf, const uchar *EndBuf) { Function *F = FunctionSignatureList.back().first; unsigned FunctionSlot = FunctionSignatureList.back().second; FunctionSignatureList.pop_back(); - F->setInternalLinkage(isInternal != 0); + F->setLinkage(isInternal ? GlobalValue::InternalLinkage : + GlobalValue::ExternalLinkage); const FunctionType::ParamTypes &Params =F->getFunctionType()->getParamTypes(); Function::aiterator AI = F->abegin(); @@ -399,8 +400,13 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End){ const Type *ElTy = cast(Ty)->getElementType(); + + GlobalValue::LinkageTypes Linkage = + (VarType & 4) ? GlobalValue::InternalLinkage : + GlobalValue::ExternalLinkage; + // Create the global variable... - GlobalVariable *GV = new GlobalVariable(ElTy, VarType & 1, VarType & 4, + GlobalVariable *GV = new GlobalVariable(ElTy, VarType & 1, Linkage, 0, "", TheModule); int DestSlot = insertValue(GV, ModuleValues); if (DestSlot == -1) return true; @@ -435,7 +441,8 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End){ // this placeholder is replaced. // Insert the placeholder... - Function *Func = new Function(cast(Ty), false, "", TheModule); + Function *Func = new Function(cast(Ty), + GlobalValue::InternalLinkage, "", TheModule); int DestSlot = insertValue(Func, ModuleValues); if (DestSlot == -1) return true; ResolveReferencesToValue(Func, (unsigned)DestSlot); diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 60c6e03ae12..b5207a85429 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -189,42 +189,48 @@ static bool LinkGlobals(Module *Dest, const Module *Src, // for (Module::const_giterator I = Src->gbegin(), E = Src->gend(); I != E; ++I){ const GlobalVariable *SGV = I; - Value *V; - - // If the global variable has a name, and that name is already in use in the - // Dest module, make sure that the name is a compatible global variable... - // - if (SGV->hasExternalLinkage() && SGV->hasName() && - (V = ST->lookup(SGV->getType(), SGV->getName())) && - cast(V)->hasExternalLinkage()) { - // The same named thing is a global variable, because the only two things + GlobalVariable *DGV = 0; + if (SGV->hasName()) { + // A same named thing is a global variable, because the only two things // that may be in a module level symbol table are Global Vars and // Functions, and they both have distinct, nonoverlapping, possible types. // - GlobalVariable *DGV = cast(V); + DGV = cast_or_null(ST->lookup(SGV->getType(), + SGV->getName())); + } - // Check to see if the two GV's have the same Const'ness... - if (SGV->isConstant() != DGV->isConstant()) - return Error(Err, "Global Variable Collision on '" + - SGV->getType()->getDescription() + "':%" + SGV->getName() + - " - Global variables differ in const'ness"); + assert(SGV->hasInitializer() || SGV->hasExternalLinkage() && + "Global must either be external or have an initializer!"); - // Okay, everything is cool, remember the mapping... - ValueMap.insert(std::make_pair(SGV, DGV)); - } else { + if (!DGV || DGV->hasInternalLinkage() || SGV->hasInternalLinkage()) { // No linking to be performed, simply create an identical version of the // symbol over in the dest module... the initializer will be filled in // later by LinkGlobalInits... // - GlobalVariable *DGV = - new GlobalVariable(SGV->getType()->getElementType(), SGV->isConstant(), - SGV->hasInternalLinkage(), 0, SGV->getName()); - - // Add the new global to the dest module - Dest->getGlobalList().push_back(DGV); + DGV = new GlobalVariable(SGV->getType()->getElementType(), + SGV->isConstant(), SGV->getLinkage(), /*init*/0, + SGV->getName(), Dest); // Make sure to remember this mapping... ValueMap.insert(std::make_pair(SGV, DGV)); + } else if (SGV->getLinkage() != DGV->getLinkage()) { + return Error(Err, "Global variables named '" + SGV->getName() + + "' have different linkage specifiers!"); + } else if (SGV->hasExternalLinkage() || SGV->hasLinkOnceLinkage() || + SGV->hasAppendingLinkage()) { + // If the global variable has a name, and that name is already in use in + // the Dest module, make sure that the name is a compatible global + // variable... + // + // Check to see if the two GV's have the same Const'ness... + if (SGV->isConstant() != DGV->isConstant()) + return Error(Err, "Global Variable Collision on '" + + SGV->getType()->getDescription() + "':%" + SGV->getName() + + " - Global variables differ in const'ness"); + // Okay, everything is cool, remember the mapping... + ValueMap.insert(std::make_pair(SGV, DGV)); + } else { + assert(0 && "Unknown linkage!"); } } return false; @@ -245,19 +251,28 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src, if (SGV->hasInitializer()) { // Only process initialized GV's // Figure out what the initializer looks like in the dest module... - Constant *DInit = + Constant *SInit = cast(RemapOperand(SGV->getInitializer(), ValueMap, 0)); GlobalVariable *DGV = cast(ValueMap[SGV]); - if (DGV->hasInitializer() && SGV->hasExternalLinkage() && - DGV->hasExternalLinkage()) { - if (DGV->getInitializer() != DInit) - return Error(Err, "Global Variable Collision on '" + - SGV->getType()->getDescription() + "':%" +SGV->getName()+ - " - Global variables have different initializers"); + if (DGV->hasInitializer()) { + assert(SGV->getLinkage() == DGV->getLinkage()); + if (SGV->hasExternalLinkage()) { + if (DGV->getInitializer() != SInit) + return Error(Err, "Global Variable Collision on '" + + SGV->getType()->getDescription() +"':%"+SGV->getName()+ + " - Global variables have different initializers"); + } else if (DGV->hasLinkOnceLinkage()) { + // Nothing is required, mapped values will take the new global + // automatically. + } else if (DGV->hasAppendingLinkage()) { + assert(0 && "Appending linkage unimplemented!"); + } else { + assert(0 && "Unknown linkage!"); + } } else { // Copy the initializer over now... - DGV->setInitializer(DInit); + DGV->setInitializer(SInit); } } } @@ -278,39 +293,42 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, // for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) { const Function *SF = I; // SrcFunction - Value *V; - - // If the function has a name, and that name is already in use in the Dest - // module, make sure that the name is a compatible function... - // - if (SF->hasExternalLinkage() && SF->hasName() && - (V = ST->lookup(SF->getType(), SF->getName())) && - cast(V)->hasExternalLinkage()) { + Function *DF = 0; + if (SF->hasName()) // The same named thing is a Function, because the only two things // that may be in a module level symbol table are Global Vars and // Functions, and they both have distinct, nonoverlapping, possible types. // - Function *DF = cast(V); // DestFunction + DF = cast_or_null(ST->lookup(SF->getType(), SF->getName())); + if (!DF || SF->hasInternalLinkage() || DF->hasInternalLinkage()) { + // Function does not already exist, simply insert an external function + // signature identical to SF into the dest module... + Function *DF = new Function(SF->getFunctionType(), SF->getLinkage(), + SF->getName(), Dest); + + // ... and remember this mapping... + ValueMap.insert(std::make_pair(SF, DF)); + } else if (SF->getLinkage() != DF->getLinkage()) { + return Error(Err, "Functions named '" + SF->getName() + + "' have different linkage specifiers!"); + } else if (SF->getLinkage() == GlobalValue::AppendingLinkage) { + return Error(Err, "Functions named '" + SF->getName() + + "' have appending linkage!"); + } else if (SF->getLinkage() == GlobalValue::ExternalLinkage) { + // If the function has a name, and that name is already in use in the Dest + // module, make sure that the name is a compatible function... + // // Check to make sure the function is not defined in both modules... if (!SF->isExternal() && !DF->isExternal()) return Error(Err, "Function '" + SF->getFunctionType()->getDescription() + "':\"" + SF->getName() + "\" - Function is already defined!"); - + // Otherwise, just remember this mapping... ValueMap.insert(std::make_pair(SF, DF)); - } else { - // Function does not already exist, simply insert an external function - // signature identical to SF into the dest module... - Function *DF = new Function(SF->getFunctionType(), - SF->hasInternalLinkage(), - SF->getName()); - - // Add the function signature to the dest module... - Dest->getFunctionList().push_back(DF); - - // ... and remember this mapping... + } else if (SF->getLinkage() == GlobalValue::LinkOnceLinkage) { + // Completely ignore the source function. ValueMap.insert(std::make_pair(SF, DF)); } } @@ -391,6 +409,7 @@ static bool LinkFunctionBodies(Module *Dest, const Module *Src, // DF not external SF external? if (!DF->isExternal()) { + if (DF->hasLinkOnceLinkage()) continue; // No relinkage for link-once! if (Err) *Err = "Function '" + (SF->hasName() ? SF->getName() :std::string("")) + "' body multiply defined!"; diff --git a/lib/Target/SparcV9/SparcV9PreSelection.cpp b/lib/Target/SparcV9/SparcV9PreSelection.cpp index 7cd5b1dc055..b4bbc77a071 100644 --- a/lib/Target/SparcV9/SparcV9PreSelection.cpp +++ b/lib/Target/SparcV9/SparcV9PreSelection.cpp @@ -87,7 +87,8 @@ namespace { GV = PI->second; // put in map else { - GV = new GlobalVariable(CV->getType(), true,true,CV); //put in map + GV = new GlobalVariable(CV->getType(), true, //put in map + GlobalValue::InternalLinkage, CV); myModule->getGlobalList().push_back(GV); // GV owned by module now } } diff --git a/lib/Transforms/IPO/ExtractFunction.cpp b/lib/Transforms/IPO/ExtractFunction.cpp index a2d28f58c68..f16c3f32530 100644 --- a/lib/Transforms/IPO/ExtractFunction.cpp +++ b/lib/Transforms/IPO/ExtractFunction.cpp @@ -16,13 +16,13 @@ namespace { } // Make sure our result is globally accessable... - Named->setInternalLinkage(false); + Named->setLinkage(GlobalValue::ExternalLinkage); // Mark all global variables internal for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) if (!I->isExternal()) { I->setInitializer(0); // Make all variables external - I->setInternalLinkage(false); // Make sure it's not internal + I->setLinkage(GlobalValue::ExternalLinkage); } // All of the functions may be used by global variables or the named @@ -35,7 +35,9 @@ namespace { for (Module::iterator I = M.begin(); ; ++I) { if (&*I != Named) { - Function *New = new Function(I->getFunctionType(),false,I->getName()); + Function *New = new Function(I->getFunctionType(), + GlobalValue::ExternalLinkage, + I->getName()); I->setName(""); // Remove Old name // If it's not the named function, delete the body of the function diff --git a/lib/Transforms/IPO/Internalize.cpp b/lib/Transforms/IPO/Internalize.cpp index 910e1d4322d..f09fd141c72 100644 --- a/lib/Transforms/IPO/Internalize.cpp +++ b/lib/Transforms/IPO/Internalize.cpp @@ -29,7 +29,7 @@ namespace { if (&*I != MainFunc && // Leave the main function external !I->isExternal() && // Function must be defined here !I->hasInternalLinkage()) { // Can't already have internal linkage - I->setInternalLinkage(true); + I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumFunctions; DEBUG(std::cerr << "Internalizing func " << I->getName() << "\n"); @@ -38,7 +38,7 @@ namespace { // Mark all global variables with initializers as internal as well... for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) if (!I->isExternal() && I->hasExternalLinkage()) { - I->setInternalLinkage(true); + I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumGlobals; DEBUG(std::cerr << "Internalizing gvar " << I->getName() << "\n"); diff --git a/lib/Transforms/IPO/MutateStructTypes.cpp b/lib/Transforms/IPO/MutateStructTypes.cpp index b7418ec6e3e..8e58d4dbb20 100644 --- a/lib/Transforms/IPO/MutateStructTypes.cpp +++ b/lib/Transforms/IPO/MutateStructTypes.cpp @@ -250,8 +250,7 @@ void MutateStructTypes::processGlobals(Module &M) { cast(ConvertType(I->getFunctionType())); // Create a new function to put stuff into... - Function *NewMeth = new Function(NewMTy, I->hasInternalLinkage(), - I->getName()); + Function *NewMeth = new Function(NewMTy, I->getLinkage(), I->getName()); if (I->hasName()) I->setName("OLD."+I->getName()); diff --git a/lib/Transforms/IPO/Parallelize.cpp b/lib/Transforms/IPO/Parallelize.cpp index 08c800eb1c7..46fbcc7d855 100644 --- a/lib/Transforms/IPO/Parallelize.cpp +++ b/lib/Transforms/IPO/Parallelize.cpp @@ -137,7 +137,8 @@ Cilkifier::Cilkifier(Module& M) DummySyncFunc = new Function(FunctionType::get( Type::VoidTy, std::vector(), /*isVararg*/ false), - /*isInternal*/ false, DummySyncFuncName, &M); + GlobalValue::ExternalLinkage, DummySyncFuncName, + &M); } void Cilkifier::TransformFunc(Function* F, diff --git a/lib/Transforms/IPO/PoolAllocate.cpp b/lib/Transforms/IPO/PoolAllocate.cpp index b2efc12de27..844d0c15ffa 100644 --- a/lib/Transforms/IPO/PoolAllocate.cpp +++ b/lib/Transforms/IPO/PoolAllocate.cpp @@ -161,7 +161,8 @@ Function *PoolAllocate::MakeFunctionClone(Function &F) { FunctionType *FuncTy = FunctionType::get(OldFuncTy->getReturnType(), ArgTys, OldFuncTy->isVarArg()); // Create the new function... - Function *New = new Function(FuncTy, true, F.getName(), F.getParent()); + Function *New = new Function(FuncTy, GlobalValue::InternalLinkage, + F.getName(), F.getParent()); // Set the rest of the new arguments names to be PDa and add entries to the // pool descriptors map diff --git a/lib/Transforms/Instrumentation/EmitFunctions.cpp b/lib/Transforms/Instrumentation/EmitFunctions.cpp index d4a99e2c674..32488d69b53 100644 --- a/lib/Transforms/Instrumentation/EmitFunctions.cpp +++ b/lib/Transforms/Instrumentation/EmitFunctions.cpp @@ -33,7 +33,8 @@ bool EmitFunctionTable::run(Module &M){ StructType *sttype = StructType::get(vType); ConstantStruct *cstruct = ConstantStruct::get(sttype, vConsts); - GlobalVariable *gb = new GlobalVariable(cstruct->getType(), true, false, + GlobalVariable *gb = new GlobalVariable(cstruct->getType(), true, + GlobalValue::ExternalLinkage, cstruct, "llvmFunctionTable"); M.getGlobalList().push_back(gb); return true; // Always modifies program diff --git a/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp b/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp index 39e7c351210..57b17a590ff 100644 --- a/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp +++ b/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp @@ -183,14 +183,19 @@ bool ProfilePaths::runOnFunction(Function &F){ for(int xi=0; xigetGlobalList().push_back(threshold); insertedThreshold = true; diff --git a/lib/Transforms/Instrumentation/TraceValues.cpp b/lib/Transforms/Instrumentation/TraceValues.cpp index c19848dd4b5..75149ce9123 100644 --- a/lib/Transforms/Instrumentation/TraceValues.cpp +++ b/lib/Transforms/Instrumentation/TraceValues.cpp @@ -154,7 +154,8 @@ static inline GlobalVariable *getStringRef(Module *M, const string &str) { // Create the global variable and record it in the module // The GV will be renamed to a unique name if needed. - GlobalVariable *GV = new GlobalVariable(Init->getType(), true, true, Init, + GlobalVariable *GV = new GlobalVariable(Init->getType(), true, + GlobalValue::InternalLinkage, Init, "trstr"); M->getGlobalList().push_back(GV); return GV; diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp index ca22003b409..512bd38d839 100644 --- a/lib/Transforms/Utils/CloneFunction.cpp +++ b/lib/Transforms/Utils/CloneFunction.cpp @@ -110,7 +110,7 @@ Function *CloneFunction(const Function *F, ArgTypes, F->getFunctionType()->isVarArg()); // Create the new function... - Function *NewF = new Function(FTy, F->hasInternalLinkage(), F->getName()); + Function *NewF = new Function(FTy, F->getLinkage(), F->getName()); // Loop over the arguments, copying the names of the mapped arguments over... Function::aiterator DestI = NewF->abegin(); diff --git a/lib/Transforms/Utils/CloneModule.cpp b/lib/Transforms/Utils/CloneModule.cpp index 043e06d5437..223e3fd88cd 100644 --- a/lib/Transforms/Utils/CloneModule.cpp +++ b/lib/Transforms/Utils/CloneModule.cpp @@ -29,13 +29,14 @@ Module *CloneModule(const Module *M) { // don't worry about attributes or initializers, they will come later. // for (Module::const_giterator I = M->gbegin(), E = M->gend(); I != E; ++I) - ValueMap[I] = new GlobalVariable(I->getType()->getElementType(), - false, false, 0, I->getName(), New); + ValueMap[I] = new GlobalVariable(I->getType()->getElementType(), false, + GlobalValue::ExternalLinkage, 0, + I->getName(), New); // Loop over the functions in the module, making external functions as before for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) ValueMap[I]=new Function(cast(I->getType()->getElementType()), - false, I->getName(), New); + GlobalValue::ExternalLinkage, I->getName(), New); // Now that all of the things that global variable initializer can refer to // have been created, loop through and copy the global variable referrers @@ -46,8 +47,7 @@ Module *CloneModule(const Module *M) { if (I->hasInitializer()) GV->setInitializer(cast(MapValue(I->getInitializer(), ValueMap))); - if (I->hasInternalLinkage()) - GV->setInternalLinkage(true); + GV->setLinkage(I->getLinkage()); } // Similarly, copy over function bodies now... @@ -65,8 +65,7 @@ Module *CloneModule(const Module *M) { CloneFunctionInto(F, I, ValueMap, Returns); } - if (I->hasInternalLinkage()) - F->setInternalLinkage(true); + F->setLinkage(I->getLinkage()); } return New; diff --git a/lib/Transforms/Utils/Linker.cpp b/lib/Transforms/Utils/Linker.cpp index 60c6e03ae12..b5207a85429 100644 --- a/lib/Transforms/Utils/Linker.cpp +++ b/lib/Transforms/Utils/Linker.cpp @@ -189,42 +189,48 @@ static bool LinkGlobals(Module *Dest, const Module *Src, // for (Module::const_giterator I = Src->gbegin(), E = Src->gend(); I != E; ++I){ const GlobalVariable *SGV = I; - Value *V; - - // If the global variable has a name, and that name is already in use in the - // Dest module, make sure that the name is a compatible global variable... - // - if (SGV->hasExternalLinkage() && SGV->hasName() && - (V = ST->lookup(SGV->getType(), SGV->getName())) && - cast(V)->hasExternalLinkage()) { - // The same named thing is a global variable, because the only two things + GlobalVariable *DGV = 0; + if (SGV->hasName()) { + // A same named thing is a global variable, because the only two things // that may be in a module level symbol table are Global Vars and // Functions, and they both have distinct, nonoverlapping, possible types. // - GlobalVariable *DGV = cast(V); + DGV = cast_or_null(ST->lookup(SGV->getType(), + SGV->getName())); + } - // Check to see if the two GV's have the same Const'ness... - if (SGV->isConstant() != DGV->isConstant()) - return Error(Err, "Global Variable Collision on '" + - SGV->getType()->getDescription() + "':%" + SGV->getName() + - " - Global variables differ in const'ness"); + assert(SGV->hasInitializer() || SGV->hasExternalLinkage() && + "Global must either be external or have an initializer!"); - // Okay, everything is cool, remember the mapping... - ValueMap.insert(std::make_pair(SGV, DGV)); - } else { + if (!DGV || DGV->hasInternalLinkage() || SGV->hasInternalLinkage()) { // No linking to be performed, simply create an identical version of the // symbol over in the dest module... the initializer will be filled in // later by LinkGlobalInits... // - GlobalVariable *DGV = - new GlobalVariable(SGV->getType()->getElementType(), SGV->isConstant(), - SGV->hasInternalLinkage(), 0, SGV->getName()); - - // Add the new global to the dest module - Dest->getGlobalList().push_back(DGV); + DGV = new GlobalVariable(SGV->getType()->getElementType(), + SGV->isConstant(), SGV->getLinkage(), /*init*/0, + SGV->getName(), Dest); // Make sure to remember this mapping... ValueMap.insert(std::make_pair(SGV, DGV)); + } else if (SGV->getLinkage() != DGV->getLinkage()) { + return Error(Err, "Global variables named '" + SGV->getName() + + "' have different linkage specifiers!"); + } else if (SGV->hasExternalLinkage() || SGV->hasLinkOnceLinkage() || + SGV->hasAppendingLinkage()) { + // If the global variable has a name, and that name is already in use in + // the Dest module, make sure that the name is a compatible global + // variable... + // + // Check to see if the two GV's have the same Const'ness... + if (SGV->isConstant() != DGV->isConstant()) + return Error(Err, "Global Variable Collision on '" + + SGV->getType()->getDescription() + "':%" + SGV->getName() + + " - Global variables differ in const'ness"); + // Okay, everything is cool, remember the mapping... + ValueMap.insert(std::make_pair(SGV, DGV)); + } else { + assert(0 && "Unknown linkage!"); } } return false; @@ -245,19 +251,28 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src, if (SGV->hasInitializer()) { // Only process initialized GV's // Figure out what the initializer looks like in the dest module... - Constant *DInit = + Constant *SInit = cast(RemapOperand(SGV->getInitializer(), ValueMap, 0)); GlobalVariable *DGV = cast(ValueMap[SGV]); - if (DGV->hasInitializer() && SGV->hasExternalLinkage() && - DGV->hasExternalLinkage()) { - if (DGV->getInitializer() != DInit) - return Error(Err, "Global Variable Collision on '" + - SGV->getType()->getDescription() + "':%" +SGV->getName()+ - " - Global variables have different initializers"); + if (DGV->hasInitializer()) { + assert(SGV->getLinkage() == DGV->getLinkage()); + if (SGV->hasExternalLinkage()) { + if (DGV->getInitializer() != SInit) + return Error(Err, "Global Variable Collision on '" + + SGV->getType()->getDescription() +"':%"+SGV->getName()+ + " - Global variables have different initializers"); + } else if (DGV->hasLinkOnceLinkage()) { + // Nothing is required, mapped values will take the new global + // automatically. + } else if (DGV->hasAppendingLinkage()) { + assert(0 && "Appending linkage unimplemented!"); + } else { + assert(0 && "Unknown linkage!"); + } } else { // Copy the initializer over now... - DGV->setInitializer(DInit); + DGV->setInitializer(SInit); } } } @@ -278,39 +293,42 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, // for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) { const Function *SF = I; // SrcFunction - Value *V; - - // If the function has a name, and that name is already in use in the Dest - // module, make sure that the name is a compatible function... - // - if (SF->hasExternalLinkage() && SF->hasName() && - (V = ST->lookup(SF->getType(), SF->getName())) && - cast(V)->hasExternalLinkage()) { + Function *DF = 0; + if (SF->hasName()) // The same named thing is a Function, because the only two things // that may be in a module level symbol table are Global Vars and // Functions, and they both have distinct, nonoverlapping, possible types. // - Function *DF = cast(V); // DestFunction + DF = cast_or_null(ST->lookup(SF->getType(), SF->getName())); + if (!DF || SF->hasInternalLinkage() || DF->hasInternalLinkage()) { + // Function does not already exist, simply insert an external function + // signature identical to SF into the dest module... + Function *DF = new Function(SF->getFunctionType(), SF->getLinkage(), + SF->getName(), Dest); + + // ... and remember this mapping... + ValueMap.insert(std::make_pair(SF, DF)); + } else if (SF->getLinkage() != DF->getLinkage()) { + return Error(Err, "Functions named '" + SF->getName() + + "' have different linkage specifiers!"); + } else if (SF->getLinkage() == GlobalValue::AppendingLinkage) { + return Error(Err, "Functions named '" + SF->getName() + + "' have appending linkage!"); + } else if (SF->getLinkage() == GlobalValue::ExternalLinkage) { + // If the function has a name, and that name is already in use in the Dest + // module, make sure that the name is a compatible function... + // // Check to make sure the function is not defined in both modules... if (!SF->isExternal() && !DF->isExternal()) return Error(Err, "Function '" + SF->getFunctionType()->getDescription() + "':\"" + SF->getName() + "\" - Function is already defined!"); - + // Otherwise, just remember this mapping... ValueMap.insert(std::make_pair(SF, DF)); - } else { - // Function does not already exist, simply insert an external function - // signature identical to SF into the dest module... - Function *DF = new Function(SF->getFunctionType(), - SF->hasInternalLinkage(), - SF->getName()); - - // Add the function signature to the dest module... - Dest->getFunctionList().push_back(DF); - - // ... and remember this mapping... + } else if (SF->getLinkage() == GlobalValue::LinkOnceLinkage) { + // Completely ignore the source function. ValueMap.insert(std::make_pair(SF, DF)); } } @@ -391,6 +409,7 @@ static bool LinkFunctionBodies(Module *Dest, const Module *Src, // DF not external SF external? if (!DF->isExternal()) { + if (DF->hasLinkOnceLinkage()) continue; // No relinkage for link-once! if (Err) *Err = "Function '" + (SF->hasName() ? SF->getName() :std::string("")) + "' body multiply defined!"; diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 958980bad67..c55a87515c5 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -535,8 +535,15 @@ void AssemblyWriter::printModule(const Module *M) { void AssemblyWriter::printGlobal(const GlobalVariable *GV) { if (GV->hasName()) Out << "%" << GV->getName() << " = "; - if (GV->hasInternalLinkage()) Out << "internal "; - if (!GV->hasInitializer()) Out << "external "; + if (!GV->hasInitializer()) + Out << "external "; + else + switch (GV->getLinkage()) { + case GlobalValue::InternalLinkage: Out << "internal "; break; + case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break; + case GlobalValue::AppendingLinkage: Out << "appending "; break; + case GlobalValue::ExternalLinkage: break; + } Out << (GV->isConstant() ? "constant " : "global "); printType(GV->getType()->getElementType()); @@ -594,8 +601,18 @@ void AssemblyWriter::printConstant(const Constant *CPV) { // void AssemblyWriter::printFunction(const Function *F) { // Print out the return type and name... - Out << "\n" << (F->isExternal() ? "declare " : "") - << (F->hasInternalLinkage() ? "internal " : ""); + Out << "\n"; + + if (F->isExternal()) + Out << "declare "; + else + switch (F->getLinkage()) { + case GlobalValue::InternalLinkage: Out << "internal "; break; + case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break; + case GlobalValue::AppendingLinkage: Out << "appending "; break; + case GlobalValue::ExternalLinkage: break; + } + printType(F->getReturnType()) << " %" << F->getName() << "("; Table.incorporateFunction(F); diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 70569c0f67c..3324565654b 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -77,9 +77,9 @@ void Argument::setParent(Function *parent) { // Function Implementation //===----------------------------------------------------------------------===// -Function::Function(const FunctionType *Ty, bool isInternal, +Function::Function(const FunctionType *Ty, LinkageTypes Linkage, const std::string &name, Module *ParentModule) - : GlobalValue(PointerType::get(Ty), Value::FunctionVal, isInternal, name) { + : GlobalValue(PointerType::get(Ty), Value::FunctionVal, Linkage, name) { BasicBlocks.setItemParent(this); BasicBlocks.setParent(this); ArgumentList.setItemParent(this); @@ -154,10 +154,10 @@ void Function::dropAllReferences() { // GlobalVariable Implementation //===----------------------------------------------------------------------===// -GlobalVariable::GlobalVariable(const Type *Ty, bool constant, bool isIntern, +GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link, Constant *Initializer, const std::string &Name, Module *ParentModule) - : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal, isIntern, Name), + : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal, Link, Name), isConstantGlobal(constant) { if (Initializer) Operands.push_back(Use((Value*)Initializer, this)); diff --git a/lib/VMCore/Linker.cpp b/lib/VMCore/Linker.cpp index 60c6e03ae12..b5207a85429 100644 --- a/lib/VMCore/Linker.cpp +++ b/lib/VMCore/Linker.cpp @@ -189,42 +189,48 @@ static bool LinkGlobals(Module *Dest, const Module *Src, // for (Module::const_giterator I = Src->gbegin(), E = Src->gend(); I != E; ++I){ const GlobalVariable *SGV = I; - Value *V; - - // If the global variable has a name, and that name is already in use in the - // Dest module, make sure that the name is a compatible global variable... - // - if (SGV->hasExternalLinkage() && SGV->hasName() && - (V = ST->lookup(SGV->getType(), SGV->getName())) && - cast(V)->hasExternalLinkage()) { - // The same named thing is a global variable, because the only two things + GlobalVariable *DGV = 0; + if (SGV->hasName()) { + // A same named thing is a global variable, because the only two things // that may be in a module level symbol table are Global Vars and // Functions, and they both have distinct, nonoverlapping, possible types. // - GlobalVariable *DGV = cast(V); + DGV = cast_or_null(ST->lookup(SGV->getType(), + SGV->getName())); + } - // Check to see if the two GV's have the same Const'ness... - if (SGV->isConstant() != DGV->isConstant()) - return Error(Err, "Global Variable Collision on '" + - SGV->getType()->getDescription() + "':%" + SGV->getName() + - " - Global variables differ in const'ness"); + assert(SGV->hasInitializer() || SGV->hasExternalLinkage() && + "Global must either be external or have an initializer!"); - // Okay, everything is cool, remember the mapping... - ValueMap.insert(std::make_pair(SGV, DGV)); - } else { + if (!DGV || DGV->hasInternalLinkage() || SGV->hasInternalLinkage()) { // No linking to be performed, simply create an identical version of the // symbol over in the dest module... the initializer will be filled in // later by LinkGlobalInits... // - GlobalVariable *DGV = - new GlobalVariable(SGV->getType()->getElementType(), SGV->isConstant(), - SGV->hasInternalLinkage(), 0, SGV->getName()); - - // Add the new global to the dest module - Dest->getGlobalList().push_back(DGV); + DGV = new GlobalVariable(SGV->getType()->getElementType(), + SGV->isConstant(), SGV->getLinkage(), /*init*/0, + SGV->getName(), Dest); // Make sure to remember this mapping... ValueMap.insert(std::make_pair(SGV, DGV)); + } else if (SGV->getLinkage() != DGV->getLinkage()) { + return Error(Err, "Global variables named '" + SGV->getName() + + "' have different linkage specifiers!"); + } else if (SGV->hasExternalLinkage() || SGV->hasLinkOnceLinkage() || + SGV->hasAppendingLinkage()) { + // If the global variable has a name, and that name is already in use in + // the Dest module, make sure that the name is a compatible global + // variable... + // + // Check to see if the two GV's have the same Const'ness... + if (SGV->isConstant() != DGV->isConstant()) + return Error(Err, "Global Variable Collision on '" + + SGV->getType()->getDescription() + "':%" + SGV->getName() + + " - Global variables differ in const'ness"); + // Okay, everything is cool, remember the mapping... + ValueMap.insert(std::make_pair(SGV, DGV)); + } else { + assert(0 && "Unknown linkage!"); } } return false; @@ -245,19 +251,28 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src, if (SGV->hasInitializer()) { // Only process initialized GV's // Figure out what the initializer looks like in the dest module... - Constant *DInit = + Constant *SInit = cast(RemapOperand(SGV->getInitializer(), ValueMap, 0)); GlobalVariable *DGV = cast(ValueMap[SGV]); - if (DGV->hasInitializer() && SGV->hasExternalLinkage() && - DGV->hasExternalLinkage()) { - if (DGV->getInitializer() != DInit) - return Error(Err, "Global Variable Collision on '" + - SGV->getType()->getDescription() + "':%" +SGV->getName()+ - " - Global variables have different initializers"); + if (DGV->hasInitializer()) { + assert(SGV->getLinkage() == DGV->getLinkage()); + if (SGV->hasExternalLinkage()) { + if (DGV->getInitializer() != SInit) + return Error(Err, "Global Variable Collision on '" + + SGV->getType()->getDescription() +"':%"+SGV->getName()+ + " - Global variables have different initializers"); + } else if (DGV->hasLinkOnceLinkage()) { + // Nothing is required, mapped values will take the new global + // automatically. + } else if (DGV->hasAppendingLinkage()) { + assert(0 && "Appending linkage unimplemented!"); + } else { + assert(0 && "Unknown linkage!"); + } } else { // Copy the initializer over now... - DGV->setInitializer(DInit); + DGV->setInitializer(SInit); } } } @@ -278,39 +293,42 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, // for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) { const Function *SF = I; // SrcFunction - Value *V; - - // If the function has a name, and that name is already in use in the Dest - // module, make sure that the name is a compatible function... - // - if (SF->hasExternalLinkage() && SF->hasName() && - (V = ST->lookup(SF->getType(), SF->getName())) && - cast(V)->hasExternalLinkage()) { + Function *DF = 0; + if (SF->hasName()) // The same named thing is a Function, because the only two things // that may be in a module level symbol table are Global Vars and // Functions, and they both have distinct, nonoverlapping, possible types. // - Function *DF = cast(V); // DestFunction + DF = cast_or_null(ST->lookup(SF->getType(), SF->getName())); + if (!DF || SF->hasInternalLinkage() || DF->hasInternalLinkage()) { + // Function does not already exist, simply insert an external function + // signature identical to SF into the dest module... + Function *DF = new Function(SF->getFunctionType(), SF->getLinkage(), + SF->getName(), Dest); + + // ... and remember this mapping... + ValueMap.insert(std::make_pair(SF, DF)); + } else if (SF->getLinkage() != DF->getLinkage()) { + return Error(Err, "Functions named '" + SF->getName() + + "' have different linkage specifiers!"); + } else if (SF->getLinkage() == GlobalValue::AppendingLinkage) { + return Error(Err, "Functions named '" + SF->getName() + + "' have appending linkage!"); + } else if (SF->getLinkage() == GlobalValue::ExternalLinkage) { + // If the function has a name, and that name is already in use in the Dest + // module, make sure that the name is a compatible function... + // // Check to make sure the function is not defined in both modules... if (!SF->isExternal() && !DF->isExternal()) return Error(Err, "Function '" + SF->getFunctionType()->getDescription() + "':\"" + SF->getName() + "\" - Function is already defined!"); - + // Otherwise, just remember this mapping... ValueMap.insert(std::make_pair(SF, DF)); - } else { - // Function does not already exist, simply insert an external function - // signature identical to SF into the dest module... - Function *DF = new Function(SF->getFunctionType(), - SF->hasInternalLinkage(), - SF->getName()); - - // Add the function signature to the dest module... - Dest->getFunctionList().push_back(DF); - - // ... and remember this mapping... + } else if (SF->getLinkage() == GlobalValue::LinkOnceLinkage) { + // Completely ignore the source function. ValueMap.insert(std::make_pair(SF, DF)); } } @@ -391,6 +409,7 @@ static bool LinkFunctionBodies(Module *Dest, const Module *Src, // DF not external SF external? if (!DF->isExternal()) { + if (DF->hasLinkOnceLinkage()) continue; // No relinkage for link-once! if (Err) *Err = "Function '" + (SF->hasName() ? SF->getName() :std::string("")) + "' body multiply defined!"; diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp index f54a6f390be..e0a6fb271ce 100644 --- a/lib/VMCore/Module.cpp +++ b/lib/VMCore/Module.cpp @@ -17,13 +17,14 @@ Function *ilist_traits::createNode() { FunctionType *FTy = FunctionType::get(Type::VoidTy, std::vector(), false); - Function *Ret = new Function(FTy, false); + Function *Ret = new Function(FTy, GlobalValue::ExternalLinkage); // This should not be garbage monitored. LeakDetector::removeGarbageObject(Ret); return Ret; } GlobalVariable *ilist_traits::createNode() { - GlobalVariable *Ret = new GlobalVariable(Type::IntTy, false, false); + GlobalVariable *Ret = new GlobalVariable(Type::IntTy, false, + GlobalValue::ExternalLinkage); // This should not be garbage monitored. LeakDetector::removeGarbageObject(Ret); return Ret; @@ -87,7 +88,7 @@ Function *Module::getOrInsertFunction(const std::string &Name, if (Value *V = SymTab.lookup(PointerType::get(Ty), Name)) { return cast(V); // Yup, got it } else { // Nope, add one - Function *New = new Function(Ty, false, Name); + Function *New = new Function(Ty, GlobalVariable::ExternalLinkage, Name); FunctionList.push_back(New); return New; // Return the new prototype... } -- 2.40.0