void mangleCXXCtorType(CXXCtorType T);
void mangleCXXDtorType(CXXDtorType T);
+ void mangleTemplateArgs(const ExplicitTemplateArgumentList &TemplateArgs);
void mangleTemplateArgs(TemplateName Template,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs);
mangleMemberExpr(ME->getBase(), ME->isArrow(),
ME->getQualifier(), ME->getMemberName(),
Arity);
+ if (ME->hasExplicitTemplateArgs())
+ mangleTemplateArgs(ME->getExplicitTemplateArgs());
break;
}
mangleMemberExpr(ME->getBase(), ME->isArrow(),
ME->getQualifier(), ME->getMember(),
Arity);
+ if (ME->hasExplicitTemplateArgs())
+ mangleTemplateArgs(ME->getExplicitTemplateArgs());
break;
}
// expression.
const UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(E);
mangleUnresolvedName(ULE->getQualifier(), ULE->getName(), Arity);
+ if (ULE->hasExplicitTemplateArgs())
+ mangleTemplateArgs(ULE->getExplicitTemplateArgs());
break;
}
}
assert(QTy && "Qualifier was not type!");
- // ::= sr <type> <unqualified-name> # dependent name
+ // ::= sr <type> <unqualified-name> # dependent name
+ // ::= sr <type> <unqualified-name> <template-args> # dependent template-id
Out << "sr";
mangleType(QualType(QTy, 0));
mangleUnqualifiedName(0, DRE->getDeclName(), Arity);
+ if (DRE->hasExplicitTemplateArgs())
+ mangleTemplateArgs(DRE->getExplicitTemplateArgs());
break;
}
}
}
+void CXXNameMangler::mangleTemplateArgs(
+ const ExplicitTemplateArgumentList &TemplateArgs) {
+ // <template-args> ::= I <template-arg>+ E
+ Out << 'I';
+ for (unsigned I = 0, E = TemplateArgs.NumTemplateArgs; I != E; ++I)
+ mangleTemplateArg(0, TemplateArgs.getTemplateArgs()[I].getArgument());
+ Out << 'E';
+}
+
void CXXNameMangler::mangleTemplateArgs(TemplateName Template,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs) {
template <class T> A<sizeof(T::foo())> func(void);
- // CHECK: define i32 @_ZN6test174testEv()
+ // CHECK: define void @_ZN6test174testEv()
// CHECK: call {{.*}} @_ZN6test174funcINS_1BEEENS_1AIXszclsrT_3fooEEEEv()
- int test() {
- func<B>(); // { dg-error "sorry, unimplemented" }
+ void test() {
+ func<B>();
}
}
// CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_mlEEE
// CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_anEEE
}
+
+// rdar://problem/8332117
+namespace test19 {
+ struct A {
+ template <typename T> int f();
+ int operator+();
+ operator int();
+ template <typename T> int operator-();
+ };
+
+ template <int (A::*)()> struct S {};
+
+ template <typename T> void g (S<&T::template f<int> >) {}
+ template <typename T> void g (S<&T::operator+ >) {}
+ template <typename T> void g (S<&T::operator int>) {}
+ template <typename T> void g (S<&T::template operator- <double> >) {}
+
+ // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_1fIiEEEE(
+ template void g<A>(S<&A::f<int> >);
+ // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_plEEE(
+ template void g<A>(S<&A::operator+>);
+ // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_cviEEE(
+ template void g<A>(S<&A::operator int>);
+ // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_miIdEEEE(
+ template void g<A>(S<&A::operator-<double> >);
+}
+
+namespace test20 {
+ template <class T> T *f(const T&);
+ template <class T> T *f(T*);
+
+ // CHECK: define weak_odr void @_ZN6test205test0IiEEvDTcl1fIPT_ELi0EEE(
+ template <class T> void test0(decltype(f<T*>(0))) {}
+ template void test0<int>(decltype(f<int*>(0)));
+
+ // CHECK: define weak_odr void @_ZN6test205test1IiEEvDTcl1fIEcvT__EEE(
+ template <class T> void test1(decltype(f<>(T()))) {}
+ template void test1<int>(decltype(f<>(int())));
+}