[cfe-commits] r112636 - in /cfe/trunk: include/clang-c/Index.h test/Index/index-templates.cpp tools/libclang/CIndex.cpp tools/libclang/CXCursor.cpp tools/libclang/CXCursor.h
Douglas Gregor
dgregor at apple.com
Tue Aug 31 13:37:03 PDT 2010
Author: dgregor
Date: Tue Aug 31 15:37:03 2010
New Revision: 112636
URL: http://llvm.org/viewvc/llvm-project?rev=112636&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang-c/Index.h
cfe/trunk/test/Index/index-templates.cpp
cfe/trunk/tools/libclang/CIndex.cpp
cfe/trunk/tools/libclang/CXCursor.cpp
cfe/trunk/tools/libclang/CXCursor.h
Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=112636&r1=112635&r2=112636&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Tue Aug 31 15:37:03 2010
@@ -1020,7 +1020,12 @@
*/
CXCursor_TypeRef = 43,
CXCursor_CXXBaseSpecifier = 44,
- CXCursor_LastRef = CXCursor_CXXBaseSpecifier,
+ /**
+ * \brief A reference to a class template, function template, or template
+ * template parameter.
+ */
+ CXCursor_TemplateRef = 45,
+ CXCursor_LastRef = CXCursor_TemplateRef,
/* Error conditions */
CXCursor_FirstInvalid = 70,
Modified: cfe/trunk/test/Index/index-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/index-templates.cpp?rev=112636&r1=112635&r2=112636&view=diff
==============================================================================
--- cfe/trunk/test/Index/index-templates.cpp (original)
+++ cfe/trunk/test/Index/index-templates.cpp Tue Aug 31 15:37:03 2010
@@ -19,7 +19,7 @@
// FIXME: Need the template type parameter here
// CHECK-LOAD: index-templates.cpp:3:66: TemplateTemplateParameter=X:3:66 (Definition) Extent=[3:31 - 3:67]
// CHECK-LOAD: index-templates.cpp:4:20: ParmDecl=x:4:20 (Definition) Extent=[4:8 - 4:21]
-// FIXME: Need the template declaration here.
+// CHECK-LOAD: index-templates.cpp:4:8: TemplateRef=X:3:66 Extent=[4:8 - 4:9]
// FIXME: Need the template type parameter here
// CHECK-LOAD: index-templates.cpp:4:13: DeclRefExpr=Value:3:24 Extent=[4:13 - 4:18]
// CHECK-LOAD: index-templates.cpp:6:28: ClassTemplate=allocator:6:28 Extent=[6:1 - 6:37]
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=112636&r1=112635&r2=112636&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Tue Aug 31 15:37:03 2010
@@ -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();
}
Modified: cfe/trunk/tools/libclang/CXCursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=112636&r1=112635&r2=112636&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Tue Aug 31 15:37:03 2010
@@ -313,6 +313,22 @@
reinterpret_cast<uintptr_t>(C.data[1])));
}
+CXCursor cxcursor::MakeCursorTemplateRef(TemplateDecl *Template,
+ SourceLocation Loc, ASTUnit *TU) {
+ assert(Template && TU && "Invalid arguments!");
+ void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+ CXCursor C = { CXCursor_TemplateRef, { Template, RawLoc, TU } };
+ return C;
+}
+
+std::pair<TemplateDecl *, SourceLocation>
+cxcursor::getCursorTemplateRef(CXCursor C) {
+ assert(C.kind == CXCursor_TemplateRef);
+ return std::make_pair(static_cast<TemplateDecl *>(C.data[0]),
+ SourceLocation::getFromRawEncoding(
+ reinterpret_cast<uintptr_t>(C.data[1])));
+}
+
CXCursor cxcursor::MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU){
CXCursor C = { CXCursor_CXXBaseSpecifier, { B, 0, TU } };
return C;
Modified: cfe/trunk/tools/libclang/CXCursor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.h?rev=112636&r1=112635&r2=112636&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.h (original)
+++ cfe/trunk/tools/libclang/CXCursor.h Tue Aug 31 15:37:03 2010
@@ -32,6 +32,7 @@
class ObjCInterfaceDecl;
class ObjCProtocolDecl;
class Stmt;
+class TemplateDecl;
class TypeDecl;
namespace cxcursor {
@@ -71,11 +72,19 @@
/// \brief Create a type reference at the given location.
CXCursor MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc, ASTUnit *TU);
-
+
/// \brief Unpack a TypeRef cursor into the class it references
/// and optionally the location where the reference occurred.
std::pair<TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C);
+/// \brief Create a reference to a template at the given location.
+CXCursor MakeCursorTemplateRef(TemplateDecl *Template, SourceLocation Loc,
+ ASTUnit *TU);
+
+/// \brief Unpack a TemplateRef cursor into the template it references and
+/// the location where the reference occurred.
+std::pair<TemplateDecl *, SourceLocation> getCursorTemplateRef(CXCursor C);
+
/// \brief Create a CXX base specifier cursor.
CXCursor MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU);
More information about the cfe-commits
mailing list