summaryrefslogtreecommitdiffstats
path: root/clang/tools/libclang
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-09-01 17:32:36 +0000
committerDouglas Gregor <dgregor@apple.com>2010-09-01 17:32:36 +0000
commit9dc243c3eb85c71b05d117525324091ec2e142f2 (patch)
treee15665a4a4034a167511656d886ad540b85d5a3d /clang/tools/libclang
parenta5d315c6651ce927fad4e39e873b117e4feb129f (diff)
downloadbcm5719-llvm-9dc243c3eb85c71b05d117525324091ec2e142f2.tar.gz
bcm5719-llvm-9dc243c3eb85c71b05d117525324091ec2e142f2.zip
Improve libclang indexing support for class template specializations
in a few related ways: - Don't recurse into instantiations of templates. - Recurse into explicit specializations. - Visit the template arguments of an explicit specialization or explicit instantiation. - Include template specialization arguments in the USRs for class template specializations. llvm-svn: 112720
Diffstat (limited to 'clang/tools/libclang')
-rw-r--r--clang/tools/libclang/CIndex.cpp36
-rw-r--r--clang/tools/libclang/CIndexUSRs.cpp11
2 files changed, 47 insertions, 0 deletions
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index af521e9cdad..3c4211efdc5 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -290,6 +290,7 @@ public:
bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
bool VisitTypedefDecl(TypedefDecl *D);
bool VisitTagDecl(TagDecl *D);
+ bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
bool VisitClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *D);
bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
@@ -605,6 +606,41 @@ bool CursorVisitor::VisitTagDecl(TagDecl *D) {
return VisitDeclContext(D);
}
+bool CursorVisitor::VisitClassTemplateSpecializationDecl(
+ ClassTemplateSpecializationDecl *D) {
+ bool ShouldVisitBody = false;
+ switch (D->getSpecializationKind()) {
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ // Nothing to visit
+ return false;
+
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ break;
+
+ case TSK_ExplicitSpecialization:
+ ShouldVisitBody = true;
+ break;
+ }
+
+ // Visit the template arguments used in the specialization.
+ if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
+ TypeLoc TL = SpecType->getTypeLoc();
+ if (TemplateSpecializationTypeLoc *TSTLoc
+ = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
+ for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
+ if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
+ return true;
+ }
+ }
+
+ if (ShouldVisitBody && VisitCXXRecordDecl(D))
+ return true;
+
+ return false;
+}
+
bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *D) {
// FIXME: Visit the "outer" template parameter lists on the TagDecl
diff --git a/clang/tools/libclang/CIndexUSRs.cpp b/clang/tools/libclang/CIndexUSRs.cpp
index 5628aef056a..a60d1d3e189 100644
--- a/clang/tools/libclang/CIndexUSRs.cpp
+++ b/clang/tools/libclang/CIndexUSRs.cpp
@@ -422,6 +422,17 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
else
Buf[off] = 'a';
}
+
+ // For a class template specialization, mangle the template arguments.
+ if (ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+ const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs();
+ Out << '>';
+ for (unsigned I = 0, N = Args.size(); I != N; ++I) {
+ Out << '#';
+ VisitTemplateArgument(Args.get(I));
+ }
+ }
}
void USRGenerator::VisitTypedefDecl(TypedefDecl *D) {
OpenPOWER on IntegriCloud