From fa551b8b9703c5877ac653344c3e01b2ef4de98b Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 26 Feb 2014 15:34:24 -0500 Subject: Output: Generate function template instantiations and specializations Teach the AddStartDecl and PrintMembersAttribute methods to queue function template instantiations and specializations for output using an AddFunctionTemplateDecl helper to share common implementation. Map the Clang SubstTemplateTypeParm type to its replacement type. --- src/Output.cxx | 32 ++++++++++++++++++++++++++++ test/CMakeLists.txt | 1 + test/expect/gccxml.Function-template-xml.txt | 13 +++++++++++ test/input/Function-template.cxx | 3 +++ 4 files changed, 49 insertions(+) create mode 100644 test/expect/gccxml.Function-template-xml.txt create mode 100644 test/input/Function-template.cxx diff --git a/src/Output.cxx b/src/Output.cxx index 8bcf98c..c42a881 100644 --- a/src/Output.cxx +++ b/src/Output.cxx @@ -151,6 +151,10 @@ class ASTVisitor: public ASTVisitorBase void AddClassTemplateDecl(clang::ClassTemplateDecl const* d, std::set* emitted = 0); + /** Add function template specializations and instantiations for output. */ + void AddFunctionTemplateDecl(clang::FunctionTemplateDecl const* d, + std::set* emitted = 0); + /** Add a starting declaration for output. */ void AddStartDecl(clang::Decl const* d); @@ -349,6 +353,10 @@ unsigned int ASTVisitor::AddDumpNode(clang::QualType t, bool complete) { case clang::Type::Record: return this->AddDumpNode(t->getAs()->getDecl(), complete); + case clang::Type::SubstTemplateTypeParm: + return this->AddDumpNode( + t->getAs()->getReplacementType(), + complete); case clang::Type::TemplateSpecialization: { clang::TemplateSpecializationType const* tst = t->getAs(); @@ -419,6 +427,21 @@ void ASTVisitor::AddClassTemplateDecl(clang::ClassTemplateDecl const* d, } //---------------------------------------------------------------------------- +void ASTVisitor::AddFunctionTemplateDecl(clang::FunctionTemplateDecl const* d, + std::set* emitted) +{ + // Queue all the instantiations of this function template. + for(clang::FunctionTemplateDecl::spec_iterator i = d->spec_begin(), + e = d->spec_end(); i != e; ++i) { + clang::FunctionDecl const* fd = *i; + unsigned int id = this->AddDumpNode(fd, true); + if(id && emitted) { + emitted->insert(id); + } + } +} + +//---------------------------------------------------------------------------- void ASTVisitor::AddStartDecl(clang::Decl const* d) { switch (d->getKind()) { @@ -426,6 +449,10 @@ void ASTVisitor::AddStartDecl(clang::Decl const* d) this->AddClassTemplateDecl( static_cast(d)); break; + case clang::Decl::FunctionTemplate: + this->AddFunctionTemplateDecl( + static_cast(d)); + break; default: this->AddDumpNode(d, true); break; @@ -704,6 +731,11 @@ void ASTVisitor::PrintMembersAttribute(clang::DeclContext const* dc) static_cast(d), &emitted); continue; } break; + case clang::Decl::FunctionTemplate: { + this->AddFunctionTemplateDecl( + static_cast(d), &emitted); + continue; + } break; default: break; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 815060f..50c8343 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -72,6 +72,7 @@ castxml_test_gccxml(Class-incomplete) castxml_test_gccxml(Class-template) castxml_test_gccxml(CvQualifiedType) castxml_test_gccxml(Function) +castxml_test_gccxml(Function-template) castxml_test_gccxml(Function-throw) castxml_test_gccxml(FundamentalType) castxml_test_gccxml(Method) diff --git a/test/expect/gccxml.Function-template-xml.txt b/test/expect/gccxml.Function-template-xml.txt new file mode 100644 index 0000000..e503865 --- /dev/null +++ b/test/expect/gccxml.Function-template-xml.txt @@ -0,0 +1,13 @@ +^<\?xml version="1.0"\?> +]*> + + + + + + + + + + +$ diff --git a/test/input/Function-template.cxx b/test/input/Function-template.cxx new file mode 100644 index 0000000..b501b82 --- /dev/null +++ b/test/input/Function-template.cxx @@ -0,0 +1,3 @@ +template T start(T) {} +template <> char start(char); // specialization +template int start(int); // instantiation -- cgit v0.12