forked from OSchip/llvm-project
Address Chris's comments regarding C++ name mangling.
llvm-svn: 64984
This commit is contained in:
parent
84e7c1e2ff
commit
5f361c9f1e
|
@ -106,7 +106,7 @@ CodeGenFunction::GenerateStaticBlockVarDecl(const VarDecl &D,
|
|||
|
||||
std::string ContextName;
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl))
|
||||
ContextName = CGM.getMangledName(FD)->getName();
|
||||
ContextName = CGM.getMangledName(FD);
|
||||
else if (isa<ObjCMethodDecl>(CurFuncDecl))
|
||||
ContextName = std::string(CurFn->getNameStart(),
|
||||
CurFn->getNameStart() + CurFn->getNameLen());
|
||||
|
@ -171,7 +171,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
|
|||
// A normal fixed sized variable becomes an alloca in the entry block.
|
||||
const llvm::Type *LTy = ConvertType(Ty);
|
||||
llvm::AllocaInst *Alloc =
|
||||
CreateTempAlloca(LTy, CGM.getMangledName(&D)->getName());
|
||||
CreateTempAlloca(LTy, CGM.getMangledName(&D));
|
||||
unsigned align = getContext().getTypeAlign(Ty);
|
||||
if (const AlignedAttr* AA = D.getAttr<AlignedAttr>())
|
||||
align = std::max(align, AA->getAlignment());
|
||||
|
|
|
@ -702,7 +702,7 @@ LValue CodeGenFunction::EmitPredefinedFunctionName(unsigned Type) {
|
|||
|
||||
std::string FunctionName;
|
||||
if(const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl)) {
|
||||
FunctionName = CGM.getMangledName(FD)->getName();
|
||||
FunctionName = CGM.getMangledName(FD);
|
||||
} else {
|
||||
// Just get the mangled name.
|
||||
FunctionName = CurFn->getName();
|
||||
|
|
|
@ -171,8 +171,7 @@ void CodeGenFunction::StartFunction(const Decl *D, QualType RetTy,
|
|||
if (CGDebugInfo *DI = getDebugInfo()) {
|
||||
DI->setLocation(StartLoc);
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
DI->EmitFunctionStart(CGM.getMangledName(FD)->getName(),
|
||||
RetTy, CurFn, Builder);
|
||||
DI->EmitFunctionStart(CGM.getMangledName(FD), RetTy, CurFn, Builder);
|
||||
} else {
|
||||
// Just use LLVM function name.
|
||||
DI->EmitFunctionStart(Fn->getName().c_str(),
|
||||
|
|
|
@ -170,13 +170,15 @@ static void setGlobalVisibility(llvm::GlobalValue *GV,
|
|||
/// FIXME: Performance here is going to be terribly until we start
|
||||
/// caching mangled names. However, we should fix the problem above
|
||||
/// first.
|
||||
IdentifierInfo *CodeGenModule::getMangledName(const NamedDecl *ND) const {
|
||||
std::string Name;
|
||||
llvm::raw_string_ostream Out(Name);
|
||||
const char *CodeGenModule::getMangledName(const NamedDecl *ND) {
|
||||
llvm::SmallString<256> Name;
|
||||
llvm::raw_svector_ostream Out(Name);
|
||||
if (!mangleName(ND, Context, Out))
|
||||
return ND->getIdentifier();
|
||||
return ND->getIdentifier()->getName();
|
||||
|
||||
return &Context.Idents.get(Out.str());
|
||||
Name += '\0';
|
||||
return MangledNames.GetOrCreateValue(Name.begin(), Name.end())
|
||||
.getKeyData();
|
||||
}
|
||||
|
||||
/// AddGlobalCtor - Add a function to the list that will be called before
|
||||
|
@ -379,7 +381,7 @@ void CodeGenModule::EmitAliases() {
|
|||
llvm::GlobalValue *GA =
|
||||
new llvm::GlobalAlias(aliasee->getType(),
|
||||
llvm::Function::ExternalLinkage,
|
||||
getMangledName(D)->getName(), aliasee,
|
||||
getMangledName(D), aliasee,
|
||||
&getModule());
|
||||
|
||||
llvm::GlobalValue *&Entry = GlobalDeclMap[getMangledName(D)];
|
||||
|
@ -582,7 +584,7 @@ void CodeGenModule::EmitGlobalDefinition(const ValueDecl *D) {
|
|||
llvm::GlobalVariable *GV =
|
||||
new llvm::GlobalVariable(Ty, false,
|
||||
llvm::GlobalValue::ExternalLinkage,
|
||||
0, getMangledName(D)->getName(), &getModule(),
|
||||
0, getMangledName(D), &getModule(),
|
||||
0, ASTTy.getAddressSpace());
|
||||
Entry = GV;
|
||||
|
||||
|
@ -630,7 +632,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
|
|||
if (!GV) {
|
||||
GV = new llvm::GlobalVariable(InitType, false,
|
||||
llvm::GlobalValue::ExternalLinkage,
|
||||
0, getMangledName(D)->getName(),
|
||||
0, getMangledName(D),
|
||||
&getModule(), 0, ASTTy.getAddressSpace());
|
||||
} else if (GV->getType() !=
|
||||
llvm::PointerType::get(InitType, ASTTy.getAddressSpace())) {
|
||||
|
@ -654,7 +656,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
|
|||
// Make a new global with the correct type
|
||||
GV = new llvm::GlobalVariable(InitType, false,
|
||||
llvm::GlobalValue::ExternalLinkage,
|
||||
0, getMangledName(D)->getName(),
|
||||
0, getMangledName(D),
|
||||
&getModule(), 0, ASTTy.getAddressSpace());
|
||||
// Steal the name of the old global
|
||||
GV->takeName(OldGV);
|
||||
|
@ -753,7 +755,7 @@ CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D) {
|
|||
const llvm::Type *Ty = getTypes().ConvertType(D->getType());
|
||||
llvm::Function *F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
|
||||
llvm::Function::ExternalLinkage,
|
||||
getMangledName(D)->getName(),
|
||||
getMangledName(D),
|
||||
&getModule());
|
||||
SetFunctionAttributes(D, F);
|
||||
return F;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "clang/AST/Attr.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
|
||||
#include "CGCall.h"
|
||||
|
||||
|
@ -81,14 +82,23 @@ class CodeGenModule {
|
|||
/// will name them and patch up conflicts when we release the module.
|
||||
std::vector< std::pair<llvm::Function*, std::string> > RuntimeFunctions;
|
||||
|
||||
/// GlobalDeclMap - Mapping of decl names 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 name, not the global name (which may change with attributes such as
|
||||
/// asm-labels). This key to this map should be generated using
|
||||
/// getMangledName().
|
||||
llvm::DenseMap<IdentifierInfo*, llvm::GlobalValue*> GlobalDeclMap;
|
||||
/// 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 name, not the global name
|
||||
/// (which may change with attributes such as asm-labels). This key
|
||||
/// to this map should be generated using getMangledName().
|
||||
llvm::DenseMap<const char*, llvm::GlobalValue*> GlobalDeclMap;
|
||||
|
||||
/// \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;
|
||||
|
||||
/// Aliases - List of aliases in module. These cannot be emitted until all the
|
||||
/// code has been seen, as they reference things by name instead of directly
|
||||
|
@ -285,7 +295,7 @@ public:
|
|||
const Decl *TargetDecl,
|
||||
AttributeListType &PAL);
|
||||
|
||||
IdentifierInfo *getMangledName(const NamedDecl *ND) const;
|
||||
const char *getMangledName(const NamedDecl *ND);
|
||||
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===--------------------- Mangle.cpp - Mangle C++ Names ------------------===//
|
||||
//===--- Mangle.cpp - Mangle C++ Names --------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -18,6 +18,7 @@
|
|||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace clang;
|
||||
|
@ -61,17 +62,28 @@ bool CXXNameMangler::mangle(const NamedDecl *D) {
|
|||
// FIXME: Actually use a visitor to decode these?
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
bool RequiresMangling = false;
|
||||
// Clang's "overloadable" attribute extension to C/C++
|
||||
if (FD->getAttr<OverloadableAttr>())
|
||||
// No mangled in an "implicit extern C" header.
|
||||
if (Context.getSourceManager().getFileCharacteristic(FD->getLocation())
|
||||
== SrcMgr::C_ExternCSystem)
|
||||
RequiresMangling = false;
|
||||
// Clang's "overloadable" attribute extension to C/C++ implies
|
||||
// name mangling (always).
|
||||
else if (FD->getAttr<OverloadableAttr>())
|
||||
RequiresMangling = true;
|
||||
else if (Context.getLangOptions().CPlusPlus) {
|
||||
// C++ requires name mangling, unless we're in a C linkage
|
||||
// specification.
|
||||
RequiresMangling = true;
|
||||
if (isa<LinkageSpecDecl>(FD->getDeclContext()) &&
|
||||
cast<LinkageSpecDecl>(FD->getDeclContext())->getLanguage()
|
||||
== LinkageSpecDecl::lang_c) {
|
||||
// Entities with C linkage are not mangled.
|
||||
RequiresMangling = false;
|
||||
}
|
||||
|
||||
for (const DeclContext *DC = FD->getDeclContext();
|
||||
!DC->isTranslationUnit(); DC = DC->getParent()) {
|
||||
if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) {
|
||||
// extern "C" functions don't use name mangling
|
||||
if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
|
||||
RequiresMangling = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (RequiresMangling) {
|
||||
|
@ -95,15 +107,7 @@ static bool isStdNamespace(const DeclContext *DC) {
|
|||
return false;
|
||||
|
||||
const NamespaceDecl *NS = cast<NamespaceDecl>(DC);
|
||||
const IdentifierInfo *Name = NS->getIdentifier();
|
||||
if (Name->getLength() != 3)
|
||||
return false;
|
||||
|
||||
const char *Str = Name->getName();
|
||||
if (Str[0] != 's' || Str[1] != 't' || Str[2] != 'd')
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return NS->getOriginalNamespace()->getIdentifier()->isStr("std");
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleName(const NamedDecl *ND) {
|
||||
|
@ -307,7 +311,7 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
|
|||
|
||||
case OO_None:
|
||||
case NUM_OVERLOADED_OPERATORS:
|
||||
assert(false && "Not an ovelroaded operator");
|
||||
assert(false && "Not an overloaded operator");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -516,7 +520,11 @@ namespace clang {
|
|||
bool mangleName(const NamedDecl *D, ASTContext &Context,
|
||||
llvm::raw_ostream &os) {
|
||||
CXXNameMangler Mangler(Context, os);
|
||||
return Mangler.mangle(D);
|
||||
if (!Mangler.mangle(D))
|
||||
return false;
|
||||
|
||||
os.flush();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===---------------------- Mangle.h - Mangle C++ Names -------------------===//
|
||||
//===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue