diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index 24b4a2829930..b491854af9ec 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -15,6 +15,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" +#include "Mangle.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" @@ -23,67 +24,6 @@ using namespace clang; using namespace CodeGen; - -// FIXME: Name mangling should be moved to a separate class. - -static void mangleDeclContextInternal(const DeclContext *D, std::string &S) -{ - // FIXME: Should ObjcMethodDecl have the TranslationUnitDecl as its parent? - assert((!D->getParent() || isa(D->getParent())) && - "Only one level of decl context mangling is currently supported!"); - - if (const FunctionDecl* FD = dyn_cast(D)) { - S += llvm::utostr(FD->getIdentifier()->getLength()); - S += FD->getIdentifier()->getName(); - - if (FD->param_size() == 0) - S += 'v'; - else - assert(0 && "mangling of types not supported yet!"); - } else if (const ObjCMethodDecl* MD = dyn_cast(D)) { - - // FIXME: This should really use GetNameForMethod from CGObjCMac. - std::string Name; - Name += MD->isInstanceMethod() ? '-' : '+'; - Name += '['; - Name += MD->getClassInterface()->getNameAsString(); - Name += ' '; - Name += MD->getSelector().getAsString(); - Name += ']'; - S += llvm::utostr(Name.length()); - S += Name; - } else - assert(0 && "Unsupported decl type!"); -} - -static void mangleVarDeclInternal(const VarDecl &D, std::string &S) -{ - S += 'Z'; - mangleDeclContextInternal(D.getDeclContext(), S); - S += 'E'; - - S += llvm::utostr(D.getIdentifier()->getLength()); - S += D.getIdentifier()->getName(); -} - -static std::string mangleVarDecl(const VarDecl& D) -{ - std::string S = "_Z"; - - mangleVarDeclInternal(D, S); - - return S; -} - -static std::string mangleGuardVariable(const VarDecl& D) -{ - std::string S = "_ZGV"; - - mangleVarDeclInternal(D, S); - - return S; -} - void CodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV) { @@ -92,12 +32,16 @@ CodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D, assert(!getContext().getLangOptions().ThreadsafeStatics && "thread safe statics are currently not supported!"); + llvm::SmallString<256> GuardVName; + llvm::raw_svector_ostream GuardVOut(GuardVName); + mangleGuardVariable(&D, getContext(), GuardVOut); + // Create the guard variable. llvm::GlobalValue *GuardV = new llvm::GlobalVariable(llvm::Type::Int64Ty, false, GV->getLinkage(), llvm::Constant::getNullValue(llvm::Type::Int64Ty), - mangleGuardVariable(D), + GuardVName.c_str(), &CGM.getModule()); // Load the first byte of the guard variable. @@ -117,9 +61,6 @@ CodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D, EmitBlock(InitBlock); - // Patch the name. FIXME: We shouldn't need to do this. - GV->setName(mangleVarDecl(D)); - const Expr *Init = D.getInit(); if (!hasAggregateLLVMType(Init->getType())) { llvm::Value *V = EmitScalarExpr(Init); diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp index f608a22f0323..0f135270233a 100644 --- a/clang/test/CodeGenCXX/mangle.cpp +++ b/clang/test/CodeGenCXX/mangle.cpp @@ -42,5 +42,9 @@ extern "C" { namespace N { int unmangled_variable; } } // RUN: grep _ZN1N1iE %t | count 1 && namespace N { int i; } -// RUN: grep _ZZN1N1fEiiE1b %t | count 2 +// RUN: grep _ZZN1N1fEiiE1b %t | count 2 && namespace N { int f(int, int) { static int b; return b; } } + +// RUN: grep "_ZZN1N1gEvE1a =" %t | count 1 && +// RUN: grep "_ZGVZN1N1gEvE1a =" %t | count 1 +namespace N { int h(); void g() { static int a = h(); } }