diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp | 749 |
1 files changed, 450 insertions, 299 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp b/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp index 156ad64..d07efae 100644 --- a/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp @@ -42,8 +42,8 @@ using namespace clang; namespace { -/// \brief Retrieve the declaration context that should be used when mangling -/// the given declaration. +/// 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 @@ -69,6 +69,14 @@ static const DeclContext *getEffectiveDeclContext(const Decl *D) { if (const CapturedDecl *CD = dyn_cast<CapturedDecl>(DC)) return getEffectiveDeclContext(CD); + if (const auto *VD = dyn_cast<VarDecl>(D)) + if (VD->isExternC()) + return VD->getASTContext().getTranslationUnitDecl(); + + if (const auto *FD = dyn_cast<FunctionDecl>(D)) + if (FD->isExternC()) + return FD->getASTContext().getTranslationUnitDecl(); + return DC; } @@ -156,12 +164,18 @@ public: void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override; void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &Out) override; + void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl, + raw_ostream &Out) override; + void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl, + raw_ostream &Out) override; void mangleItaniumThreadLocalInit(const VarDecl *D, raw_ostream &) override; void mangleItaniumThreadLocalWrapper(const VarDecl *D, raw_ostream &) override; void mangleStringLiteral(const StringLiteral *, raw_ostream &) override; + void mangleCXXVTableBitSet(const CXXRecordDecl *RD, raw_ostream &) override; + bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) { // Lambda closure types are already numbered. if (isLambda(ND)) @@ -196,7 +210,7 @@ public: /// @} }; -/// CXXNameMangler - Manage the mangling of a single name. +/// Manage the mangling of a single name. class CXXNameMangler { ItaniumMangleContextImpl &Context; raw_ostream &Out; @@ -207,7 +221,7 @@ class CXXNameMangler { const NamedDecl *Structor; unsigned StructorType; - /// SeqID - The next subsitution sequence number. + /// The next substitution sequence number. unsigned SeqID; class FunctionTypeDepthState { @@ -284,7 +298,7 @@ public: #endif raw_ostream &getStream() { return Out; } - void mangle(const NamedDecl *D, StringRef Prefix = "_Z"); + void mangle(const NamedDecl *D); void mangleCallOffset(int64_t NonVirtual, int64_t Virtual); void mangleNumber(const llvm::APSInt &I); void mangleNumber(int64_t Number); @@ -317,10 +331,8 @@ private: 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); @@ -350,6 +362,9 @@ private: void manglePrefix(QualType type); void mangleTemplatePrefix(const TemplateDecl *ND, bool NoFunction=false); void mangleTemplatePrefix(TemplateName Template); + bool mangleUnresolvedTypeOrSimpleId(QualType DestroyedType, + StringRef Prefix = ""); + void mangleOperatorName(DeclarationName Name, unsigned Arity); void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity); void mangleQualifiers(Qualifiers Quals); void mangleRefQualifier(RefQualifierKind RefQualifier); @@ -370,12 +385,14 @@ private: void mangleAArch64NeonVectorType(const VectorType *T); void mangleIntegerLiteral(QualType T, const llvm::APSInt &Value); + void mangleMemberExprBase(const Expr *base, bool isArrow); void mangleMemberExpr(const Expr *base, bool isArrow, NestedNameSpecifier *qualifier, NamedDecl *firstQualifierLookup, DeclarationName name, unsigned knownArity); void mangleCastExpression(const Expr *E, StringRef CastEncoding); + void mangleInitListElements(const InitListExpr *InitList); void mangleExpression(const Expr *E, unsigned Arity = UnknownArity); void mangleCXXCtorType(CXXCtorType T); void mangleCXXDtorType(CXXDtorType T); @@ -439,11 +456,11 @@ bool ItaniumMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) { return true; } -void CXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) { +void CXXNameMangler::mangle(const NamedDecl *D) { // <mangled-name> ::= _Z <encoding> // ::= <data name> // ::= <special-name> - Out << Prefix; + Out << "_Z"; if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) mangleFunctionEncoding(FD); else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) @@ -519,7 +536,7 @@ static const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC) { return DC; } -/// isStd - Return whether a given namespace is the 'std' namespace. +/// Return whether a given namespace is the 'std' namespace. static bool isStd(const NamespaceDecl *NS) { if (!IgnoreLinkageSpecDecls(getEffectiveParentContext(NS)) ->isTranslationUnit()) @@ -748,8 +765,7 @@ void CXXNameMangler::mangleCallOffset(int64_t NonVirtual, int64_t Virtual) { } void CXXNameMangler::manglePrefix(QualType type) { - if (const TemplateSpecializationType *TST = - type->getAs<TemplateSpecializationType>()) { + if (const auto *TST = type->getAs<TemplateSpecializationType>()) { if (!mangleSubstitution(QualType(TST, 0))) { mangleTemplatePrefix(TST->getTemplateName()); @@ -759,17 +775,19 @@ void CXXNameMangler::manglePrefix(QualType type) { 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); + } else if (const auto *DTST = + type->getAs<DependentTemplateSpecializationType>()) { + if (!mangleSubstitution(QualType(DTST, 0))) { + 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()); + // 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()); + addSubstitution(QualType(DTST, 0)); + } } else { // We use the QualType mangle type variant here because it handles // substitutions. @@ -779,12 +797,9 @@ void CXXNameMangler::manglePrefix(QualType 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 @@ -817,7 +832,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, case NestedNameSpecifier::Namespace: if (qualifier->getPrefix()) - mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup, + mangleUnresolvedPrefix(qualifier->getPrefix(), /*recursive*/ true); else Out << "sr"; @@ -825,7 +840,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, break; case NestedNameSpecifier::NamespaceAlias: if (qualifier->getPrefix()) - mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup, + mangleUnresolvedPrefix(qualifier->getPrefix(), /*recursive*/ true); else Out << "sr"; @@ -842,193 +857,26 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, // - a template template parameter with arguments // In all of these cases, we should have no prefix. if (qualifier->getPrefix()) { - mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup, + mangleUnresolvedPrefix(qualifier->getPrefix(), /*recursive*/ true); } else { // Otherwise, all the cases want this. Out << "sr"; } - // Only certain other types are valid as prefixes; enumerate them. - switch (type->getTypeClass()) { - case Type::Builtin: - case Type::Complex: - case Type::Adjusted: - case Type::Decayed: - case Type::Pointer: - case Type::BlockPointer: - case Type::LValueReference: - case Type::RValueReference: - case Type::MemberPointer: - case Type::ConstantArray: - case Type::IncompleteArray: - case Type::VariableArray: - case Type::DependentSizedArray: - case Type::DependentSizedExtVector: - case Type::Vector: - case Type::ExtVector: - case Type::FunctionProto: - case Type::FunctionNoProto: - case Type::Enum: - case Type::Paren: - case Type::Elaborated: - case Type::Attributed: - case Type::Auto: - case Type::PackExpansion: - case Type::ObjCObject: - case Type::ObjCInterface: - case Type::ObjCObjectPointer: - case Type::Atomic: - llvm_unreachable("type is illegal as a nested name specifier"); - - case Type::SubstTemplateTypeParmPack: - // FIXME: not clear how to mangle this! - // template <class T...> class A { - // template <class U...> void foo(decltype(T::foo(U())) x...); - // }; - Out << "_SUBSTPACK_"; - break; - - // <unresolved-type> ::= <template-param> - // ::= <decltype> - // ::= <template-template-param> <template-args> - // (this last is not official yet) - case Type::TypeOfExpr: - case Type::TypeOf: - case Type::Decltype: - case Type::TemplateTypeParm: - case Type::UnaryTransform: - case Type::SubstTemplateTypeParm: - unresolvedType: - assert(!qualifier->getPrefix()); - - // We only get here recursively if we're followed by identifiers. - if (recursive) Out << 'N'; - - // This seems to do everything we want. It's not really - // sanctioned for a substituted template parameter, though. - mangleType(QualType(type, 0)); - - // We never want to print 'E' directly after an unresolved-type, - // so we return directly. + if (mangleUnresolvedTypeOrSimpleId(QualType(type, 0), recursive ? "N" : "")) return; - case Type::Typedef: - mangleSourceName(cast<TypedefType>(type)->getDecl()->getIdentifier()); - break; - - case Type::UnresolvedUsing: - mangleSourceName(cast<UnresolvedUsingType>(type)->getDecl() - ->getIdentifier()); - break; - - case Type::Record: - mangleSourceName(cast<RecordType>(type)->getDecl()->getIdentifier()); - break; - - case Type::TemplateSpecialization: { - const TemplateSpecializationType *tst - = cast<TemplateSpecializationType>(type); - TemplateName name = tst->getTemplateName(); - switch (name.getKind()) { - case TemplateName::Template: - case TemplateName::QualifiedTemplate: { - TemplateDecl *temp = name.getAsTemplateDecl(); - - // If the base is a template template parameter, this is an - // unresolved type. - assert(temp && "no template for template specialization type"); - if (isa<TemplateTemplateParmDecl>(temp)) goto unresolvedType; - - mangleSourceName(temp->getIdentifier()); - break; - } - - case TemplateName::OverloadedTemplate: - case TemplateName::DependentTemplate: - llvm_unreachable("invalid base for a template specialization type"); - - case TemplateName::SubstTemplateTemplateParm: { - SubstTemplateTemplateParmStorage *subst - = name.getAsSubstTemplateTemplateParm(); - mangleExistingSubstitution(subst->getReplacement()); - break; - } - - case TemplateName::SubstTemplateTemplateParmPack: { - // FIXME: not clear how to mangle this! - // template <template <class U> class T...> class A { - // template <class U...> void foo(decltype(T<U>::foo) x...); - // }; - Out << "_SUBSTPACK_"; - break; - } - } - - mangleTemplateArgs(tst->getArgs(), tst->getNumArgs()); - break; - } - - case Type::InjectedClassName: - mangleSourceName(cast<InjectedClassNameType>(type)->getDecl() - ->getIdentifier()); - break; - - case Type::DependentName: - mangleSourceName(cast<DependentNameType>(type)->getIdentifier()); - break; - - case Type::DependentTemplateSpecialization: { - const DependentTemplateSpecializationType *tst - = cast<DependentTemplateSpecializationType>(type); - mangleSourceName(tst->getIdentifier()); - mangleTemplateArgs(tst->getArgs(), tst->getNumArgs()); - break; - } - } break; } case NestedNameSpecifier::Identifier: // Member expressions can have these without prefixes. - if (qualifier->getPrefix()) { - mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup, + if (qualifier->getPrefix()) + mangleUnresolvedPrefix(qualifier->getPrefix(), /*recursive*/ true); - } else if (firstQualifierLookup) { - - // Try to make a proper qualifier out of the lookup result, and - // then just recurse on that. - NestedNameSpecifier *newQualifier; - if (TypeDecl *typeDecl = dyn_cast<TypeDecl>(firstQualifierLookup)) { - QualType type = getASTContext().getTypeDeclType(typeDecl); - - // Pretend we had a different nested name specifier. - newQualifier = NestedNameSpecifier::Create(getASTContext(), - /*prefix*/ nullptr, - /*template*/ false, - type.getTypePtr()); - } else if (NamespaceDecl *nspace = - dyn_cast<NamespaceDecl>(firstQualifierLookup)) { - newQualifier = NestedNameSpecifier::Create(getASTContext(), - /*prefix*/ nullptr, - nspace); - } else if (NamespaceAliasDecl *alias = - dyn_cast<NamespaceAliasDecl>(firstQualifierLookup)) { - newQualifier = NestedNameSpecifier::Create(getASTContext(), - /*prefix*/ nullptr, - alias); - } else { - // No sensible mangling to do here. - newQualifier = nullptr; - } - - if (newQualifier) - return mangleUnresolvedPrefix(newQualifier, /*lookup*/ nullptr, - recursive); - - } else { + else Out << "sr"; - } mangleSourceName(qualifier->getAsIdentifier()); break; @@ -1043,16 +891,41 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, /// Mangle an unresolved-name, which is generally used for names which /// weren't resolved to specific entities. void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *qualifier, - NamedDecl *firstQualifierLookup, DeclarationName name, unsigned knownArity) { - if (qualifier) mangleUnresolvedPrefix(qualifier, firstQualifierLookup); - mangleUnqualifiedName(nullptr, name, knownArity); + if (qualifier) mangleUnresolvedPrefix(qualifier); + switch (name.getNameKind()) { + // <base-unresolved-name> ::= <simple-id> + case DeclarationName::Identifier: + mangleSourceName(name.getAsIdentifierInfo()); + break; + // <base-unresolved-name> ::= dn <destructor-name> + case DeclarationName::CXXDestructorName: + Out << "dn"; + mangleUnresolvedTypeOrSimpleId(name.getCXXNameType()); + break; + // <base-unresolved-name> ::= on <operator-name> + case DeclarationName::CXXConversionFunctionName: + case DeclarationName::CXXLiteralOperatorName: + case DeclarationName::CXXOperatorName: + Out << "on"; + mangleOperatorName(name, knownArity); + break; + case DeclarationName::CXXConstructorName: + llvm_unreachable("Can't mangle a constructor name!"); + case DeclarationName::CXXUsingDirective: + llvm_unreachable("Can't mangle a using directive name!"); + case DeclarationName::ObjCMultiArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCZeroArgSelector: + llvm_unreachable("Can't mangle Objective-C selector names here!"); + } } void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name, unsigned KnownArity) { + unsigned Arity = KnownArity; // <unqualified-name> ::= <operator-name> // ::= <ctor-dtor-name> // ::= <source-name> @@ -1163,7 +1036,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, Str += llvm::utostr(AnonStructId); Out << Str.size(); - Out << Str.str(); + Out << Str; break; } @@ -1194,33 +1067,19 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, mangleCXXDtorType(Dtor_Complete); break; - case DeclarationName::CXXConversionFunctionName: - // <operator-name> ::= cv <type> # (cast) - Out << "cv"; - mangleType(Name.getCXXNameType()); - break; - - case DeclarationName::CXXOperatorName: { - unsigned Arity; - if (ND) { + case DeclarationName::CXXOperatorName: + if (ND && Arity == UnknownArity) { Arity = cast<FunctionDecl>(ND)->getNumParams(); - // If we have a C++ member function, we need to include the 'this' pointer. - // FIXME: This does not make sense for operators that are static, but their - // names stay the same regardless of the arity (operator new for instance). - if (isa<CXXMethodDecl>(ND)) - Arity++; - } else - Arity = KnownArity; - - mangleOperatorName(Name.getCXXOverloadedOperator(), Arity); - break; - } - + // If we have a member function, we need to include the 'this' pointer. + if (const auto *MD = dyn_cast<CXXMethodDecl>(ND)) + if (!MD->isStatic()) + Arity++; + } + // FALLTHROUGH + case DeclarationName::CXXConversionFunctionName: case DeclarationName::CXXLiteralOperatorName: - // FIXME: This mangling is not yet official. - Out << "li"; - mangleSourceName(Name.getCXXLiteralIdentifier()); + mangleOperatorName(Name, Arity); break; case DeclarationName::CXXUsingDirective: @@ -1529,7 +1388,8 @@ void CXXNameMangler::mangleTemplatePrefix(TemplateName Template) { DependentTemplateName *Dependent = Template.getAsDependentTemplateName(); assert(Dependent && "Unknown template name kind?"); - manglePrefix(Dependent->getQualifier()); + if (NestedNameSpecifier *Qualifier = Dependent->getQualifier()) + manglePrefix(Qualifier); mangleUnscopedTemplateName(Template); } @@ -1591,7 +1451,7 @@ void CXXNameMangler::mangleType(TemplateName TN) { // <class-enum-type> ::= <name> // <name> ::= <nested-name> - mangleUnresolvedPrefix(Dependent->getQualifier(), nullptr); + mangleUnresolvedPrefix(Dependent->getQualifier()); mangleSourceName(Dependent->getIdentifier()); break; } @@ -1620,6 +1480,181 @@ void CXXNameMangler::mangleType(TemplateName TN) { addSubstitution(TN); } +bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty, + StringRef Prefix) { + // Only certain other types are valid as prefixes; enumerate them. + switch (Ty->getTypeClass()) { + case Type::Builtin: + case Type::Complex: + case Type::Adjusted: + case Type::Decayed: + case Type::Pointer: + case Type::BlockPointer: + case Type::LValueReference: + case Type::RValueReference: + case Type::MemberPointer: + case Type::ConstantArray: + case Type::IncompleteArray: + case Type::VariableArray: + case Type::DependentSizedArray: + case Type::DependentSizedExtVector: + case Type::Vector: + case Type::ExtVector: + case Type::FunctionProto: + case Type::FunctionNoProto: + case Type::Paren: + case Type::Attributed: + case Type::Auto: + case Type::PackExpansion: + case Type::ObjCObject: + case Type::ObjCInterface: + case Type::ObjCObjectPointer: + case Type::Atomic: + llvm_unreachable("type is illegal as a nested name specifier"); + + case Type::SubstTemplateTypeParmPack: + // FIXME: not clear how to mangle this! + // template <class T...> class A { + // template <class U...> void foo(decltype(T::foo(U())) x...); + // }; + Out << "_SUBSTPACK_"; + break; + + // <unresolved-type> ::= <template-param> + // ::= <decltype> + // ::= <template-template-param> <template-args> + // (this last is not official yet) + case Type::TypeOfExpr: + case Type::TypeOf: + case Type::Decltype: + case Type::TemplateTypeParm: + case Type::UnaryTransform: + case Type::SubstTemplateTypeParm: + unresolvedType: + // Some callers want a prefix before the mangled type. + Out << Prefix; + + // This seems to do everything we want. It's not really + // sanctioned for a substituted template parameter, though. + mangleType(Ty); + + // We never want to print 'E' directly after an unresolved-type, + // so we return directly. + return true; + + case Type::Typedef: + mangleSourceName(cast<TypedefType>(Ty)->getDecl()->getIdentifier()); + break; + + case Type::UnresolvedUsing: + mangleSourceName( + cast<UnresolvedUsingType>(Ty)->getDecl()->getIdentifier()); + break; + + case Type::Enum: + case Type::Record: + mangleSourceName(cast<TagType>(Ty)->getDecl()->getIdentifier()); + break; + + case Type::TemplateSpecialization: { + const TemplateSpecializationType *TST = + cast<TemplateSpecializationType>(Ty); + TemplateName TN = TST->getTemplateName(); + switch (TN.getKind()) { + case TemplateName::Template: + case TemplateName::QualifiedTemplate: { + TemplateDecl *TD = TN.getAsTemplateDecl(); + + // If the base is a template template parameter, this is an + // unresolved type. + assert(TD && "no template for template specialization type"); + if (isa<TemplateTemplateParmDecl>(TD)) + goto unresolvedType; + + mangleSourceName(TD->getIdentifier()); + break; + } + + case TemplateName::OverloadedTemplate: + case TemplateName::DependentTemplate: + llvm_unreachable("invalid base for a template specialization type"); + + case TemplateName::SubstTemplateTemplateParm: { + SubstTemplateTemplateParmStorage *subst = + TN.getAsSubstTemplateTemplateParm(); + mangleExistingSubstitution(subst->getReplacement()); + break; + } + + case TemplateName::SubstTemplateTemplateParmPack: { + // FIXME: not clear how to mangle this! + // template <template <class U> class T...> class A { + // template <class U...> void foo(decltype(T<U>::foo) x...); + // }; + Out << "_SUBSTPACK_"; + break; + } + } + + mangleTemplateArgs(TST->getArgs(), TST->getNumArgs()); + break; + } + + case Type::InjectedClassName: + mangleSourceName( + cast<InjectedClassNameType>(Ty)->getDecl()->getIdentifier()); + break; + + case Type::DependentName: + mangleSourceName(cast<DependentNameType>(Ty)->getIdentifier()); + break; + + case Type::DependentTemplateSpecialization: { + const DependentTemplateSpecializationType *DTST = + cast<DependentTemplateSpecializationType>(Ty); + mangleSourceName(DTST->getIdentifier()); + mangleTemplateArgs(DTST->getArgs(), DTST->getNumArgs()); + break; + } + + case Type::Elaborated: + return mangleUnresolvedTypeOrSimpleId( + cast<ElaboratedType>(Ty)->getNamedType(), Prefix); + } + + return false; +} + +void CXXNameMangler::mangleOperatorName(DeclarationName Name, unsigned Arity) { + switch (Name.getNameKind()) { + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXUsingDirective: + case DeclarationName::Identifier: + case DeclarationName::ObjCMultiArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCZeroArgSelector: + llvm_unreachable("Not an operator name"); + + case DeclarationName::CXXConversionFunctionName: + // <operator-name> ::= cv <type> # (cast) + Out << "cv"; + mangleType(Name.getCXXNameType()); + break; + + case DeclarationName::CXXLiteralOperatorName: + Out << "li"; + mangleSourceName(Name.getCXXLiteralIdentifier()); + return; + + case DeclarationName::CXXOperatorName: + mangleOperatorName(Name.getCXXOverloadedOperator(), Arity); + break; + } +} + + + void CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) { switch (OO) { @@ -2276,6 +2311,7 @@ void CXXNameMangler::mangleAArch64NeonVectorType(const VectorType *T) { EltName = "Poly16"; break; case BuiltinType::ULong: + case BuiltinType::ULongLong: EltName = "Poly64"; break; default: @@ -2519,6 +2555,29 @@ void CXXNameMangler::mangleIntegerLiteral(QualType T, } +void CXXNameMangler::mangleMemberExprBase(const Expr *Base, bool IsArrow) { + // Ignore member expressions involving anonymous unions. + while (const auto *RT = Base->getType()->getAs<RecordType>()) { + if (!RT->getDecl()->isAnonymousStructOrUnion()) + break; + const auto *ME = dyn_cast<MemberExpr>(Base); + if (!ME) + break; + Base = ME->getBase(); + IsArrow = ME->isArrow(); + } + + if (Base->isImplicitCXXThis()) { + // Note: GCC mangles member expressions to the implicit 'this' as + // *this., whereas we represent them as this->. The Itanium C++ ABI + // does not specify anything here, so we follow GCC. + Out << "dtdefpT"; + } else { + Out << (IsArrow ? "pt" : "dt"); + mangleExpression(Base); + } +} + /// Mangles a member expression. void CXXNameMangler::mangleMemberExpr(const Expr *base, bool isArrow, @@ -2528,30 +2587,9 @@ void CXXNameMangler::mangleMemberExpr(const Expr *base, unsigned arity) { // <expression> ::= dt <expression> <unresolved-name> // ::= pt <expression> <unresolved-name> - if (base) { - - // Ignore member expressions involving anonymous unions. - while (const auto *RT = base->getType()->getAs<RecordType>()) { - if (!RT->getDecl()->isAnonymousStructOrUnion()) - break; - const auto *ME = dyn_cast<MemberExpr>(base); - if (!ME) - break; - base = ME->getBase(); - isArrow = ME->isArrow(); - } - - if (base->isImplicitCXXThis()) { - // Note: GCC mangles member expressions to the implicit 'this' as - // *this., whereas we represent them as this->. The Itanium C++ ABI - // does not specify anything here, so we follow GCC. - Out << "dtdefpT"; - } else { - Out << (isArrow ? "pt" : "dt"); - mangleExpression(base); - } - } - mangleUnresolvedName(qualifier, firstQualifierLookup, member, arity); + if (base) + mangleMemberExprBase(base, isArrow); + mangleUnresolvedName(qualifier, member, arity); } /// Look at the callee of the given call expression and determine if @@ -2592,6 +2630,13 @@ void CXXNameMangler::mangleCastExpression(const Expr *E, StringRef CastEncoding) mangleExpression(ECE->getSubExpr()); } +void CXXNameMangler::mangleInitListElements(const InitListExpr *InitList) { + if (auto *Syntactic = InitList->getSyntacticForm()) + InitList = Syntactic; + for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i) + mangleExpression(InitList->getInit(i)); +} + void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { // <expression> ::= <unary operator-name> <expression> // ::= <binary operator-name> <expression> <expression> @@ -2631,7 +2676,6 @@ recurse: // These all can only appear in local or variable-initialization // contexts and so should never appear in a mangling. case Expr::AddrLabelExprClass: - case Expr::DesignatedInitExprClass: case Expr::ImplicitValueInitExprClass: case Expr::ParenListExprClass: case Expr::LambdaExprClass: @@ -2641,9 +2685,9 @@ recurse: // FIXME: invent manglings for all these. case Expr::BlockExprClass: - case Expr::CXXPseudoDestructorExprClass: case Expr::ChooseExprClass: case Expr::CompoundLiteralExprClass: + case Expr::DesignatedInitExprClass: case Expr::ExtVectorElementExprClass: case Expr::GenericSelectionExprClass: case Expr::ObjCEncodeExprClass: @@ -2713,9 +2757,7 @@ recurse: case Expr::InitListExprClass: { Out << "il"; - const InitListExpr *InitList = cast<InitListExpr>(E); - for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i) - mangleExpression(InitList->getInit(i)); + mangleInitListElements(cast<InitListExpr>(E)); Out << "E"; break; } @@ -2759,9 +2801,14 @@ recurse: Out << "cl"; } - mangleExpression(CE->getCallee(), CE->getNumArgs()); - for (unsigned I = 0, N = CE->getNumArgs(); I != N; ++I) - mangleExpression(CE->getArg(I)); + unsigned CallArity = CE->getNumArgs(); + for (const Expr *Arg : CE->arguments()) + if (isa<PackExpansionExpr>(Arg)) + CallArity = UnknownArity; + + mangleExpression(CE->getCallee(), CallArity); + for (const Expr *Arg : CE->arguments()) + mangleExpression(Arg); Out << 'E'; break; } @@ -2793,9 +2840,7 @@ recurse: } else if (New->getInitializationStyle() == CXXNewExpr::ListInit && isa<InitListExpr>(Init)) { // Only take InitListExprs apart for list-initialization. - const InitListExpr *InitList = cast<InitListExpr>(Init); - for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i) - mangleExpression(InitList->getInit(i)); + mangleInitListElements(cast<InitListExpr>(Init)); } else mangleExpression(Init); } @@ -2803,6 +2848,33 @@ recurse: break; } + case Expr::CXXPseudoDestructorExprClass: { + const auto *PDE = cast<CXXPseudoDestructorExpr>(E); + if (const Expr *Base = PDE->getBase()) + mangleMemberExprBase(Base, PDE->isArrow()); + NestedNameSpecifier *Qualifier = PDE->getQualifier(); + QualType ScopeType; + if (TypeSourceInfo *ScopeInfo = PDE->getScopeTypeInfo()) { + if (Qualifier) { + mangleUnresolvedPrefix(Qualifier, + /*Recursive=*/true); + mangleUnresolvedTypeOrSimpleId(ScopeInfo->getType()); + Out << 'E'; + } else { + Out << "sr"; + if (!mangleUnresolvedTypeOrSimpleId(ScopeInfo->getType())) + Out << 'E'; + } + } else if (Qualifier) { + mangleUnresolvedPrefix(Qualifier); + } + // <base-unresolved-name> ::= dn <destructor-name> + Out << "dn"; + QualType DestroyedType = PDE->getDestroyedType(); + mangleUnresolvedTypeOrSimpleId(DestroyedType); + break; + } + case Expr::MemberExprClass: { const MemberExpr *ME = cast<MemberExpr>(E); mangleMemberExpr(ME->getBase(), ME->isArrow(), @@ -2813,9 +2885,9 @@ recurse: case Expr::UnresolvedMemberExprClass: { const UnresolvedMemberExpr *ME = cast<UnresolvedMemberExpr>(E); - mangleMemberExpr(ME->getBase(), ME->isArrow(), - ME->getQualifier(), nullptr, ME->getMemberName(), - Arity); + mangleMemberExpr(ME->isImplicitAccess() ? nullptr : ME->getBase(), + ME->isArrow(), ME->getQualifier(), nullptr, + ME->getMemberName(), Arity); if (ME->hasExplicitTemplateArgs()) mangleTemplateArgs(ME->getExplicitTemplateArgs()); break; @@ -2824,8 +2896,9 @@ recurse: case Expr::CXXDependentScopeMemberExprClass: { const CXXDependentScopeMemberExpr *ME = cast<CXXDependentScopeMemberExpr>(E); - mangleMemberExpr(ME->getBase(), ME->isArrow(), - ME->getQualifier(), ME->getFirstQualifierFoundInScope(), + mangleMemberExpr(ME->isImplicitAccess() ? nullptr : ME->getBase(), + ME->isArrow(), ME->getQualifier(), + ME->getFirstQualifierFoundInScope(), ME->getMember(), Arity); if (ME->hasExplicitTemplateArgs()) mangleTemplateArgs(ME->getExplicitTemplateArgs()); @@ -2834,7 +2907,7 @@ recurse: case Expr::UnresolvedLookupExprClass: { const UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(E); - mangleUnresolvedName(ULE->getQualifier(), nullptr, ULE->getName(), Arity); + mangleUnresolvedName(ULE->getQualifier(), ULE->getName(), Arity); // All the <unresolved-name> productions end in a // base-unresolved-name, where <template-args> are just tacked @@ -2856,26 +2929,55 @@ recurse: break; } - case Expr::CXXTemporaryObjectExprClass: case Expr::CXXConstructExprClass: { - const CXXConstructExpr *CE = cast<CXXConstructExpr>(E); + const auto *CE = cast<CXXConstructExpr>(E); + if (!CE->isListInitialization() || CE->isStdInitListInitialization()) { + assert( + CE->getNumArgs() >= 1 && + (CE->getNumArgs() == 1 || isa<CXXDefaultArgExpr>(CE->getArg(1))) && + "implicit CXXConstructExpr must have one argument"); + return mangleExpression(cast<CXXConstructExpr>(E)->getArg(0)); + } + Out << "il"; + for (auto *E : CE->arguments()) + mangleExpression(E); + Out << "E"; + break; + } + + case Expr::CXXTemporaryObjectExprClass: { + const auto *CE = cast<CXXTemporaryObjectExpr>(E); unsigned N = CE->getNumArgs(); + bool List = CE->isListInitialization(); - if (CE->isListInitialization()) + if (List) Out << "tl"; else Out << "cv"; mangleType(CE->getType()); - if (N != 1) Out << '_'; - for (unsigned I = 0; I != N; ++I) mangleExpression(CE->getArg(I)); - if (N != 1) Out << 'E'; + if (!List && N != 1) + Out << '_'; + if (CE->isStdInitListInitialization()) { + // We implicitly created a std::initializer_list<T> for the first argument + // of a constructor of type U in an expression of the form U{a, b, c}. + // Strip all the semantic gunk off the initializer list. + auto *SILE = + cast<CXXStdInitializerListExpr>(CE->getArg(0)->IgnoreImplicit()); + auto *ILE = cast<InitListExpr>(SILE->getSubExpr()->IgnoreImplicit()); + mangleInitListElements(ILE); + } else { + for (auto *E : CE->arguments()) + mangleExpression(E); + } + if (List || N != 1) + Out << 'E'; break; } case Expr::CXXScalarValueInitExprClass: - Out <<"cv"; + Out << "cv"; mangleType(E->getType()); - Out <<"_E"; + Out << "_E"; break; case Expr::CXXNoexceptExprClass: @@ -3020,10 +3122,28 @@ recurse: // Fall through to mangle the cast itself. case Expr::CStyleCastExprClass: - case Expr::CXXFunctionalCastExprClass: mangleCastExpression(E, "cv"); break; + case Expr::CXXFunctionalCastExprClass: { + auto *Sub = cast<ExplicitCastExpr>(E)->getSubExpr()->IgnoreImplicit(); + // FIXME: Add isImplicit to CXXConstructExpr. + if (auto *CCE = dyn_cast<CXXConstructExpr>(Sub)) + if (CCE->getParenOrBraceRange().isInvalid()) + Sub = CCE->getArg(0)->IgnoreImplicit(); + if (auto *StdInitList = dyn_cast<CXXStdInitializerListExpr>(Sub)) + Sub = StdInitList->getSubExpr()->IgnoreImplicit(); + if (auto *IL = dyn_cast<InitListExpr>(Sub)) { + Out << "tl"; + mangleType(E->getType()); + mangleInitListElements(IL); + Out << "E"; + } else { + mangleCastExpression(E, "cv"); + } + break; + } + case Expr::CXXStaticCastExprClass: mangleCastExpression(E, "sc"); break; @@ -3058,7 +3178,7 @@ recurse: default: // <expr-primary> ::= L <mangled-name> E # external name Out << 'L'; - mangle(D, "_Z"); + mangle(D); Out << 'E'; break; @@ -3101,8 +3221,7 @@ recurse: case Expr::DependentScopeDeclRefExprClass: { const DependentScopeDeclRefExpr *DRE = cast<DependentScopeDeclRefExpr>(E); - mangleUnresolvedName(DRE->getQualifier(), nullptr, DRE->getDeclName(), - Arity); + mangleUnresolvedName(DRE->getQualifier(), DRE->getDeclName(), Arity); // All the <unresolved-name> productions end in a // base-unresolved-name, where <template-args> are just tacked @@ -3327,6 +3446,9 @@ void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) { case Ctor_Comdat: Out << "C5"; break; + case Ctor_DefaultClosure: + case Ctor_CopyingClosure: + llvm_unreachable("closure constructors don't exist for the Itanium ABI!"); } } @@ -3410,8 +3532,8 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A) { if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { const ValueDecl *D = DRE->getDecl(); if (isa<VarDecl>(D) || isa<FunctionDecl>(D)) { - Out << "L"; - mangle(D, "_Z"); + Out << 'L'; + mangle(D); Out << 'E'; break; } @@ -3440,13 +3562,7 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A) { Out << 'L'; // References to external entities use the mangled name; if the name would // not normally be manged then mangle it as unqualified. - // - // FIXME: The ABI specifies that external names here should have _Z, but - // gcc leaves this off. - if (compensateMangling) - mangle(D, "_Z"); - else - mangle(D, "Z"); + mangle(D); Out << 'E'; if (compensateMangling) @@ -3524,8 +3640,8 @@ bool CXXNameMangler::mangleSubstitution(const NamedDecl *ND) { return mangleSubstitution(reinterpret_cast<uintptr_t>(ND)); } -/// \brief Determine whether the given type has any qualifiers that are -/// relevant for substitutions. +/// Determine whether the given type has any qualifiers that are relevant for +/// substitutions. static bool hasMangledSubstitutionQualifiers(QualType T) { Qualifiers Qs = T.getQualifiers(); return Qs.getCVRQualifiers() || Qs.hasAddressSpace(); @@ -3571,8 +3687,8 @@ static bool isCharType(QualType T) { T->isSpecificBuiltinType(BuiltinType::Char_U); } -/// isCharSpecialization - Returns whether a given type is a template -/// specialization of a given name with a single argument of type char. +/// Returns whether a given type is a template specialization of a given name +/// with a single argument of type char. static bool isCharSpecialization(QualType T, const char *Name) { if (T.isNull()) return false; @@ -3722,8 +3838,8 @@ void CXXNameMangler::addSubstitution(uintptr_t Ptr) { // -/// \brief Mangles the name of the declaration D and emits that name to the -/// given output stream. +/// Mangles the name of the declaration D and emits that name to the given +/// output stream. /// /// If the declaration D requires a mangled name, this routine will emit that /// mangled name to \p os and return true. Otherwise, \p os will be unchanged @@ -3815,8 +3931,7 @@ void ItaniumMangleContextImpl::mangleCXXDtorThunk( Mangler.mangleFunctionEncoding(DD); } -/// mangleGuardVariable - Returns the mangled name for a guard variable -/// for the passed in VarDecl. +/// Returns the mangled name for a guard variable for the passed in VarDecl. void ItaniumMangleContextImpl::mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out) { // <special-name> ::= GV <object name> # Guard variable for one-time @@ -3845,6 +3960,26 @@ void ItaniumMangleContextImpl::mangleDynamicAtExitDestructor(const VarDecl *D, Mangler.getStream() << D->getName(); } +void ItaniumMangleContextImpl::mangleSEHFilterExpression( + const NamedDecl *EnclosingDecl, raw_ostream &Out) { + CXXNameMangler Mangler(*this, Out); + Mangler.getStream() << "__filt_"; + if (shouldMangleDeclName(EnclosingDecl)) + Mangler.mangle(EnclosingDecl); + else + Mangler.getStream() << EnclosingDecl->getName(); +} + +void ItaniumMangleContextImpl::mangleSEHFinallyBlock( + const NamedDecl *EnclosingDecl, raw_ostream &Out) { + CXXNameMangler Mangler(*this, Out); + Mangler.getStream() << "__fin_"; + if (shouldMangleDeclName(EnclosingDecl)) + Mangler.mangle(EnclosingDecl); + else + Mangler.getStream() << EnclosingDecl->getName(); +} + void ItaniumMangleContextImpl::mangleItaniumThreadLocalInit(const VarDecl *D, raw_ostream &Out) { // <special-name> ::= TH <object name> @@ -3923,6 +4058,22 @@ void ItaniumMangleContextImpl::mangleTypeName(QualType Ty, raw_ostream &Out) { mangleCXXRTTIName(Ty, Out); } +void ItaniumMangleContextImpl::mangleCXXVTableBitSet(const CXXRecordDecl *RD, + raw_ostream &Out) { + Linkage L = RD->getLinkageInternal(); + if (L == InternalLinkage || L == UniqueExternalLinkage) { + // This part of the identifier needs to be unique across all translation + // units in the linked program. The scheme fails if multiple translation + // units are compiled using the same relative source file path, or if + // multiple translation units are built from the same source file. + SourceManager &SM = getASTContext().getSourceManager(); + Out << "[" << SM.getFileEntryForID(SM.getMainFileID())->getName() << "]"; + } + + CXXNameMangler Mangler(*this, Out); + Mangler.mangleType(QualType(RD->getTypeForDecl(), 0)); +} + void ItaniumMangleContextImpl::mangleStringLiteral(const StringLiteral *, raw_ostream &) { llvm_unreachable("Can't mangle string literals"); } |