[cfe-commits] r94116 - in /cfe/trunk: test/Index/c-index-api-loadTU-test.m tools/CIndex/CIndex.cpp

Douglas Gregor dgregor at apple.com
Thu Jan 21 15:27:09 PST 2010


Author: dgregor
Date: Thu Jan 21 17:27:09 2010
New Revision: 94116

URL: http://llvm.org/viewvc/llvm-project?rev=94116&view=rev
Log:
Teach the cursor visitor to walk statements and expressions, including
a few important subkinds. Now we're cookin' with gas!

Modified:
    cfe/trunk/test/Index/c-index-api-loadTU-test.m
    cfe/trunk/tools/CIndex/CIndex.cpp

Modified: cfe/trunk/test/Index/c-index-api-loadTU-test.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/c-index-api-loadTU-test.m?rev=94116&r1=94115&r2=94116&view=diff

==============================================================================
--- cfe/trunk/test/Index/c-index-api-loadTU-test.m (original)
+++ cfe/trunk/test/Index/c-index-api-loadTU-test.m Thu Jan 21 17:27:09 2010
@@ -87,3 +87,15 @@
 // CHECK: c-index-api-loadTU-test.m:49:13: VarDecl=d:49:13 (Definition) [Extent=49:13:49:13]
 // CHECK: c-index-api-loadTU-test.m:49:2: TypeRef=id:0:0 [Extent=49:2:49:3]
 // CHECK: c-index-api-loadTU-test.m:49:6: ObjCProtocolRef=Proto:24:1 [Extent=49:6:49:10]
+// CHECK: c-index-api-loadTU-test.m:50:2: DeclRefExpr=d:49:13 [Extent=50:2:50:2]
+// CHECK: c-index-api-loadTU-test.m:50:6: DeclRefExpr=c:48:12 [Extent=50:6:50:6]
+// CHECK: c-index-api-loadTU-test.m:51:2: ObjCMessageExpr=pMethod:25:1 [Extent=51:2:51:12]
+// CHECK: c-index-api-loadTU-test.m:51:3: DeclRefExpr=d:49:13 [Extent=51:3:51:3]
+// CHECK: c-index-api-loadTU-test.m:52:2: ObjCMessageExpr=catMethodWithFloat::20:1 [Extent=52:2:52:43]
+// CHECK: c-index-api-loadTU-test.m:52:3: DeclRefExpr=bee:46:8 [Extent=52:3:52:5]
+// CHECK: c-index-api-loadTU-test.m:52:26: ObjCMessageExpr=floatMethod:21:1 [Extent=52:26:52:42]
+// CHECK: c-index-api-loadTU-test.m:52:27: DeclRefExpr=bee:46:8 [Extent=52:27:52:29]
+// CHECK: c-index-api-loadTU-test.m:53:3: CallExpr=main:45:5 [Extent=53:3:53:36]
+// CHECK: c-index-api-loadTU-test.m:53:3: DeclRefExpr=main:45:5 [Extent=53:3:53:6]
+// CHECK: c-index-api-loadTU-test.m:53:8: DeclRefExpr=someEnum:42:3 [Extent=53:8:53:15]
+// CHECK: c-index-api-loadTU-test.m:53:33: DeclRefExpr=bee:46:8 [Extent=53:33:53:35]

Modified: cfe/trunk/tools/CIndex/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=94116&r1=94115&r2=94116&view=diff

==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndex.cpp Thu Jan 21 17:27:09 2010
@@ -142,7 +142,8 @@
   
 // Cursor visitor.
 class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
-                      public TypeLocVisitor<CursorVisitor, bool>
+                      public TypeLocVisitor<CursorVisitor, bool>,
+                      public StmtVisitor<CursorVisitor, bool>
 {
   ASTUnit *TU;
   CXCursor Parent;
@@ -157,6 +158,7 @@
   
   using DeclVisitor<CursorVisitor, bool>::Visit;
   using TypeLocVisitor<CursorVisitor, bool>::Visit;
+  using StmtVisitor<CursorVisitor, bool>::Visit;
   
 public:
   CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData, 
@@ -178,6 +180,7 @@
   bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
   bool VisitDeclaratorDecl(DeclaratorDecl *DD);
   bool VisitFunctionDecl(FunctionDecl *ND);
+  bool VisitObjCContainerDecl(ObjCContainerDecl *D);
   bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
   bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
   bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
@@ -205,6 +208,10 @@
   // implemented
   bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
   bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
+  
+  // Statement visitors
+  bool VisitStmt(Stmt *S);
+  bool VisitDeclStmt(DeclStmt *S);
 };
   
 } // end anonymous namespace
