From e949e6cced1079dbb6eaa7364e6fd5c65864e4c9 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sat, 21 Nov 2009 09:14:52 +0000 Subject: [PATCH] Mangler: Lift shouldMangleDeclName predicate out of CXXNameMangler::mangle. - Sometimes we have to mangle things we wouldn't normally (e.g., because they appear in a template expression). - This also tidies up the predicate to be more obvious what is getting mangled. llvm-svn: 89555 --- clang/lib/CodeGen/CodeGenModule.cpp | 9 +--- clang/lib/CodeGen/Mangle.cpp | 80 ++++++++++++++++------------- clang/lib/CodeGen/Mangle.h | 4 +- 3 files changed, 49 insertions(+), 44 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 8ba3d3261899..5744489f2f53 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -160,18 +160,13 @@ const char *CodeGenModule::getMangledName(const GlobalDecl &GD) { /// the unmangled name. /// const char *CodeGenModule::getMangledName(const NamedDecl *ND) { - // In C, functions with no attributes never need to be mangled. Fastpath them. - if (!getLangOptions().CPlusPlus && !ND->hasAttrs()) { + if (!getMangleContext().shouldMangleDeclName(ND)) { assert(ND->getIdentifier() && "Attempt to mangle unnamed decl."); return ND->getNameAsCString(); } llvm::SmallString<256> Name; - if (!getMangleContext().mangleName(ND, Name)) { - assert(ND->getIdentifier() && "Attempt to mangle unnamed decl."); - return ND->getNameAsCString(); - } - + getMangleContext().mangleName(ND, Name); Name += '\0'; return UniqueMangledName(Name.begin(), Name.end()); } diff --git a/clang/lib/CodeGen/Mangle.cpp b/clang/lib/CodeGen/Mangle.cpp index a4b2fce7c196..566deda6961b 100644 --- a/clang/lib/CodeGen/Mangle.cpp +++ b/clang/lib/CodeGen/Mangle.cpp @@ -51,7 +51,7 @@ public: llvm::raw_svector_ostream &getStream() { return Out; } - bool mangle(const NamedDecl *D); + void mangle(const NamedDecl *D); void mangleCalloffset(int64_t nv, int64_t v); void mangleFunctionEncoding(const FunctionDecl *FD); void mangleName(const NamedDecl *ND); @@ -124,60 +124,68 @@ static bool isInCLinkageSpecification(const Decl *D) { return false; } -bool CXXNameMangler::mangleFunctionDecl(const FunctionDecl *FD) { +bool MangleContext::shouldMangleDeclName(const NamedDecl *D) { + // In C, functions with no attributes never need to be mangled. Fastpath them. + if (!getASTContext().getLangOptions().CPlusPlus && !D->hasAttrs()) + return false; + + // Any decl can be declared with __asm("foo") on it, and this takes precedence + // over all other naming in the .o file. + if (D->hasAttr()) + return true; + // Clang's "overloadable" attribute extension to C/C++ implies name mangling // (always) as does passing a C++ member function and a function // whose name is not a simple identifier. - if (!FD->hasAttr() && !isa(FD) && - FD->getDeclName().isIdentifier()) { - // C functions are not mangled, and "main" is never mangled. - if (!Context.getASTContext().getLangOptions().CPlusPlus || FD->isMain()) - return false; + const FunctionDecl *FD = dyn_cast(D); + if (FD && (FD->hasAttr() || isa(FD) || + !FD->getDeclName().isIdentifier())) + return true; - // No mangling in an "implicit extern C" header. - if (FD->getLocation().isValid() && - Context.getASTContext().getSourceManager(). - isInExternCSystemHeader(FD->getLocation())) - return false; + // Otherwise, no mangling is done outside C++ mode. + if (!getASTContext().getLangOptions().CPlusPlus) + return false; - // No name mangling in a C linkage specification. - if (isInCLinkageSpecification(FD)) - return false; - } + // No mangling in an "implicit extern C" header. + if (D->getLocation().isValid() && + getASTContext().getSourceManager(). + isInExternCSystemHeader(D->getLocation())) + return false; + + // C functions, "main", and variables at global scope are not + // mangled. + if ((FD && FD->isMain()) || + (!FD && D->getDeclContext()->isTranslationUnit()) || + isInCLinkageSpecification(D)) + return false; - // If we get here, mangle the decl name! - Out << "_Z"; - mangleFunctionEncoding(FD); return true; } -bool CXXNameMangler::mangle(const NamedDecl *D) { +void CXXNameMangler::mangle(const NamedDecl *D) { + assert(Context.shouldMangleDeclName(D) && "Invalid mangle call!"); + // Any decl can be declared with __asm("foo") on it, and this takes precedence // over all other naming in the .o file. if (const AsmLabelAttr *ALA = D->getAttr()) { // If we have an asm name, then we use it as the mangling. Out << '\01'; // LLVM IR Marker for __asm("foo") Out << ALA->getLabel(); - return true; + return; } // ::= _Z // ::= // ::= - - // FIXME: Actually use a visitor to decode these? - if (const FunctionDecl *FD = dyn_cast(D)) - return mangleFunctionDecl(FD); - - const VarDecl *VD = cast(D); - if (!Context.getASTContext().getLangOptions().CPlusPlus || - isInCLinkageSpecification(D) || - D->getDeclContext()->isTranslationUnit()) - return false; - - Out << "_Z"; - mangleName(VD); - return true; + if (const FunctionDecl *FD = dyn_cast(D)) { + // If we get here, mangle the decl name! + Out << "_Z"; + mangleFunctionEncoding(FD); + } else { + const VarDecl *VD = cast(D); + Out << "_Z"; + mangleName(VD); + } } void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { @@ -1293,7 +1301,7 @@ void CXXNameMangler::addSubstitution(uintptr_t Ptr) { /// and this routine will return false. In this case, the caller should just /// emit the identifier of the declaration (\c D->getIdentifier()) as its /// name. -bool MangleContext::mangleName(const NamedDecl *D, +void MangleContext::mangleName(const NamedDecl *D, llvm::SmallVectorImpl &Res) { assert((isa(D) || isa(D)) && "Invalid mangleName() call, argument is not a variable or function!"); diff --git a/clang/lib/CodeGen/Mangle.h b/clang/lib/CodeGen/Mangle.h index 0c237f810a4e..edbbff516192 100644 --- a/clang/lib/CodeGen/Mangle.h +++ b/clang/lib/CodeGen/Mangle.h @@ -58,7 +58,9 @@ public: /// @name Mangler Entry Points /// @{ - bool mangleName(const NamedDecl *D, llvm::SmallVectorImpl &); + bool shouldMangleDeclName(const NamedDecl *D); + + void mangleName(const NamedDecl *D, llvm::SmallVectorImpl &); void mangleThunk(const FunctionDecl *FD, int64_t n, int64_t vn, llvm::SmallVectorImpl &); void mangleCovariantThunk(const FunctionDecl *FD, int64_t nv_t, int64_t v_t,