r229809 - Itanium ABI: Properly qualify the destructor-name

David Majnemer david.majnemer at gmail.com
Wed Feb 18 21:53:41 PST 2015


Thanks, fixed in r229822.

On Wed, Feb 18, 2015 at 9:34 PM, Craig Topper <craig.topper at gmail.com>
wrote:

> I think this left behind a nullptr argument being passed to
> mangleUnresolvedPrefix here
>
>   case TemplateName::DependentTemplate: {
>     const DependentTemplateName *Dependent =
> TN.getAsDependentTemplateName();
>     assert(Dependent->isIdentifier());
>
>     // <class-enum-type> ::= <name>
>     // <name> ::= <nested-name>
>     mangleUnresolvedPrefix(Dependent->getQualifier(), nullptr);
>     mangleSourceName(Dependent->getIdentifier());
>     break;
>   }
>
> On Wed, Feb 18, 2015 at 6:16 PM, David Majnemer <david.majnemer at gmail.com>
> wrote:
>
>> Author: majnemer
>> Date: Wed Feb 18 20:16:16 2015
>> New Revision: 229809
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=229809&view=rev
>> Log:
>> Itanium ABI: Properly qualify the destructor-name
>>
>> We didn't have enough qualificaiton before the scope specifier and we
>> had too much qualification in the destructor name itself.
>>
>> Modified:
>>     cfe/trunk/lib/AST/ItaniumMangle.cpp
>>     cfe/trunk/test/CodeGenCXX/mangle.cpp
>>
>> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=229809&r1=229808&r2=229809&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
>> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Wed Feb 18 20:16:16 2015
>> @@ -327,10 +327,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);
>>
>> @@ -360,7 +358,8 @@ private:
>>    void manglePrefix(QualType type);
>>    void mangleTemplatePrefix(const TemplateDecl *ND, bool
>> NoFunction=false);
>>    void mangleTemplatePrefix(TemplateName Template);
>> -  void mangleDestructorName(QualType DestroyedType);
>> +  bool mangleUnresolvedTypeOrSimpleId(QualType DestroyedType,
>> +                                      StringRef Prefix = "");
>>    void mangleOperatorName(DeclarationName Name, unsigned Arity);
>>    void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
>>    void mangleQualifiers(Qualifiers Quals);
>> @@ -799,7 +798,6 @@ void CXXNameMangler::manglePrefix(QualTy
>>  /// \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
>> @@ -832,7 +830,7 @@ void CXXNameMangler::mangleUnresolvedPre
>>
>>    case NestedNameSpecifier::Namespace:
>>      if (qualifier->getPrefix())
>> -      mangleUnresolvedPrefix(qualifier->getPrefix(),
>> firstQualifierLookup,
>> +      mangleUnresolvedPrefix(qualifier->getPrefix(),
>>                               /*recursive*/ true);
>>      else
>>        Out << "sr";
>> @@ -840,7 +838,7 @@ void CXXNameMangler::mangleUnresolvedPre
>>      break;
>>    case NestedNameSpecifier::NamespaceAlias:
>>      if (qualifier->getPrefix())
>> -      mangleUnresolvedPrefix(qualifier->getPrefix(),
>> firstQualifierLookup,
>> +      mangleUnresolvedPrefix(qualifier->getPrefix(),
>>                               /*recursive*/ true);
>>      else
>>        Out << "sr";
>> @@ -857,193 +855,26 @@ void CXXNameMangler::mangleUnresolvedPre
>>      //   - 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;
>> @@ -1058,10 +889,9 @@ void CXXNameMangler::mangleUnresolvedPre
>>  /// 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);
>> +  if (qualifier) mangleUnresolvedPrefix(qualifier);
>>    switch (name.getNameKind()) {
>>      // <base-unresolved-name> ::= <simple-id>
>>      case DeclarationName::Identifier:
>> @@ -1070,7 +900,7 @@ void CXXNameMangler::mangleUnresolvedNam
>>      // <base-unresolved-name> ::= dn <destructor-name>
>>      case DeclarationName::CXXDestructorName:
>>        Out << "dn";
>> -      mangleDestructorName(name.getCXXNameType());
>> +      mangleUnresolvedTypeOrSimpleId(name.getCXXNameType());
>>        break;
>>      // <base-unresolved-name> ::= on <operator-name>
>>      case DeclarationName::CXXConversionFunctionName:
>> @@ -1648,29 +1478,149 @@ void CXXNameMangler::mangleType(Template
>>    addSubstitution(TN);
>>  }
>>
>> -void CXXNameMangler::mangleDestructorName(QualType DestroyedType) {
>> -  // <destructor-name> ::= <unresolved-type>
>> -  //                   ::= <simple-id>
>> -  if (const auto *TST =
>> DestroyedType->getAs<TemplateSpecializationType>()) {
>> +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();
>> -    const auto *TD = TN.getAsTemplateDecl();
>> -    if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TD)) {
>> -      // Proposed to cxx-abi-dev on 2015-02-17.
>> -      mangleTemplateParameter(TTP->getIndex());
>> -    } else {
>> -      mangleUnscopedName(TD->getTemplatedDecl());
>> +    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());
>> -  } else if (const auto *DTST =
>> -
>>  DestroyedType->getAs<DependentTemplateSpecializationType>()) {
>> -    const IdentifierInfo *II = DTST->getIdentifier();
>> -    mangleSourceName(II);
>> +    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());
>> -  } else {
>> -    // We use the QualType mangle type variant here because it handles
>> -    // substitutions.
>> -    mangleType(DestroyedType);
>> +    break;
>>    }
>> +
>> +  case Type::Elaborated:
>> +    return mangleUnresolvedTypeOrSimpleId(
>> +        cast<ElaboratedType>(Ty)->getNamedType(), Prefix);
>> +  }
>> +
>> +  return false;
>>  }
>>
>>  void CXXNameMangler::mangleOperatorName(DeclarationName Name, unsigned
>> Arity) {
>> @@ -2636,7 +2586,7 @@ void CXXNameMangler::mangleMemberExpr(co
>>    //              ::= pt <expression> <unresolved-name>
>>    if (base)
>>      mangleMemberExprBase(base, isArrow);
>> -  mangleUnresolvedName(qualifier, firstQualifierLookup, member, arity);
>> +  mangleUnresolvedName(qualifier, member, arity);
>>  }
>>
>>  /// Look at the callee of the given call expression and determine if
>> @@ -2894,12 +2844,26 @@ recurse:
>>      const auto *PDE = cast<CXXPseudoDestructorExpr>(E);
>>      if (const Expr *Base = PDE->getBase())
>>        mangleMemberExprBase(Base, PDE->isArrow());
>> -    if (NestedNameSpecifier *Qualifier = PDE->getQualifier())
>> -      mangleUnresolvedPrefix(Qualifier,
>> /*FirstQualifierLookup=*/nullptr);
>> +    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();
>> -    mangleDestructorName(DestroyedType);
>> +    mangleUnresolvedTypeOrSimpleId(DestroyedType);
>>      break;
>>    }
>>
>> @@ -2934,7 +2898,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
>> @@ -3248,8 +3212,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
>>
>> Modified: cfe/trunk/test/CodeGenCXX/mangle.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle.cpp?rev=229809&r1=229808&r2=229809&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/CodeGenCXX/mangle.cpp (original)
>> +++ cfe/trunk/test/CodeGenCXX/mangle.cpp Wed Feb 18 20:16:16 2015
>> @@ -1024,6 +1024,12 @@ namespace test51 {
>>    template void fun<S1<int> >();
>>    // CHECK-LABEL: @_ZN6test513funI2S1IiEEEDTcldtcvT__EdnS3_EEv
>>
>> +  enum E {};
>> +  template <typename T>
>> +  struct X {
>> +    struct Y {};
>> +  };
>> +
>>    template <typename T>
>>    decltype(S1<T>().~S1<T>()) fun1() {};
>>    template <typename U, typename T>
>> @@ -1036,6 +1042,10 @@ namespace test51 {
>>    decltype(S1<int>().~S1<T>()) fun5(){};
>>    template <template <typename T> class U>
>>    decltype(S1<int>().~U<int>()) fun6(){};
>> +  template <typename T>
>> +  decltype(E().E::~T()) fun7() {}
>> +  template <template <typename> class U>
>> +  decltype(X<int>::Y().U<int>::Y::~Y()) fun8() {}
>>    template void fun1<int>();
>>    // CHECK-LABEL: @_ZN6test514fun1IiEEDTcldtcv2S1IT_E_Edn2S1IS2_EEEv
>>    template void fun2<S1<int>, int>();
>> @@ -1045,6 +1055,10 @@ namespace test51 {
>>    template void fun4<int>();
>>    // CHECK-LABEL:
>> @_ZN6test514fun4IiEEDTcmcldtcv2S1IT_E_Edn2S1IS2_EEcldtcvS3__Edn2S1IS2_EEEv
>>    template void fun5<int>();
>> -  // CHECK-LABEL: @_ZN6test514fun6I2S1EEDTcldtcvS1_IiE_EdnT_IiEEEv
>> +  // CHECK-LABEL: @_ZN6test514fun5IiEEDTcldtcv2S1IiE_Edn2S1IT_EEEv
>>    template void fun6<S1>();
>> +  // CHECK-LABEL: @_ZN6test514fun6I2S1EEDTcldtcvS1_IiE_EdnT_IiEEEv
>> +  template void fun7<E>();
>> +  // CHECK-LABEL: @_ZN6test514fun7INS_1EEEEDTcldtcvS1__Esr1EEdnT_EEv
>> +  template void fun8<X>();
>>  }
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>
>
>
> --
> ~Craig
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150218/bde833d9/attachment.html>


More information about the cfe-commits mailing list