@@ -247,6 +254,11 @@
 /// \returns true if the visitation should be aborted, false if it
 /// should continue.
 bool CursorVisitor::VisitChildren(CXCursor Cursor) { 
+  if (clang_isReference(Cursor.kind)) {
+    // By definition, references have no children.
+    return false;
+  }
+  
   // Set the Parent field to Cursor, then back to its old value once we're 
   // done.
   class SetParentRAII {
@@ -276,6 +288,11 @@
     return Visit(D);
   }
   
+  if (clang_isStatement(Cursor.kind))
+    return Visit(getCursorStmt(Cursor));
+  if (clang_isExpression(Cursor.kind))
+    return Visit(getCursorExpr(Cursor));
+  
   if (clang_isTranslationUnit(Cursor.kind)) {
     ASTUnit *CXXUnit = getCursorASTUnit(Cursor);
     if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls()) {
@@ -292,9 +309,8 @@
     
     return false;
   }
-    
+  
   // Nothing to visit at the moment.
-  // FIXME: Traverse statements, declarations, etc. here.
   return false;
 }
 
@@ -325,21 +341,17 @@
   if (VisitDeclaratorDecl(ND))
     return true;
 
-  // FIXME: This is wrong. We want to visit the body as a statement.
-  if (ND->isThisDeclarationADefinition()) {
-    return VisitDeclContext(ND);
-    
-#if 0
-    // Not currently needed.
-    CompoundStmt *Body = dyn_cast<CompoundStmt>(ND->getBody());
-    CRefVisitor RVisit(CDecl, Callback, CData);
-    RVisit.Visit(Body);
-#endif
-  }
+  if (ND->isThisDeclarationADefinition() &&
+      Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
+    return true;
   
   return false;
 }
 
+bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
+  return VisitDeclContext(D);
+}
+
 bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
   if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
                                    TU)))
@@ -351,7 +363,7 @@
     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
       return true;
   
-  return VisitDeclContext(ND);
+  return VisitObjCContainerDecl(ND);
 }
 
 bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
@@ -368,13 +380,23 @@
     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
       return true;
   
-  return VisitDeclContext(D);
+  return VisitObjCContainerDecl(D);
 }
 
 bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
-  // FIXME: Wrong in the same way that VisitFunctionDecl is wrong.
-  if (ND->getBody())
-    return VisitDeclContext(ND);
+  // FIXME: We really need a TypeLoc covering Objective-C method declarations.
+  // At the moment, we don't have information about locations in the return 
+  // type.
+  for (ObjCMethodDecl::param_iterator P = ND->param_begin(), 
+                                   PEnd = ND->param_end();
+       P != PEnd; ++P) {
+    if (Visit(MakeCXCursor(*P, TU)))
+      return true;
+  }
+  
+  if (ND->isThisDeclarationADefinition() &&
+      Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
+    return true;
   
   return false;
 }
@@ -386,7 +408,7 @@
     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
       return true;
   
-  return VisitDeclContext(PID);
+  return VisitObjCContainerDecl(PID);
 }
 
 bool CursorVisitor::VisitTagDecl(TagDecl *D) {
@@ -517,9 +539,6 @@
   if (Visit(TL.getResultLoc()))
     return true;
 
-  // FIXME: For function definitions, this means that we'll end up
-  // visiting the parameters twice, because VisitFunctionDecl is
-  // walking the DeclContext.
   for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
     if (Visit(MakeCXCursor(TL.getArg(I), TU)))
       return true;
@@ -548,6 +567,26 @@
   return false;
 }
 
+bool CursorVisitor::VisitStmt(Stmt *S) {
+  for (Stmt::child_iterator Child = S->child_begin(), ChildEnd = S->child_end();
+       Child != ChildEnd; ++Child) {
+    if (Visit(MakeCXCursor(*Child, StmtParent, TU)))
+      return true;
+  }
+  
+  return false;
+}
+
+bool CursorVisitor::VisitDeclStmt(DeclStmt *S) {
+  for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
+       D != DEnd; ++D) {
+    if (Visit(MakeCXCursor(*D, TU)))
+      return true;
+  }
+  
+  return false;
+}
+
 CXString CIndexer::createCXString(const char *String, bool DupString){
   CXString Str;
   if (DupString) {





More information about the cfe-commits mailing list