diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-11-21 09:14:52 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-11-21 09:14:52 +0000 |
commit | f981bf84ad7745861bc9c971f46417527e1e5db5 (patch) | |
tree | 3fbe233cb30c77d0a3093b686ae3c34f2dedc6ea /lib/CodeGen/Mangle.cpp | |
parent | c02ab4c76d7f8e672cda266436d64dd23bd2ad26 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89555 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/Mangle.cpp')
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 80 |
1 files changed, 44 insertions, 36 deletions
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index a4b2fce7c1..566deda696 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/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<AsmLabelAttr>()) + 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<OverloadableAttr>() && !isa<CXXMethodDecl>(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<FunctionDecl>(D); + if (FD && (FD->hasAttr<OverloadableAttr>() || isa<CXXMethodDecl>(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<AsmLabelAttr>()) { // 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; } // <mangled-name> ::= _Z <encoding> // ::= <data name> // ::= <special-name> - - // FIXME: Actually use a visitor to decode these? - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) - return mangleFunctionDecl(FD); - - const VarDecl *VD = cast<VarDecl>(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<FunctionDecl>(D)) { + // If we get here, mangle the decl name! + Out << "_Z"; + mangleFunctionEncoding(FD); + } else { + const VarDecl *VD = cast<VarDecl>(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<char> &Res) { assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) && "Invalid mangleName() call, argument is not a variable or function!"); |