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
This commit is contained in:
Daniel Dunbar 2009-11-21 09:14:52 +00:00
parent 161ade4455
commit e949e6cced
3 changed files with 49 additions and 44 deletions

View File

@ -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());
}

View File

@ -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())
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
if (FD && (FD->hasAttr<OverloadableAttr>() || isa<CXXMethodDecl>(FD) ||
!FD->getDeclName().isIdentifier()))
return true;
// Otherwise, no mangling is done outside C++ mode.
if (!getASTContext().getLangOptions().CPlusPlus)
return false;
// No mangling in an "implicit extern C" header.
if (FD->getLocation().isValid() &&
Context.getASTContext().getSourceManager().
isInExternCSystemHeader(FD->getLocation()))
if (D->getLocation().isValid() &&
getASTContext().getSourceManager().
isInExternCSystemHeader(D->getLocation()))
return false;
// No name mangling in a C linkage specification.
if (isInCLinkageSpecification(FD))
// 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);
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);
if (!Context.getASTContext().getLangOptions().CPlusPlus ||
isInCLinkageSpecification(D) ||
D->getDeclContext()->isTranslationUnit())
return false;
Out << "_Z";
mangleName(VD);
return true;
}
}
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!");

View File

@ -58,7 +58,9 @@ public:
/// @name Mangler Entry Points
/// @{
bool mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
bool shouldMangleDeclName(const NamedDecl *D);
void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
void mangleThunk(const FunctionDecl *FD, int64_t n, int64_t vn,
llvm::SmallVectorImpl<char> &);
void mangleCovariantThunk(const FunctionDecl *FD, int64_t nv_t, int64_t v_t,