r204100 - AST dumper: if we have multiple implicit instantiations of the same class
Richard Smith
richard-llvm at metafoo.co.uk
Mon Mar 17 19:07:29 PDT 2014
Author: rsmith
Date: Mon Mar 17 21:07:28 2014
New Revision: 204100
URL: http://llvm.org/viewvc/llvm-project?rev=204100&view=rev
Log:
AST dumper: if we have multiple implicit instantiations of the same class
template specialization (from different modules), dump them all, so that every
declaration is dumped somewhere.
Modified:
cfe/trunk/lib/AST/ASTDumper.cpp
cfe/trunk/test/Modules/cxx-templates.cpp
Modified: cfe/trunk/lib/AST/ASTDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=204100&r1=204099&r2=204100&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDumper.cpp (original)
+++ cfe/trunk/lib/AST/ASTDumper.cpp Mon Mar 17 21:07:28 2014
@@ -254,6 +254,11 @@ namespace {
void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
void VisitCXXRecordDecl(const CXXRecordDecl *D);
void VisitStaticAssertDecl(const StaticAssertDecl *D);
+ template<typename SpecializationDecl>
+ void VisitTemplateDeclSpecialization(ChildDumper &Children,
+ const SpecializationDecl *D,
+ bool DumpExplicitInst,
+ bool DumpRefOnly);
template<typename TemplateDecl>
void VisitTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
@@ -1075,6 +1080,46 @@ void ASTDumper::VisitStaticAssertDecl(co
dumpStmt(D->getMessage());
}
+template<typename SpecializationDecl>
+void ASTDumper::VisitTemplateDeclSpecialization(ChildDumper &Children,
+ const SpecializationDecl *D,
+ bool DumpExplicitInst,
+ bool DumpRefOnly) {
+ bool DumpedAny = false;
+ for (auto *RedeclWithBadType : D->redecls()) {
+ // FIXME: The redecls() range sometimes has elements of a less-specific
+ // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
+ // us TagDecls, and should give CXXRecordDecls).
+ auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
+ if (!Redecl) {
+ // Found the injected-class-name for a class template. This will be dumped
+ // as part of its surrounding class so we don't need to dump it here.
+ assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
+ "expected an injected-class-name");
+ continue;
+ }
+
+ switch (Redecl->getTemplateSpecializationKind()) {
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ if (!DumpExplicitInst)
+ break;
+ // Fall through.
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ Children.dump(Redecl, DumpRefOnly);
+ DumpedAny = true;
+ break;
+ case TSK_ExplicitSpecialization:
+ break;
+ }
+ }
+
+ // Ensure we dump at least one decl for each specialization.
+ if (!DumpedAny)
+ Children.dumpRef(D);
+}
+
template<typename TemplateDecl>
void ASTDumper::VisitTemplateDecl(const TemplateDecl *D,
bool DumpExplicitInst) {
@@ -1084,22 +1129,9 @@ void ASTDumper::VisitTemplateDecl(const
ChildDumper Children(*this);
Children.dump(D->getTemplatedDecl());
- for (auto *Child : D->specializations()) {
- switch (Child->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- Children.dump(Child, /*Ref*/D != D->getCanonicalDecl());
- break;
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- Children.dump(Child, /*Ref*/D != D->getCanonicalDecl() ||
- !DumpExplicitInst);
- break;
- case TSK_ExplicitSpecialization:
- Children.dumpRef(Child);
- break;
- }
- }
+ for (auto *Child : D->specializations())
+ VisitTemplateDeclSpecialization(Children, Child, DumpExplicitInst,
+ !D->isCanonicalDecl());
}
void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
Modified: cfe/trunk/test/Modules/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cxx-templates.cpp?rev=204100&r1=204099&r2=204100&view=diff
==============================================================================
--- cfe/trunk/test/Modules/cxx-templates.cpp (original)
+++ cfe/trunk/test/Modules/cxx-templates.cpp Mon Mar 17 21:07:28 2014
@@ -1,6 +1,7 @@
// RUN: rm -rf %t
// RUN: not %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump -ast-dump-lookups | FileCheck %s --check-prefix=CHECK-GLOBAL
// RUN: not %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump -ast-dump-lookups -ast-dump-filter N | FileCheck %s --check-prefix=CHECK-NAMESPACE-N
+// RUN: not %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump | FileCheck %s --check-prefix=CHECK-DUMP
// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11
@import cxx_templates_a;
@@ -123,3 +124,13 @@ void testImplicitSpecialMembers(SomeTemp
// CHECK-NAMESPACE-N: DeclarationName 'f'
// CHECK-NAMESPACE-N-NEXT: |-FunctionTemplate {{.*}} 'f'
// CHECK-NAMESPACE-N-NEXT: `-FunctionTemplate {{.*}} 'f'
+
+// CHECK-DUMP: ClassTemplateDecl {{.*}} <{{.*}}/cxx-templates-common.h:1:1, {{.*}}> in cxx_templates_common SomeTemplate
+// CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} prev [[CHAR2:[^ ]*]] {{.*}} SomeTemplate
+// CHECK-DUMP-NEXT: TemplateArgument type 'char [2]'
+// CHECK-DUMP: ClassTemplateSpecializationDecl [[CHAR2]] {{.*}} SomeTemplate definition
+// CHECK-DUMP-NEXT: TemplateArgument type 'char [2]'
+// CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} prev [[CHAR1:[^ ]*]] {{.*}} SomeTemplate
+// CHECK-DUMP-NEXT: TemplateArgument type 'char [1]'
+// CHECK-DUMP: ClassTemplateSpecializationDecl [[CHAR1]] {{.*}} SomeTemplate definition
+// CHECK-DUMP-NEXT: TemplateArgument type 'char [1]'
More information about the cfe-commits
mailing list