diff options
author | Guy Benyei <guy.benyei@intel.com> | 2012-12-18 12:30:03 +0000 |
---|---|---|
committer | Guy Benyei <guy.benyei@intel.com> | 2012-12-18 12:30:03 +0000 |
commit | 736104a7619c53ef92553780273d7357a3cdde81 (patch) | |
tree | a9f11d9747d4f6523e19cb83ae3a8ca3124f77af /lib | |
parent | 15cc355526cdd898f5e528c38c3e385c45746e06 (diff) |
Add OpenCL images as clang builtin types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@170428 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 19 | ||||
-rw-r--r-- | lib/AST/ItaniumMangle.cpp | 7154 | ||||
-rw-r--r-- | lib/AST/MicrosoftMangle.cpp | 3443 | ||||
-rw-r--r-- | lib/AST/NSAPI.cpp | 834 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 6 | ||||
-rw-r--r-- | lib/AST/TypeLoc.cpp | 728 | ||||
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 5636 | ||||
-rw-r--r-- | lib/CodeGen/CGDebugInfo.h | 655 | ||||
-rw-r--r-- | lib/CodeGen/CGOpenCLRuntime.cpp | 87 | ||||
-rw-r--r-- | lib/CodeGen/CGOpenCLRuntime.h | 98 | ||||
-rw-r--r-- | lib/CodeGen/CGRTTI.cpp | 2028 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.cpp | 10 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 48 | ||||
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 8 | ||||
-rw-r--r-- | lib/Parse/ParseTentative.cpp | 3154 | ||||
-rw-r--r-- | lib/Sema/DeclSpec.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 24 | ||||
-rw-r--r-- | lib/Serialization/ASTCommon.cpp | 166 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 13990 |
20 files changed, 19180 insertions, 18926 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index f3fa13584d..b04b830c85 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -874,6 +874,15 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) { InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId); InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass); InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel); + + if (LangOpts.OpenCL) { + InitBuiltinType(OCLImage1dTy, BuiltinType::OCLImage1d); + InitBuiltinType(OCLImage1dArrayTy, BuiltinType::OCLImage1dArray); + InitBuiltinType(OCLImage1dBufferTy, BuiltinType::OCLImage1dBuffer); + InitBuiltinType(OCLImage2dTy, BuiltinType::OCLImage2d); + InitBuiltinType(OCLImage2dArrayTy, BuiltinType::OCLImage2dArray); + InitBuiltinType(OCLImage3dTy, BuiltinType::OCLImage3d); + } // Builtin type for __objc_yes and __objc_no ObjCBuiltinBoolTy = (Target.useSignedCharForObjCBool() ? @@ -1412,6 +1421,16 @@ ASTContext::getTypeInfoImpl(const Type *T) const { Width = Target->getPointerWidth(0); Align = Target->getPointerAlign(0); break; + case BuiltinType::OCLImage1d: + case BuiltinType::OCLImage1dArray: + case BuiltinType::OCLImage1dBuffer: + case BuiltinType::OCLImage2d: + case BuiltinType::OCLImage2dArray: + case BuiltinType::OCLImage3d: + // Currently these types are pointers to opaque types. + Width = Target->getPointerWidth(0); + Align = Target->getPointerAlign(0); + break; } break; case Type::ObjCObjectPointer: diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 566a3894cb..65907f909b 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -1,3574 +1,3580 @@ -//===--- ItaniumMangle.cpp - Itanium C++ Name Mangling ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Implements C++ name mangling according to the Itanium C++ ABI, -// which is used in GCC 3.2 and newer (and many compilers that are -// ABI-compatible with GCC): -// -// http://www.codesourcery.com/public/cxx-abi/abi.html -// -//===----------------------------------------------------------------------===// -#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" -#include "clang/AST/DeclTemplate.h" -#include "clang/AST/ExprCXX.h" -#include "clang/AST/ExprObjC.h" -#include "clang/AST/TypeLoc.h" -#include "clang/Basic/ABI.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/TargetInfo.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" - -#define MANGLE_CHECKER 0 - -#if MANGLE_CHECKER -#include <cxxabi.h> -#endif - -using namespace clang; - -namespace { - -/// \brief Retrieve the declaration context that should be used when mangling -/// the given declaration. -static const DeclContext *getEffectiveDeclContext(const Decl *D) { - // The ABI assumes that lambda closure types that occur within - // default arguments live in the context of the function. However, due to - // the way in which Clang parses and creates function declarations, this is - // not the case: the lambda closure type ends up living in the context - // where the function itself resides, because the function declaration itself - // had not yet been created. Fix the context here. - if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { - if (RD->isLambda()) - if (ParmVarDecl *ContextParam - = dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl())) - return ContextParam->getDeclContext(); - } - - return D->getDeclContext(); -} - -static const DeclContext *getEffectiveParentContext(const DeclContext *DC) { - return getEffectiveDeclContext(cast<Decl>(DC)); -} - -static const CXXRecordDecl *GetLocalClassDecl(const NamedDecl *ND) { - const DeclContext *DC = dyn_cast<DeclContext>(ND); - if (!DC) - DC = getEffectiveDeclContext(ND); - while (!DC->isNamespace() && !DC->isTranslationUnit()) { - const DeclContext *Parent = getEffectiveDeclContext(cast<Decl>(DC)); - if (isa<FunctionDecl>(Parent)) - return dyn_cast<CXXRecordDecl>(DC); - DC = Parent; - } - return 0; -} - -static const FunctionDecl *getStructor(const FunctionDecl *fn) { - if (const FunctionTemplateDecl *ftd = fn->getPrimaryTemplate()) - return ftd->getTemplatedDecl(); - - return fn; -} - -static const NamedDecl *getStructor(const NamedDecl *decl) { - const FunctionDecl *fn = dyn_cast_or_null<FunctionDecl>(decl); - return (fn ? getStructor(fn) : decl); -} - -static const unsigned UnknownArity = ~0U; - -class ItaniumMangleContext : public MangleContext { - llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds; - unsigned Discriminator; - llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier; - -public: - explicit ItaniumMangleContext(ASTContext &Context, - DiagnosticsEngine &Diags) - : MangleContext(Context, Diags) { } - - uint64_t getAnonymousStructId(const TagDecl *TD) { - std::pair<llvm::DenseMap<const TagDecl *, - uint64_t>::iterator, bool> Result = - AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size())); - return Result.first->second; - } - - void startNewFunction() { - MangleContext::startNewFunction(); - mangleInitDiscriminator(); - } - - /// @name Mangler Entry Points - /// @{ - - bool shouldMangleDeclName(const NamedDecl *D); - void mangleName(const NamedDecl *D, raw_ostream &); - void mangleThunk(const CXXMethodDecl *MD, - const ThunkInfo &Thunk, - raw_ostream &); - void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, - const ThisAdjustment &ThisAdjustment, - raw_ostream &); - void mangleReferenceTemporary(const VarDecl *D, - raw_ostream &); - void mangleCXXVTable(const CXXRecordDecl *RD, - raw_ostream &); - void mangleCXXVTT(const CXXRecordDecl *RD, - raw_ostream &); - void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, - const CXXRecordDecl *Type, - raw_ostream &); - void mangleCXXRTTI(QualType T, raw_ostream &); - void mangleCXXRTTIName(QualType T, raw_ostream &); - void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, - raw_ostream &); - void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, - raw_ostream &); - - void mangleItaniumGuardVariable(const VarDecl *D, raw_ostream &); - - void mangleInitDiscriminator() { - Discriminator = 0; - } - - bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) { - // Lambda closure types with external linkage (indicated by a - // non-zero lambda mangling number) have their own numbering scheme, so - // they do not need a discriminator. - if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND)) - if (RD->isLambda() && RD->getLambdaManglingNumber() > 0) - return false; - - unsigned &discriminator = Uniquifier[ND]; - if (!discriminator) - discriminator = ++Discriminator; - if (discriminator == 1) - return false; - disc = discriminator-2; - return true; - } - /// @} -}; - -/// CXXNameMangler - Manage the mangling of a single name. -class CXXNameMangler { - ItaniumMangleContext &Context; - raw_ostream &Out; - - /// The "structor" is the top-level declaration being mangled, if - /// that's not a template specialization; otherwise it's the pattern - /// for that specialization. - const NamedDecl *Structor; - unsigned StructorType; - - /// SeqID - The next subsitution sequence number. - unsigned SeqID; - - class FunctionTypeDepthState { - unsigned Bits; - - enum { InResultTypeMask = 1 }; - - public: - FunctionTypeDepthState() : Bits(0) {} - - /// The number of function types we're inside. - unsigned getDepth() const { - return Bits >> 1; - } - - /// True if we're in the return type of the innermost function type. - bool isInResultType() const { - return Bits & InResultTypeMask; - } - - FunctionTypeDepthState push() { - FunctionTypeDepthState tmp = *this; - Bits = (Bits & ~InResultTypeMask) + 2; - return tmp; - } - - void enterResultType() { - Bits |= InResultTypeMask; - } - - void leaveResultType() { - Bits &= ~InResultTypeMask; - } - - void pop(FunctionTypeDepthState saved) { - assert(getDepth() == saved.getDepth() + 1); - Bits = saved.Bits; - } - - } FunctionTypeDepth; - - llvm::DenseMap<uintptr_t, unsigned> Substitutions; - - ASTContext &getASTContext() const { return Context.getASTContext(); } - -public: - CXXNameMangler(ItaniumMangleContext &C, raw_ostream &Out_, - const NamedDecl *D = 0) - : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(0), - SeqID(0) { - // These can't be mangled without a ctor type or dtor type. - assert(!D || (!isa<CXXDestructorDecl>(D) && - !isa<CXXConstructorDecl>(D))); - } - CXXNameMangler(ItaniumMangleContext &C, raw_ostream &Out_, - const CXXConstructorDecl *D, CXXCtorType Type) - : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type), - SeqID(0) { } - CXXNameMangler(ItaniumMangleContext &C, raw_ostream &Out_, - const CXXDestructorDecl *D, CXXDtorType Type) - : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type), - SeqID(0) { } - -#if MANGLE_CHECKER - ~CXXNameMangler() { - if (Out.str()[0] == '\01') - return; - - int status = 0; - char *result = abi::__cxa_demangle(Out.str().str().c_str(), 0, 0, &status); - assert(status == 0 && "Could not demangle mangled name!"); - free(result); - } -#endif - raw_ostream &getStream() { return Out; } - - void mangle(const NamedDecl *D, StringRef Prefix = "_Z"); - void mangleCallOffset(int64_t NonVirtual, int64_t Virtual); - void mangleNumber(const llvm::APSInt &I); - void mangleNumber(int64_t Number); - void mangleFloat(const llvm::APFloat &F); - void mangleFunctionEncoding(const FunctionDecl *FD); - void mangleName(const NamedDecl *ND); - void mangleType(QualType T); - void mangleNameOrStandardSubstitution(const NamedDecl *ND); - -private: - bool mangleSubstitution(const NamedDecl *ND); - bool mangleSubstitution(QualType T); - bool mangleSubstitution(TemplateName Template); - bool mangleSubstitution(uintptr_t Ptr); - - void mangleExistingSubstitution(QualType type); - void mangleExistingSubstitution(TemplateName name); - - bool mangleStandardSubstitution(const NamedDecl *ND); - - void addSubstitution(const NamedDecl *ND) { - ND = cast<NamedDecl>(ND->getCanonicalDecl()); - - addSubstitution(reinterpret_cast<uintptr_t>(ND)); - } - void addSubstitution(QualType T); - void addSubstitution(TemplateName Template); - void addSubstitution(uintptr_t Ptr); - - void mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, - NamedDecl *firstQualifierLookup, - bool recursive = false); - void mangleUnresolvedName(NestedNameSpecifier *qualifier, - NamedDecl *firstQualifierLookup, - DeclarationName name, - unsigned KnownArity = UnknownArity); - - void mangleName(const TemplateDecl *TD, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs); - void mangleUnqualifiedName(const NamedDecl *ND) { - mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity); - } - void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name, - unsigned KnownArity); - void mangleUnscopedName(const NamedDecl *ND); - void mangleUnscopedTemplateName(const TemplateDecl *ND); - void mangleUnscopedTemplateName(TemplateName); - void mangleSourceName(const IdentifierInfo *II); - void mangleLocalName(const NamedDecl *ND); - void mangleLambda(const CXXRecordDecl *Lambda); - void mangleNestedName(const NamedDecl *ND, const DeclContext *DC, - bool NoFunction=false); - void mangleNestedName(const TemplateDecl *TD, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs); - void manglePrefix(NestedNameSpecifier *qualifier); - void manglePrefix(const DeclContext *DC, bool NoFunction=false); - void manglePrefix(QualType type); - void mangleTemplatePrefix(const TemplateDecl *ND); - void mangleTemplatePrefix(TemplateName Template); - void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity); - void mangleQualifiers(Qualifiers Quals); - void mangleRefQualifier(RefQualifierKind RefQualifier); - - void mangleObjCMethodName(const ObjCMethodDecl *MD); - - // Declare manglers for every type class. -#define ABSTRACT_TYPE(CLASS, PARENT) -#define NON_CANONICAL_TYPE(CLASS, PARENT) -#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T); -#include "clang/AST/TypeNodes.def" - - void mangleType(const TagType*); - void mangleType(TemplateName); - void mangleBareFunctionType(const FunctionType *T, - bool MangleReturnType); - void mangleNeonVectorType(const VectorType *T); - - void mangleIntegerLiteral(QualType T, const llvm::APSInt &Value); - void mangleMemberExpr(const Expr *base, bool isArrow, - NestedNameSpecifier *qualifier, - NamedDecl *firstQualifierLookup, - DeclarationName name, - unsigned knownArity); - void mangleExpression(const Expr *E, unsigned Arity = UnknownArity); - void mangleCXXCtorType(CXXCtorType T); - void mangleCXXDtorType(CXXDtorType T); - - void mangleTemplateArgs(const ASTTemplateArgumentListInfo &TemplateArgs); - void mangleTemplateArgs(const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs); - void mangleTemplateArgs(const TemplateArgumentList &AL); - void mangleTemplateArg(TemplateArgument A); - - void mangleTemplateParameter(unsigned Index); - - void mangleFunctionParam(const ParmVarDecl *parm); -}; - -} - -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()) - 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. - 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().getLangOpts().CPlusPlus) - return false; - - // Variables at global scope with non-internal linkage are not mangled - if (!FD) { - const DeclContext *DC = getEffectiveDeclContext(D); - // Check for extern variable declared locally. - if (DC->isFunctionOrMethod() && D->hasLinkage()) - while (!DC->isNamespace() && !DC->isTranslationUnit()) - DC = getEffectiveParentContext(DC); - if (DC->isTranslationUnit() && D->getLinkage() != InternalLinkage) - 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; -} - -void CXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) { - // 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. - - // Adding the prefix can cause problems when one file has a "foo" and - // another has a "\01foo". That is known to happen on ELF with the - // tricks normally used for producing aliases (PR9177). Fortunately the - // llvm mangler on ELF is a nop, so we can just avoid adding the \01 - // marker. We also avoid adding the marker if this is an alias for an - // LLVM intrinsic. - StringRef UserLabelPrefix = - getASTContext().getTargetInfo().getUserLabelPrefix(); - if (!UserLabelPrefix.empty() && !ALA->getLabel().startswith("llvm.")) - Out << '\01'; // LLVM IR Marker for __asm("foo") - - Out << ALA->getLabel(); - return; - } - - // <mangled-name> ::= _Z <encoding> - // ::= <data name> - // ::= <special-name> - Out << Prefix; - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) - mangleFunctionEncoding(FD); - else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) - mangleName(VD); - else - mangleName(cast<FieldDecl>(D)); -} - -void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { - // <encoding> ::= <function name> <bare-function-type> - mangleName(FD); - - // Don't mangle in the type if this isn't a decl we should typically mangle. - if (!Context.shouldMangleDeclName(FD)) - return; - - // Whether the mangling of a function type includes the return type depends on - // the context and the nature of the function. The rules for deciding whether - // the return type is included are: - // - // 1. Template functions (names or types) have return types encoded, with - // the exceptions listed below. - // 2. Function types not appearing as part of a function name mangling, - // e.g. parameters, pointer types, etc., have return type encoded, with the - // exceptions listed below. - // 3. Non-template function names do not have return types encoded. - // - // The exceptions mentioned in (1) and (2) above, for which the return type is - // never included, are - // 1. Constructors. - // 2. Destructors. - // 3. Conversion operator functions, e.g. operator int. - bool MangleReturnType = false; - if (FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate()) { - if (!(isa<CXXConstructorDecl>(FD) || isa<CXXDestructorDecl>(FD) || - isa<CXXConversionDecl>(FD))) - MangleReturnType = true; - - // Mangle the type of the primary template. - FD = PrimaryTemplate->getTemplatedDecl(); - } - - mangleBareFunctionType(FD->getType()->getAs<FunctionType>(), - MangleReturnType); -} - -static const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC) { - while (isa<LinkageSpecDecl>(DC)) { - DC = getEffectiveParentContext(DC); - } - - return DC; -} - -/// isStd - Return whether a given namespace is the 'std' namespace. -static bool isStd(const NamespaceDecl *NS) { - if (!IgnoreLinkageSpecDecls(getEffectiveParentContext(NS)) - ->isTranslationUnit()) - return false; - - const IdentifierInfo *II = NS->getOriginalNamespace()->getIdentifier(); - return II && II->isStr("std"); -} - -// isStdNamespace - Return whether a given decl context is a toplevel 'std' -// namespace. -static bool isStdNamespace(const DeclContext *DC) { - if (!DC->isNamespace()) - return false; - - return isStd(cast<NamespaceDecl>(DC)); -} - -static const TemplateDecl * -isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) { - // Check if we have a function template. - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)){ - if (const TemplateDecl *TD = FD->getPrimaryTemplate()) { - TemplateArgs = FD->getTemplateSpecializationArgs(); - return TD; - } - } - - // Check if we have a class template. - if (const ClassTemplateSpecializationDecl *Spec = - dyn_cast<ClassTemplateSpecializationDecl>(ND)) { - TemplateArgs = &Spec->getTemplateArgs(); - return Spec->getSpecializedTemplate(); - } - - return 0; -} - -static bool isLambda(const NamedDecl *ND) { - const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(ND); - if (!Record) - return false; - - return Record->isLambda(); -} - -void CXXNameMangler::mangleName(const NamedDecl *ND) { - // <name> ::= <nested-name> - // ::= <unscoped-name> - // ::= <unscoped-template-name> <template-args> - // ::= <local-name> - // - const DeclContext *DC = getEffectiveDeclContext(ND); - - // If this is an extern variable declared locally, the relevant DeclContext - // is that of the containing namespace, or the translation unit. - // FIXME: This is a hack; extern variables declared locally should have - // a proper semantic declaration context! - if (isa<FunctionDecl>(DC) && ND->hasLinkage() && !isLambda(ND)) - while (!DC->isNamespace() && !DC->isTranslationUnit()) - DC = getEffectiveParentContext(DC); - else if (GetLocalClassDecl(ND)) { - mangleLocalName(ND); - return; - } - - DC = IgnoreLinkageSpecDecls(DC); - - if (DC->isTranslationUnit() || isStdNamespace(DC)) { - // Check if we have a template. - const TemplateArgumentList *TemplateArgs = 0; - if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { - mangleUnscopedTemplateName(TD); - mangleTemplateArgs(*TemplateArgs); - return; - } - - mangleUnscopedName(ND); - return; - } - - if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)) { - mangleLocalName(ND); - return; - } - - mangleNestedName(ND, DC); -} -void CXXNameMangler::mangleName(const TemplateDecl *TD, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs) { - const DeclContext *DC = IgnoreLinkageSpecDecls(getEffectiveDeclContext(TD)); - - if (DC->isTranslationUnit() || isStdNamespace(DC)) { - mangleUnscopedTemplateName(TD); - mangleTemplateArgs(TemplateArgs, NumTemplateArgs); - } else { - mangleNestedName(TD, TemplateArgs, NumTemplateArgs); - } -} - -void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND) { - // <unscoped-name> ::= <unqualified-name> - // ::= St <unqualified-name> # ::std:: - - if (isStdNamespace(IgnoreLinkageSpecDecls(getEffectiveDeclContext(ND)))) - Out << "St"; - - mangleUnqualifiedName(ND); -} - -void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) { - // <unscoped-template-name> ::= <unscoped-name> - // ::= <substitution> - if (mangleSubstitution(ND)) - return; - - // <template-template-param> ::= <template-param> - if (const TemplateTemplateParmDecl *TTP - = dyn_cast<TemplateTemplateParmDecl>(ND)) { - mangleTemplateParameter(TTP->getIndex()); - return; - } - - mangleUnscopedName(ND->getTemplatedDecl()); - addSubstitution(ND); -} - -void CXXNameMangler::mangleUnscopedTemplateName(TemplateName Template) { - // <unscoped-template-name> ::= <unscoped-name> - // ::= <substitution> - if (TemplateDecl *TD = Template.getAsTemplateDecl()) - return mangleUnscopedTemplateName(TD); - - if (mangleSubstitution(Template)) - return; - - DependentTemplateName *Dependent = Template.getAsDependentTemplateName(); - assert(Dependent && "Not a dependent template name?"); - if (const IdentifierInfo *Id = Dependent->getIdentifier()) - mangleSourceName(Id); - else - mangleOperatorName(Dependent->getOperator(), UnknownArity); - - addSubstitution(Template); -} - -void CXXNameMangler::mangleFloat(const llvm::APFloat &f) { - // ABI: - // Floating-point literals are encoded using a fixed-length - // lowercase hexadecimal string corresponding to the internal - // representation (IEEE on Itanium), high-order bytes first, - // without leading zeroes. For example: "Lf bf800000 E" is -1.0f - // on Itanium. - // The 'without leading zeroes' thing seems to be an editorial - // mistake; see the discussion on cxx-abi-dev beginning on - // 2012-01-16. - - // Our requirements here are just barely weird enough to justify - // using a custom algorithm instead of post-processing APInt::toString(). - - llvm::APInt valueBits = f.bitcastToAPInt(); - unsigned numCharacters = (valueBits.getBitWidth() + 3) / 4; - assert(numCharacters != 0); - - // Allocate a buffer of the right number of characters. - llvm::SmallVector<char, 20> buffer; - buffer.set_size(numCharacters); - - // Fill the buffer left-to-right. - for (unsigned stringIndex = 0; stringIndex != numCharacters; ++stringIndex) { - // The bit-index of the next hex digit. - unsigned digitBitIndex = 4 * (numCharacters - stringIndex - 1); - - // Project out 4 bits starting at 'digitIndex'. - llvm::integerPart hexDigit - = valueBits.getRawData()[digitBitIndex / llvm::integerPartWidth]; - hexDigit >>= (digitBitIndex % llvm::integerPartWidth); - hexDigit &= 0xF; - - // Map that over to a lowercase hex digit. - static const char charForHex[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' - }; - buffer[stringIndex] = charForHex[hexDigit]; - } - - Out.write(buffer.data(), numCharacters); -} - -void CXXNameMangler::mangleNumber(const llvm::APSInt &Value) { - if (Value.isSigned() && Value.isNegative()) { - Out << 'n'; - Value.abs().print(Out, /*signed*/ false); - } else { - Value.print(Out, /*signed*/ false); - } -} - -void CXXNameMangler::mangleNumber(int64_t Number) { - // <number> ::= [n] <non-negative decimal integer> - if (Number < 0) { - Out << 'n'; - Number = -Number; - } - - Out << Number; -} - -void CXXNameMangler::mangleCallOffset(int64_t NonVirtual, int64_t Virtual) { - // <call-offset> ::= h <nv-offset> _ - // ::= v <v-offset> _ - // <nv-offset> ::= <offset number> # non-virtual base override - // <v-offset> ::= <offset number> _ <virtual offset number> - // # virtual base override, with vcall offset - if (!Virtual) { - Out << 'h'; - mangleNumber(NonVirtual); - Out << '_'; - return; - } - - Out << 'v'; - mangleNumber(NonVirtual); - Out << '_'; - mangleNumber(Virtual); - Out << '_'; -} - -void CXXNameMangler::manglePrefix(QualType type) { - if (const TemplateSpecializationType *TST = - type->getAs<TemplateSpecializationType>()) { - if (!mangleSubstitution(QualType(TST, 0))) { - mangleTemplatePrefix(TST->getTemplateName()); - - // FIXME: GCC does not appear to mangle the template arguments when - // the template in question is a dependent template name. Should we - // emulate that badness? - mangleTemplateArgs(TST->getArgs(), TST->getNumArgs()); - addSubstitution(QualType(TST, 0)); - } - } else if (const DependentTemplateSpecializationType *DTST - = type->getAs<DependentTemplateSpecializationType>()) { - TemplateName Template - = getASTContext().getDependentTemplateName(DTST->getQualifier(), - DTST->getIdentifier()); - mangleTemplatePrefix(Template); - - // FIXME: GCC does not appear to mangle the template arguments when - // the template in question is a dependent template name. Should we - // emulate that badness? - mangleTemplateArgs(DTST->getArgs(), DTST->getNumArgs()); - } else { - // We use the QualType mangle type variant here because it handles - // substitutions. - mangleType(type); - } -} - -/// Mangle everything prior to the base-unresolved-name in an unresolved-name. -/// -/// \param firstQualifierLookup - the entity found by unqualified lookup -/// for the first name in the qualifier, if this is for a member expression -/// \param recursive - true if this is being called recursively, -/// i.e. if there is more prefix "to the right". -void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, - NamedDecl *firstQualifierLookup, - bool recursive) { - - // x, ::x - // <unresolved-name> ::= [gs] <base-unresolved-name> - - // T::x / decltype(p)::x - // <unresolved-name> ::= sr <unresolved-type> <base-unresolved-name> - - // T::N::x /decltype(p)::N::x - // <unresolved-name> ::= srN <unresolved-type> <unresolved-qualifier-level>+ E - // <base-unresolved-name> - - // A::x, N::y, A<T>::z; "gs" means leading "::" - // <unresolved-name> ::= [gs] sr <unresolved-qualifier-level>+ E - // <base-unresolved-name> - - switch (qualifier->getKind()) { - case NestedNameSpecifier::Global: - Out << "gs"; - - // We want an 'sr' unless this is the entire NNS. - if (recursive) - Out << "sr"; - - // We never want an 'E' here. - return; - - case NestedNameSpecifier::Namespace: - if (qualifier->getPrefix()) - mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup, - /*recursive*/ true); - else - Out << "sr"; - mangleSourceName(qualifier->getAsNamespace()->getIdentifier()); - break; - case NestedNameSpecifier::NamespaceAlias: - if (qualifier->getPrefix()) - mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup, - |