Extend libclang with a new cursor kind that indicates a reference to a
template. Such cursors occur, for example, in template specialization
types such as vector<int>. Note that we do not handle the
super-interesting case where the template name is unresolved, e.g.,
within a template.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112636 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index ae53c16..1515ed3 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -322,6 +322,7 @@
// Template visitors
bool VisitTemplateParameters(const TemplateParameterList *Params);
+ bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
// Type visitors
@@ -902,6 +903,30 @@
return false;
}
+bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
+ switch (Name.getKind()) {
+ case TemplateName::Template:
+ return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
+
+ case TemplateName::OverloadedTemplate:
+ // FIXME: We need a way to return multiple lookup results in a single
+ // cursor.
+ return false;
+
+ case TemplateName::DependentTemplate:
+ // FIXME: Visit nested-name-specifier.
+ return false;
+
+ case TemplateName::QualifiedTemplate:
+ // FIXME: Visit nested-name-specifier.
+ return Visit(MakeCursorTemplateRef(
+ Name.getAsQualifiedTemplateName()->getDecl(),
+ Loc, TU));
+ }
+
+ return false;
+}
+
bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
switch (TAL.getArgument().getKind()) {
case TemplateArgument::Null:
@@ -928,8 +953,8 @@
return false;
case TemplateArgument::Template:
- // FIXME: Visit template name.
- return false;
+ return VisitTemplateName(TAL.getArgument().getAsTemplate(),
+ TAL.getTemplateNameLoc());
}
return false;
@@ -1090,7 +1115,10 @@
bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
TemplateSpecializationTypeLoc TL) {
- // FIXME: Visit the template name.
+ // Visit the template name.
+ if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
+ TL.getTemplateNameLoc()))
+ return true;
// Visit the template arguments.
for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
@@ -2023,6 +2051,12 @@
return createCXString(getCursorContext(C).getTypeDeclType(Type).
getAsString());
}
+ case CXCursor_TemplateRef: {
+ TemplateDecl *Template = getCursorTemplateRef(C).first;
+ assert(Template && "Missing type decl");
+
+ return createCXString(Template->getNameAsString());
+ }
default:
return createCXString("<not implemented>");
@@ -2102,6 +2136,8 @@
return createCXString("ObjCClassRef");
case CXCursor_TypeRef:
return createCXString("TypeRef");
+ case CXCursor_TemplateRef:
+ return createCXString("TemplateRef");
case CXCursor_UnexposedExpr:
return createCXString("UnexposedExpr");
case CXCursor_BlockExpr:
@@ -2287,7 +2323,12 @@
std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
-
+
+ case CXCursor_TemplateRef: {
+ std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
+ return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
+ }
+
case CXCursor_CXXBaseSpecifier: {
// FIXME: Figure out what location to return for a CXXBaseSpecifier.
return clang_getNullLocation();
@@ -2345,7 +2386,10 @@
case CXCursor_TypeRef:
return getCursorTypeRef(C).second;
-
+
+ case CXCursor_TemplateRef:
+ return getCursorTemplateRef(C).second;
+
case CXCursor_CXXBaseSpecifier:
// FIXME: Figure out what source range to use for a CXBaseSpecifier.
return SourceRange();
@@ -2422,7 +2466,10 @@
case CXCursor_TypeRef:
return MakeCXCursor(getCursorTypeRef(C).first, CXXUnit);
-
+
+ case CXCursor_TemplateRef:
+ return MakeCXCursor(getCursorTemplateRef(C).first, CXXUnit);
+
case CXCursor_CXXBaseSpecifier: {
CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
@@ -2539,8 +2586,7 @@
case Decl::ClassTemplate: {
if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
->getDefinition())
- return MakeCXCursor(
- cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
+ return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
CXXUnit);
return clang_getNullCursor();
}