Joshua Naismith
2013-Sep-05 13:59 UTC
[LLVMdev] [ast-dump] Class template partial specializations missing from an implicit class template instantiation?
I was looking at the ClassTemplatePartialSpecializationDecl::getInstantiatedFromMember documentation, in the included example it says: "(..) the instantiation of Outer<float>::Inner<int*> will end up instantiating the partial specialization Outer<float>::Inner<U*> (...)". To understand the concept better, I dumped the AST for the following code: template<typename T> struct Outer { template<typename U> struct Inner {float f(){};}; template<typename U> struct Inner<U*> {int f(){};}; }; int main() { Outer<float>::Inner<int*> ii; ii.f(); Outer<float>::Inner<int> i2; i2.f(); } The tree looks as expected for the template: |-ClassTemplateDecl 0x38e1de0 <test-src/main.cpp:1:2, line:5:2> Outer | |-TemplateTypeParmDecl 0x38e1ca0 <line:1:11, col:20> typename T | |-CXXRecordDecl 0x38e1d50 <line:2:2, line:5:2> struct Outer definition | | |-CXXRecordDecl 0x390eab0 <line:2:2, col:9> struct Outer | | |-ClassTemplateDecl 0x390ec80 <line:3:4, col:51> Inner | | | |-TemplateTypeParmDecl 0x390eb40 <col:13, col:22> typename U | | | `-CXXRecordDecl 0x390ebf0 <col:25, col:51> struct Inner definition | | | |-CXXRecordDecl 0x390ef00 <col:25, col:32> struct Inner | | | `-CXXMethodDecl 0x390f010 <col:39, col:49> f 'float (void)' | | | `-CompoundStmt 0x390f668 <col:48, col:49> | | `-ClassTemplatePartialSpecializationDecl 0x390f280 <line:4:4, col:53> struct Inner definition | | |-TemplateArgument type 'type-parameter-1-0 *' | | |-TemplateTypeParmDecl 0x390f0b0 <col:13, col:22> typename U | | |-CXXRecordDecl 0x390f490 <col:25, col:32> struct Inner | | `-CXXMethodDecl 0x390f5a0 <col:43, col:51> f 'int (void)' | | `-CompoundStmt 0x390f680 <col:50, col:51> Both ClassTemplateDecl "Inner" and ClassTemplatePartialSpecializationDecl "Inner" are descendants of ClassTemplateDecl "Outer". However, for an instantiation, it looks like this: | `-ClassTemplateSpecializationDecl 0x390f7d0 <line:1:2, line:5:2> struct Outer definition | |-TemplateArgument type 'float' | |-CXXRecordDecl 0x3916990 prev 0x390f7d0 <line:2:2, col:9> struct Outer | `-ClassTemplateDecl 0x3916b30 <line:3:4, col:32> Inner | |-TemplateTypeParmDecl 0x3916a20 <col:13, col:22> typename U | |-CXXRecordDecl 0x3916aa0 <col:25, col:32> struct Inner | |-ClassTemplateSpecializationDecl 0x3917130 <line:4:4, col:53> struct Inner definition | | |-TemplateArgument type 'int *' | | |-CXXRecordDecl 0x39174b0 prev 0x3917130 <col:25, col:32> struct Inner | | |-CXXMethodDecl 0x3917540 <col:43, col:51> f 'int (void)' | | | `-CompoundStmt 0x390f680 <col:50, col:51> | | |-CXXConstructorDecl 0x3917610 <col:32> Inner 'void (void)' inline noexcept-unevaluated 0x3917610 | | | `-CompoundStmt 0x3918370 <col:32> | | |-CXXConstructorDecl 0x3917770 <col:32> Inner 'void (const struct Outer<float>::Inner<int *> &)' inline noexcept-unevaluated 0x3917770 | | | `-ParmVarDecl 0x39178b0 <col:32> 'const struct Outer<float>::Inner<int *> &' | | `-CXXConstructorDecl 0x39181d0 <col:32> Inner 'void (struct Outer<float>::Inner<int *> &&)' inline noexcept-unevaluated 0x39181d0 | | `-ParmVarDecl 0x3918310 <col:32> 'struct Outer<float>::Inner<int *> &&' | `-ClassTemplateSpecializationDecl 0x3918540 <line:3:4, col:32> struct Inner definition | |-TemplateArgument type 'int' | |-CXXRecordDecl 0x3918840 prev 0x3918540 <col:25, col:32> struct Inner | |-CXXMethodDecl 0x39188d0 <col:39, col:49> f 'float (void)' | | `-CompoundStmt 0x390f668 <col:48, col:49> | |-CXXConstructorDecl 0x39189a0 <col:32> Inner 'void (void)' inline noexcept-unevaluated 0x39189a0 | | `-CompoundStmt 0x3918e40 <col:32> | |-CXXConstructorDecl 0x3918ad0 <col:32> Inner 'void (const struct Outer<float>::Inner<int> &)' inline noexcept-unevaluated 0x3918ad0 | | `-ParmVarDecl 0x3918c10 <col:32> 'const struct Outer<float>::Inner<int> &' | `-CXXConstructorDecl 0x3918ca0 <col:32> Inner 'void (struct Outer<float>::Inner<int> &&)' inline noexcept-unevaluated 0x3918ca0 | `-ParmVarDecl 0x3918de0 <col:32> 'struct Outer<float>::Inner<int> &&' Here, both Inner instantiations are descendants of 1 ClassTemplateDecl. I expected that there'd be a node for ClassTemplatePartialSpecializationDecl corresponding to Outer<float>::Inner<U*>, and Outer<float>::Inner<int *> would derive from that. Which option is true? 1. This is a bug in -ast-dump. 2. This is a bug in the clang AST code. 3. This is expected.
Apparently Analagous Threads
- [LLVMdev] Clang error compiling
- [lldb-dev] Adding DWARF5 accelerator table support to llvm
- [lldb-dev] Adding DWARF5 accelerator table support to llvm
- Strange local variable cv::VideoCapture allocated
- [LLVMdev] assert when mixing static and non-static members with an external AST source