[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