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