diff options
Diffstat (limited to 'lib/AST/ItaniumMangle.cpp')
-rw-r--r-- | lib/AST/ItaniumMangle.cpp | 80 |
1 files changed, 49 insertions, 31 deletions
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 851944a..21c4993 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -16,6 +16,7 @@ //===----------------------------------------------------------------------===// #include "clang/AST/Mangle.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" @@ -27,8 +28,8 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #define MANGLE_CHECKER 0 @@ -355,17 +356,6 @@ private: } -static bool isInCLinkageSpecification(const Decl *D) { - D = D->getCanonicalDecl(); - for (const DeclContext *DC = getEffectiveDeclContext(D); - !DC->isTranslationUnit(); DC = getEffectiveParentContext(DC)) { - if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) - return Linkage->getLanguage() == LinkageSpecDecl::lang_c; - } - - return false; -} - bool ItaniumMangleContext::shouldMangleDeclName(const NamedDecl *D) { // In C, functions with no attributes never need to be mangled. Fastpath them. if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs()) @@ -376,20 +366,38 @@ bool ItaniumMangleContext::shouldMangleDeclName(const NamedDecl *D) { 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. const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); - if (FD && (FD->hasAttr<OverloadableAttr>() || isa<CXXMethodDecl>(FD) || - !FD->getDeclName().isIdentifier())) - return true; + if (FD) { + LanguageLinkage L = FD->getLanguageLinkage(); + // Overloadable functions need mangling. + if (FD->hasAttr<OverloadableAttr>()) + return true; + + // "main" is not mangled. + if (FD->isMain()) + return false; + + // C++ functions and those whose names are not a simple identifier need + // mangling. + if (!FD->getDeclName().isIdentifier() || L == CXXLanguageLinkage) + return true; + + // C functions are not mangled. + if (L == CLanguageLinkage) + return false; + } // Otherwise, no mangling is done outside C++ mode. if (!getASTContext().getLangOpts().CPlusPlus) return false; - // Variables at global scope with non-internal linkage are not mangled - if (!FD) { + const VarDecl *VD = dyn_cast<VarDecl>(D); + if (VD) { + // C variables are not mangled. + if (VD->isExternC()) + return false; + + // Variables at global scope with non-internal linkage are not mangled const DeclContext *DC = getEffectiveDeclContext(D); // Check for extern variable declared locally. if (DC->isFunctionOrMethod() && D->hasLinkage()) @@ -399,14 +407,6 @@ bool ItaniumMangleContext::shouldMangleDeclName(const NamedDecl *D) { return false; } - // Class members are always mangled. - if (getEffectiveDeclContext(D)->isRecord()) - return true; - - // C functions and "main" are not mangled. - if ((FD && FD->isMain()) || isInCLinkageSpecification(D)) - return false; - return true; } @@ -656,7 +656,7 @@ void CXXNameMangler::mangleFloat(const llvm::APFloat &f) { assert(numCharacters != 0); // Allocate a buffer of the right number of characters. - llvm::SmallVector<char, 20> buffer; + SmallVector<char, 20> buffer; buffer.set_size(numCharacters); // Fill the buffer left-to-right. @@ -1117,7 +1117,16 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, break; } } - + + int UnnamedMangle = Context.getASTContext().getUnnamedTagManglingNumber(TD); + if (UnnamedMangle != -1) { + Out << "Ut"; + if (UnnamedMangle != 0) + Out << llvm::utostr(UnnamedMangle - 1); + Out << '_'; + break; + } + // Get a unique id for the anonymous struct. uint64_t AnonStructId = Context.getAnonymousStructId(TD); @@ -1658,7 +1667,8 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) { // where <address-space-number> is a source name consisting of 'AS' // followed by the address space <number>. SmallString<64> ASString; - ASString = "AS" + llvm::utostr_32(Quals.getAddressSpace()); + ASString = "AS" + llvm::utostr_32( + Context.getASTContext().getTargetAddressSpace(Quals.getAddressSpace())); Out << 'U' << ASString.size() << ASString; } @@ -1870,6 +1880,14 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { case BuiltinType::ObjCId: Out << "11objc_object"; break; case BuiltinType::ObjCClass: Out << "10objc_class"; break; case BuiltinType::ObjCSel: Out << "13objc_selector"; break; + case BuiltinType::OCLImage1d: Out << "11ocl_image1d"; break; + case BuiltinType::OCLImage1dArray: Out << "16ocl_image1darray"; break; + case BuiltinType::OCLImage1dBuffer: Out << "17ocl_image1dbuffer"; break; + case BuiltinType::OCLImage2d: Out << "11ocl_image2d"; break; + case BuiltinType::OCLImage2dArray: Out << "16ocl_image2darray"; break; + case BuiltinType::OCLImage3d: Out << "11ocl_image3d"; break; + case BuiltinType::OCLSampler: Out << "11ocl_sampler"; break; + case BuiltinType::OCLEvent: Out << "9ocl_event"; break; } } |