From: John McCall Date: Fri, 19 Mar 2010 23:29:14 +0000 (+0000) Subject: Change CodeGenModule to rely on the Module's symbol table instead of X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f746aa6a8f538be914173a4aef2d9a2fd9f99d17;p=clang Change CodeGenModule to rely on the Module's symbol table instead of shadowing it in the GlobalDeclMap. Eliminates the string-uniquing requirement for mangled names, which should help C++ codegen times a little. Forces us to do string lookups instead of pointer lookups, which might hurt codegen times a little across the board. We'll see how it plays out. Removing the string-uniquing requirement implicitly fixes any bugs like PR6635 which arose from the fact that we had multiple uniquing tables for different kinds of identifiers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99012 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 7752cf79a2..b88001c81e 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -165,19 +165,21 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl, new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule()); // Switch any previous uses to the alias. - const char *MangledName = getMangledName(AliasDecl); - llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName]; + MangleBuffer MangledName; + getMangledName(MangledName, AliasDecl); + llvm::GlobalValue *Entry = GetGlobalValue(MangledName); if (Entry) { assert(Entry->isDeclaration() && "definition already exists for alias"); assert(Entry->getType() == AliasType && "declaration exists with different type"); + Alias->takeName(Entry); Entry->replaceAllUsesWith(Alias); Entry->eraseFromParent(); + } else { + Alias->setName(MangledName.getString()); } - Entry = Alias; // Finally, set up the alias with its proper name and attributes. - Alias->setName(MangledName); SetCommonAttributes(AliasDecl.getDecl(), Alias); return false; @@ -214,8 +216,9 @@ void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D, llvm::GlobalValue * CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, CXXCtorType Type) { - const char *Name = getMangledCXXCtorName(D, Type); - if (llvm::GlobalValue *V = GlobalDeclMap[Name]) + MangleBuffer Name; + getMangledCXXCtorName(Name, D, Type); + if (llvm::GlobalValue *V = GetGlobalValue(Name)) return V; const FunctionProtoType *FPT = D->getType()->getAs(); @@ -226,13 +229,10 @@ CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); } -const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, - CXXCtorType Type) { - llvm::SmallString<256> Name; - getMangleContext().mangleCXXCtor(D, Type, Name); - - Name += '\0'; - return UniqueMangledName(Name.begin(), Name.end()); +void CodeGenModule::getMangledCXXCtorName(MangleBuffer &Name, + const CXXConstructorDecl *D, + CXXCtorType Type) { + getMangleContext().mangleCXXCtor(D, Type, Name.getBuffer()); } void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) { @@ -279,8 +279,9 @@ void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D, llvm::GlobalValue * CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, CXXDtorType Type) { - const char *Name = getMangledCXXDtorName(D, Type); - if (llvm::GlobalValue *V = GlobalDeclMap[Name]) + MangleBuffer Name; + getMangledCXXDtorName(Name, D, Type); + if (llvm::GlobalValue *V = GetGlobalValue(Name)) return V; const llvm::FunctionType *FTy = @@ -290,13 +291,10 @@ CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); } -const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D, - CXXDtorType Type) { - llvm::SmallString<256> Name; - getMangleContext().mangleCXXDtor(D, Type, Name); - - Name += '\0'; - return UniqueMangledName(Name.begin(), Name.end()); +void CodeGenModule::getMangledCXXDtorName(MangleBuffer &Name, + const CXXDestructorDecl *D, + CXXDtorType Type) { + getMangleContext().mangleCXXDtor(D, Type, Name.getBuffer()); } llvm::Constant * @@ -470,12 +468,10 @@ CodeGenModule::GetAddrOfThunk(GlobalDecl GD, OutName); else getMangleContext().mangleThunk(MD, ThisAdjustment, OutName); - OutName += '\0'; - const char* Name = UniqueMangledName(OutName.begin(), OutName.end()); // Get function for mangled name const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD); - return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl()); + return GetOrCreateLLVMFunction(OutName, Ty, GlobalDecl()); } llvm::Constant * @@ -484,10 +480,8 @@ CodeGenModule::GetAddrOfCovariantThunk(GlobalDecl GD, const CXXMethodDecl *MD = cast(GD.getDecl()); // Compute mangled name - llvm::SmallString<256> OutName; - getMangleContext().mangleCovariantThunk(MD, Adjustment, OutName); - OutName += '\0'; - const char* Name = UniqueMangledName(OutName.begin(), OutName.end()); + llvm::SmallString<256> Name; + getMangleContext().mangleCovariantThunk(MD, Adjustment, Name); // Get function for mangled name const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD); @@ -528,9 +522,6 @@ void CodeGenModule::BuildThunksForVirtual(GlobalDecl GD) { llvm::Constant *SubExpr = cast(FnConst)->getOperand(0); llvm::Function *OldFn = cast(SubExpr); - std::string Name = OldFn->getNameStr(); - GlobalDeclMap.erase(UniqueMangledName(Name.data(), - Name.data() + Name.size() + 1)); llvm::Constant *NewFnConst; if (!ReturnAdjustment.isEmpty()) NewFnConst = GetAddrOfCovariantThunk(GD, CoAdj); diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index a40a5fbdce..ad97d08a2b 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -569,13 +569,13 @@ CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method, isa(Method) || isa(Method); llvm::StringRef MethodName = getFunctionName(Method); - llvm::StringRef MethodLinkageName; llvm::DIType MethodTy = getOrCreateMethodType(Method, Unit); // Since a single ctor/dtor corresponds to multiple functions, it doesn't // make sense to give a single ctor/dtor a linkage name. + MangleBuffer MethodLinkageName; if (!IsCtorOrDtor) - MethodLinkageName = CGM.getMangledName(Method); + CGM.getMangledName(MethodLinkageName, Method); SourceManager &SM = CGM.getContext().getSourceManager(); @@ -1307,7 +1307,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, CGBuilderTy &Builder) { llvm::StringRef Name; - llvm::StringRef LinkageName; + MangleBuffer LinkageName; const Decl *D = GD.getDecl(); if (const FunctionDecl *FD = dyn_cast(D)) { @@ -1326,11 +1326,11 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, if (!Name.empty() && Name[0] == '\01') Name = Name.substr(1); // Use mangled name as linkage name for c/c++ functions. - LinkageName = CGM.getMangledName(GD); + CGM.getMangledName(LinkageName, GD); } else { // Use llvm function name as linkage name. Name = Fn->getName(); - LinkageName = Name; + LinkageName.setString(Name); if (!Name.empty() && Name[0] == '\01') Name = Name.substr(1); } diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 1dc083f387..4eb95af8ff 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -103,13 +103,18 @@ void CodeGenFunction::EmitBlockVarDecl(const VarDecl &D) { static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D, const char *Separator) { CodeGenModule &CGM = CGF.CGM; - if (CGF.getContext().getLangOptions().CPlusPlus) - return CGM.getMangledName(&D); + if (CGF.getContext().getLangOptions().CPlusPlus) { + MangleBuffer Name; + CGM.getMangledName(Name, &D); + return Name.getString().str(); + } std::string ContextName; - if (const FunctionDecl *FD = dyn_cast(CGF.CurFuncDecl)) - ContextName = CGM.getMangledName(FD); - else if (isa(CGF.CurFuncDecl)) + if (const FunctionDecl *FD = dyn_cast(CGF.CurFuncDecl)) { + MangleBuffer Name; + CGM.getMangledName(Name, FD); + ContextName = Name.getString().str(); + } else if (isa(CGF.CurFuncDecl)) ContextName = CGF.CurFn->getName(); else // FIXME: What about in a block?? diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index f41db14f1a..3b04cc125e 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -163,15 +163,15 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV, } } -const char *CodeGenModule::getMangledName(const GlobalDecl &GD) { +void CodeGenModule::getMangledName(MangleBuffer &Buffer, GlobalDecl GD) { const NamedDecl *ND = cast(GD.getDecl()); if (const CXXConstructorDecl *D = dyn_cast(ND)) - return getMangledCXXCtorName(D, GD.getCtorType()); + return getMangledCXXCtorName(Buffer, D, GD.getCtorType()); if (const CXXDestructorDecl *D = dyn_cast(ND)) - return getMangledCXXDtorName(D, GD.getDtorType()); + return getMangledCXXDtorName(Buffer, D, GD.getDtorType()); - return getMangledName(ND); + return getMangledName(Buffer, ND); } /// \brief Retrieves the mangled name for the given declaration. @@ -180,23 +180,19 @@ const char *CodeGenModule::getMangledName(const GlobalDecl &GD) { /// const char* containing the mangled name. Otherwise, returns /// the unmangled name. /// -const char *CodeGenModule::getMangledName(const NamedDecl *ND) { +void CodeGenModule::getMangledName(MangleBuffer &Buffer, + const NamedDecl *ND) { if (!getMangleContext().shouldMangleDeclName(ND)) { assert(ND->getIdentifier() && "Attempt to mangle unnamed decl."); - return ND->getNameAsCString(); + Buffer.setString(ND->getNameAsCString()); + return; } - llvm::SmallString<256> Name; - getMangleContext().mangleName(ND, Name); - Name += '\0'; - return UniqueMangledName(Name.begin(), Name.end()); + getMangleContext().mangleName(ND, Buffer.getBuffer()); } -const char *CodeGenModule::UniqueMangledName(const char *NameStart, - const char *NameEnd) { - assert(*(NameEnd - 1) == '\0' && "Mangled name must be null terminated!"); - - return MangledNames.GetOrCreateValue(NameStart, NameEnd).getKeyData(); +llvm::GlobalValue *CodeGenModule::GetGlobalValue(llvm::StringRef Name) { + return getModule().getNamedValue(Name); } /// AddGlobalCtor - Add a function to the list that will be called before @@ -505,11 +501,12 @@ void CodeGenModule::EmitDeferred() { GlobalDecl D = DeferredDeclsToEmit.back(); DeferredDeclsToEmit.pop_back(); - // The mangled name for the decl must have been emitted in GlobalDeclMap. // Look it up to see if it was defined with a stronger definition (e.g. an // extern inline function with a strong function redefinition). If so, // just ignore the deferred decl. - llvm::GlobalValue *CGRef = GlobalDeclMap[getMangledName(D)]; + MangleBuffer Name; + getMangledName(Name, D); + llvm::GlobalValue *CGRef = GetGlobalValue(Name); assert(CGRef && "Deferred decl wasn't referenced?"); if (!CGRef->isDeclaration()) @@ -644,18 +641,14 @@ llvm::Constant *CodeGenModule::GetWeakRefReference(const ValueDecl *VD) { const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(VD->getType()); - // Unique the name through the identifier table. - const char *AliaseeName = - getContext().Idents.get(AA->getAliasee()).getNameStart(); - // See if there is already something with the target's name in the module. - llvm::GlobalValue *Entry = GlobalDeclMap[AliaseeName]; + llvm::GlobalValue *Entry = GetGlobalValue(AA->getAliasee()); llvm::Constant *Aliasee; if (isa(DeclTy)) - Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, GlobalDecl()); + Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GlobalDecl()); else - Aliasee = GetOrCreateLLVMGlobal(AliaseeName, + Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), llvm::PointerType::getUnqual(DeclTy), 0); if (!Entry) { llvm::GlobalValue* F = cast(Aliasee); @@ -676,7 +669,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { // If this is an alias definition (which otherwise looks like a declaration) // emit it now. if (Global->hasAttr()) - return EmitAliasDefinition(Global); + return EmitAliasDefinition(GD); // Ignore declarations, they will be emitted on their first use. if (const FunctionDecl *FD = dyn_cast(Global)) { @@ -696,8 +689,9 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { if (MayDeferGeneration(Global)) { // If the value has already been used, add it directly to the // DeferredDeclsToEmit list. - const char *MangledName = getMangledName(GD); - if (GlobalDeclMap.count(MangledName)) + MangleBuffer MangledName; + getMangledName(MangledName, GD); + if (GetGlobalValue(MangledName)) DeferredDeclsToEmit.push_back(GD); else { // Otherwise, remember that we saw a deferred decl with this name. The @@ -753,11 +747,12 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) { /// /// If D is non-null, it specifies a decl that correspond to this. This is used /// to set the attributes on the function when it is first created. -llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName, - const llvm::Type *Ty, - GlobalDecl D) { +llvm::Constant * +CodeGenModule::GetOrCreateLLVMFunction(llvm::StringRef MangledName, + const llvm::Type *Ty, + GlobalDecl D) { // Lookup the entry, lazily creating it if necessary. - llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName]; + llvm::GlobalValue *Entry = GetGlobalValue(MangledName); if (Entry) { if (WeakRefReferences.count(Entry)) { const FunctionDecl *FD = cast_or_null(D.getDecl()); @@ -786,17 +781,15 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName, } llvm::Function *F = llvm::Function::Create(cast(Ty), llvm::Function::ExternalLinkage, - "", &getModule()); - F->setName(MangledName); + MangledName, &getModule()); + assert(F->getName() == MangledName && "name was uniqued!"); if (D.getDecl()) SetFunctionAttributes(D, F, IsIncompleteFunction); - Entry = F; // This is the first use or definition of a mangled name. If there is a // deferred decl with this name, remember that we need to emit it at the end // of the file. - llvm::DenseMap::iterator DDI = - DeferredDecls.find(MangledName); + llvm::StringMap::iterator DDI = DeferredDecls.find(MangledName); if (DDI != DeferredDecls.end()) { // Move the potentially referenced deferred decl to the DeferredDeclsToEmit // list, and remove it from DeferredDecls (since we don't need it anymore). @@ -839,16 +832,16 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD, // If there was no specific requested type, just convert it now. if (!Ty) Ty = getTypes().ConvertType(cast(GD.getDecl())->getType()); - return GetOrCreateLLVMFunction(getMangledName(GD), Ty, GD); + MangleBuffer MangledName; + getMangledName(MangledName, GD); + return GetOrCreateLLVMFunction(MangledName, Ty, GD); } /// CreateRuntimeFunction - Create a new runtime function with the specified /// type and name. llvm::Constant * CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy, - const char *Name) { - // Convert Name to be a uniqued string from the IdentifierInfo table. - Name = getContext().Idents.get(Name).getNameStart(); + llvm::StringRef Name) { return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl()); } @@ -870,11 +863,12 @@ static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D) { /// /// If D is non-null, it specifies a decl that correspond to this. This is used /// to set the attributes on the global when it is first created. -llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName, - const llvm::PointerType*Ty, - const VarDecl *D) { +llvm::Constant * +CodeGenModule::GetOrCreateLLVMGlobal(llvm::StringRef MangledName, + const llvm::PointerType *Ty, + const VarDecl *D) { // Lookup the entry, lazily creating it if necessary. - llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName]; + llvm::GlobalValue *Entry = GetGlobalValue(MangledName); if (Entry) { if (WeakRefReferences.count(Entry)) { if (D && !D->hasAttr()) @@ -893,8 +887,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName, // This is the first use or definition of a mangled name. If there is a // deferred decl with this name, remember that we need to emit it at the end // of the file. - llvm::DenseMap::iterator DDI = - DeferredDecls.find(MangledName); + llvm::StringMap::iterator DDI = DeferredDecls.find(MangledName); if (DDI != DeferredDecls.end()) { // Move the potentially referenced deferred decl to the DeferredDeclsToEmit // list, and remove it from DeferredDecls (since we don't need it anymore). @@ -905,9 +898,8 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName, llvm::GlobalVariable *GV = new llvm::GlobalVariable(getModule(), Ty->getElementType(), false, llvm::GlobalValue::ExternalLinkage, - 0, "", 0, + 0, MangledName, 0, false, Ty->getAddressSpace()); - GV->setName(MangledName); // Handle things which are present even on external declarations. if (D) { @@ -926,7 +918,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName, GV->setThreadLocal(D->isThreadSpecified()); } - return Entry = GV; + return GV; } @@ -943,16 +935,17 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, const llvm::PointerType *PTy = llvm::PointerType::get(Ty, ASTTy.getAddressSpace()); - return GetOrCreateLLVMGlobal(getMangledName(D), PTy, D); + + MangleBuffer MangledName; + getMangledName(MangledName, D); + return GetOrCreateLLVMGlobal(MangledName, PTy, D); } /// CreateRuntimeVariable - Create a new runtime global variable with the /// specified type and name. llvm::Constant * CodeGenModule::CreateRuntimeVariable(const llvm::Type *Ty, - const char *Name) { - // Convert Name to be a uniqued string from the IdentifierInfo table. - Name = getContext().Idents.get(Name).getNameStart(); + llvm::StringRef Name) { return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0); } @@ -963,8 +956,9 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) { // If we have not seen a reference to this variable yet, place it // into the deferred declarations table to be emitted if needed // later. - const char *MangledName = getMangledName(D); - if (GlobalDeclMap.count(MangledName) == 0) { + MangleBuffer MangledName; + getMangledName(MangledName, D); + if (!GetGlobalValue(MangledName)) { DeferredDecls[MangledName] = D; return; } @@ -1133,12 +1127,11 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { GV->getType()->getElementType() != InitType || GV->getType()->getAddressSpace() != ASTTy.getAddressSpace()) { - // Remove the old entry from GlobalDeclMap so that we'll create a new one. - GlobalDeclMap.erase(getMangledName(D)); + // Move the old entry aside so that we'll create a new one. + Entry->setName(llvm::StringRef()); // Make a new global with the correct type, this is now guaranteed to work. GV = cast(GetAddrOfGlobalVar(D, InitType)); - GV->takeName(cast(Entry)); // Replace all uses of the old global with the new global llvm::Constant *NewPtrForOldDecl = @@ -1296,11 +1289,10 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { // // This happens if there is a prototype for a function // (e.g. "int f()") and then a definition of a different type - // (e.g. "int f(int x)"). Start by making a new function of the - // correct type, RAUW, then steal the name. - GlobalDeclMap.erase(getMangledName(D)); + // (e.g. "int f(int x)"). Move the old function aside so that it + // doesn't interfere with GetAddrOfFunction. + OldFn->setName(llvm::StringRef()); llvm::Function *NewFn = cast(GetAddrOfFunction(GD, Ty)); - NewFn->takeName(OldFn); // If this is an implementation of a function without a prototype, try to // replace any existing uses of the function (which may be calls) with uses @@ -1336,23 +1328,29 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { AddGlobalDtor(Fn, DA->getPriority()); } -void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) { +void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { + const ValueDecl *D = cast(GD.getDecl()); const AliasAttr *AA = D->getAttr(); assert(AA && "Not an alias?"); - const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType()); + MangleBuffer MangledName; + getMangledName(MangledName, GD); - // Unique the name through the identifier table. - const char *AliaseeName = - getContext().Idents.get(AA->getAliasee()).getNameStart(); + // If there is a definition in the module, then it wins over the alias. + // This is dubious, but allow it to be safe. Just ignore the alias. + llvm::GlobalValue *Entry = GetGlobalValue(MangledName); + if (Entry && !Entry->isDeclaration()) + return; + + const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType()); // Create a reference to the named value. This ensures that it is emitted // if a deferred decl. llvm::Constant *Aliasee; if (isa(DeclTy)) - Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, GlobalDecl()); + Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GlobalDecl()); else - Aliasee = GetOrCreateLLVMGlobal(AliaseeName, + Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), llvm::PointerType::getUnqual(DeclTy), 0); // Create the new alias itself, but don't set a name yet. @@ -1361,18 +1359,9 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) { llvm::Function::ExternalLinkage, "", Aliasee, &getModule()); - // See if there is already something with the alias' name in the module. - const char *MangledName = getMangledName(D); - llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName]; - - if (Entry && !Entry->isDeclaration()) { - // If there is a definition in the module, then it wins over the alias. - // This is dubious, but allow it to be safe. Just ignore the alias. - GA->eraseFromParent(); - return; - } - if (Entry) { + assert(Entry->isDeclaration()); + // If there is a declaration in the module, then we had an extern followed // by the alias, as in: // extern int test6(); @@ -1380,16 +1369,15 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) { // int test6() __attribute__((alias("test7"))); // // Remove it and replace uses of it with the alias. + GA->takeName(Entry); Entry->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GA, Entry->getType())); Entry->eraseFromParent(); + } else { + GA->setName(MangledName.getString()); } - // Now we know that there is no conflict, set the name. - Entry = GA; - GA->setName(MangledName); - // Set attributes which are particular to an alias; this is a // specialization of the attributes which may be set on a global // variable/function. @@ -1426,8 +1414,6 @@ llvm::Value *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD, const llvm::FunctionType *Ty = cast(getTypes().ConvertType(FD->getType())); - // Unique the name through the identifier table. - Name = getContext().Idents.get(Name).getNameStart(); return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl(FD)); } diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 9077adedd0..b93f3c634d 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -73,7 +73,7 @@ namespace CodeGen { class CodeGenFunction; class CGDebugInfo; class CGObjCRuntime; - + class MangleBuffer; /// CodeGenModule - This class organizes the cross-function state that is used /// while generating LLVM code. @@ -103,38 +103,16 @@ class CodeGenModule : public BlockModule { llvm::Function *MemMoveFn; llvm::Function *MemSetFn; - /// GlobalDeclMap - Mapping of decl names (represented as unique - /// character pointers from either the identifier table or the set - /// of mangled names) to global variables we have already - /// emitted. Note that the entries in this map are the actual - /// globals and therefore may not be of the same type as the decl, - /// they should be bitcasted on retrieval. Also note that the - /// globals are keyed on their source mangled name, not the global name - /// (which may change with attributes such as asm-labels). The key - /// to this map should be generated using getMangledName(). - /// - /// Note that this map always lines up exactly with the contents of the LLVM - /// IR symbol table, but this is quicker to query since it is doing uniqued - /// pointer lookups instead of full string lookups. - llvm::DenseMap GlobalDeclMap; - // WeakRefReferences - A set of references that have only been seen via // a weakref so far. This is used to remove the weak of the reference if we ever // see a direct reference or a definition. llvm::SmallPtrSet WeakRefReferences; - /// \brief Contains the strings used for mangled names. - /// - /// FIXME: Eventually, this should map from the semantic/canonical - /// declaration for each global entity to its mangled name (if it - /// has one). - llvm::StringSet<> MangledNames; - /// DeferredDecls - This contains all the decls which have definitions but /// which are deferred for emission and therefore should only be output if /// they are actually used. If a decl is in this, then it is known to have - /// not been referenced yet. The key to this map is a uniqued mangled name. - llvm::DenseMap DeferredDecls; + /// not been referenced yet. + llvm::StringMap DeferredDecls; /// DeferredDeclsToEmit - This is a list of deferred decls which we have seen /// that *are* actually referenced. These get code generated when the module @@ -346,11 +324,11 @@ public: /// CreateRuntimeFunction - Create a new runtime function with the specified /// type and name. llvm::Constant *CreateRuntimeFunction(const llvm::FunctionType *Ty, - const char *Name); + llvm::StringRef Name); /// CreateRuntimeVariable - Create a new runtime global variable with the /// specified type and name. llvm::Constant *CreateRuntimeVariable(const llvm::Type *Ty, - const char *Name); + llvm::StringRef Name); void UpdateCompletedType(const TagDecl *TD) { // Make sure that this type is translated. @@ -422,13 +400,14 @@ public: AttributeListType &PAL, unsigned &CallingConv); - const char *getMangledName(const GlobalDecl &D); - - const char *getMangledName(const NamedDecl *ND); - const char *getMangledCXXCtorName(const CXXConstructorDecl *D, - CXXCtorType Type); - const char *getMangledCXXDtorName(const CXXDestructorDecl *D, - CXXDtorType Type); + void getMangledName(MangleBuffer &Buffer, GlobalDecl D); + void getMangledName(MangleBuffer &Buffer, const NamedDecl *ND); + void getMangledCXXCtorName(MangleBuffer &Buffer, + const CXXConstructorDecl *D, + CXXCtorType Type); + void getMangledCXXDtorName(MangleBuffer &Buffer, + const CXXDestructorDecl *D, + CXXDtorType Type); void EmitTentativeDefinition(const VarDecl *D); @@ -456,14 +435,12 @@ public: std::vector DeferredVtables; private: - /// UniqueMangledName - Unique a name by (if necessary) inserting it into the - /// MangledNames string map. - const char *UniqueMangledName(const char *NameStart, const char *NameEnd); + llvm::GlobalValue *GetGlobalValue(llvm::StringRef Ref); - llvm::Constant *GetOrCreateLLVMFunction(const char *MangledName, + llvm::Constant *GetOrCreateLLVMFunction(llvm::StringRef MangledName, const llvm::Type *Ty, GlobalDecl D); - llvm::Constant *GetOrCreateLLVMGlobal(const char *MangledName, + llvm::Constant *GetOrCreateLLVMGlobal(llvm::StringRef MangledName, const llvm::PointerType *PTy, const VarDecl *D); @@ -492,7 +469,7 @@ private: void EmitGlobalFunctionDefinition(GlobalDecl GD); void EmitGlobalVarDefinition(const VarDecl *D); - void EmitAliasDefinition(const ValueDecl *D); + void EmitAliasDefinition(GlobalDecl GD); void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D); // C++ related functions. diff --git a/lib/CodeGen/Mangle.h b/lib/CodeGen/Mangle.h index 97f94b69b4..62656b95da 100644 --- a/lib/CodeGen/Mangle.h +++ b/lib/CodeGen/Mangle.h @@ -21,10 +21,8 @@ #include "CGCXX.h" #include "clang/AST/Type.h" #include "llvm/ADT/DenseMap.h" - -namespace llvm { - template class SmallVectorImpl; -} +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallString.h" namespace clang { class ASTContext; @@ -37,6 +35,33 @@ namespace clang { namespace CodeGen { class CovariantThunkAdjustment; class ThunkAdjustment; + +/// MangleBuffer - a convenient class for storing a name which is +/// either the result of a mangling or is a constant string with +/// external memory ownership. +class MangleBuffer { +public: + void setString(llvm::StringRef Ref) { + String = Ref; + } + + llvm::SmallVectorImpl &getBuffer() { + return Buffer; + } + + llvm::StringRef getString() const { + if (!String.empty()) return String; + return Buffer.str(); + } + + operator llvm::StringRef() const { + return getString(); + } + +private: + llvm::StringRef String; + llvm::SmallString<256> Buffer; +}; /// MangleContext - Context for tracking state which persists across multiple /// calls to the C++ name mangler. diff --git a/test/CodeGenCXX/attr.cpp b/test/CodeGenCXX/attr.cpp index 4c781c62b2..d689a4fdf4 100644 --- a/test/CodeGenCXX/attr.cpp +++ b/test/CodeGenCXX/attr.cpp @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s +// CHECK: @test2 = alias i32 ()* @_Z5test1v + // CHECK: define i32 @_Z3foov() nounwind align 1024 int foo() __attribute__((aligned(1024))); int foo() { } @@ -18,3 +20,9 @@ void C::bar2() { } // CHECK: define void @_ZN1C4bar3Ev(%class.C* %this) nounwind align 1024 void C::bar3() { } + +// PR6635 +// CHECK: define i32 @_Z5test1v() +int test1() { return 10; } +// CHECK at top of file +extern "C" int test2() __attribute__((alias("_Z5test1v")));