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.
Reasonably Related 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
