if (D->isFunctionTemplateSpecialization())
Out << "template<> ";
+ else if (!D->getDescribedFunctionTemplate()) {
+ for (unsigned I = 0, NumTemplateParams = D->getNumTemplateParameterLists();
+ I < NumTemplateParams; ++I)
+ printTemplateParameters(D->getTemplateParameterList(I));
+ }
CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
prettyPrintPragmas(D->getTemplatedDecl());
+ // Print any leading template parameter lists.
+ if (const FunctionDecl *FD = D->getTemplatedDecl()) {
+ for (unsigned I = 0, NumTemplateParams = FD->getNumTemplateParameterLists();
+ I < NumTemplateParams; ++I)
+ printTemplateParameters(FD->getTemplateParameterList(I));
+ }
VisitRedeclarableTemplateDecl(D);
// Never print "instantiations" for deduction guides (they don't really
// CHECK: void Wrapper::Inner::staticMember()
}
+
+template<int x, typename T>
+class TemplateRecord {
+ void function();
+ template<typename U> void functionTemplate(T, U);
+};
+
+template<int x, typename T>
+void TemplateRecord<x, T>::function() { }
+// CHECK: template <int x, typename T> void TemplateRecord<x, T>::function()
+
+template<int x, typename T>
+template<typename U>
+void TemplateRecord<x, T>::functionTemplate(T, U) { }
+// CHECK: template <int x, typename T> template <typename U> void TemplateRecord<x, T>::functionTemplate(T, U)
+
+template<>
+class TemplateRecord<0, int> {
+ void function();
+ template<typename U> void functionTemplate(int, U);
+};
+
+void TemplateRecord<0, int>::function() { }
+// CHECK: void TemplateRecord<0, int>::function()
+
+template<typename U>
+void TemplateRecord<0, int>::functionTemplate(int, U) { }
+// CHECK: template <typename U> void TemplateRecord<0, int>::functionTemplate(int, U)
+
+template<typename T>
+struct OuterTemplateRecord {
+ template<typename U>
+ struct Inner {
+ void function();
+ };
+};
+
+template<typename T>
+template<typename U>
+void OuterTemplateRecord<T>::Inner<U>::function() { }
+// CHECK: template <typename T> template <typename U> void OuterTemplateRecord<T>::Inner<U>::function()