diff options
Diffstat (limited to 'lib/AST/ItaniumMangle.cpp')
| -rw-r--r-- | lib/AST/ItaniumMangle.cpp | 749 | 
1 files changed, 450 insertions, 299 deletions
| diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 156ad646fa6d..d07efaee7bba 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/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");  } | 
