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

Douglas Gregor dgregor at apple.com
Thu Jan 21 09:29:08 PST 2010


Author: dgregor
Date: Thu Jan 21 11:29:07 2010
New Revision: 94085

URL: http://llvm.org/viewvc/llvm-project?rev=94085&view=rev
Log:
Teach the cursor visitor to walk into a variety of different TypeLoc
kinds, so that we see referenced types, protocols, classes, etc.

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=94085&r1=94084&r2=94085&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 11:29:07 2010
@@ -78,9 +78,12 @@
 // CHECK: c-index-api-loadTU-test.m:45:15: ParmDecl=argc:45:15 (Definition) [Extent=45:15:45:18]
 // CHECK: c-index-api-loadTU-test.m:45:34: ParmDecl=argv:45:34 (Definition) [Extent=45:34:45:37]
 // CHECK: c-index-api-loadTU-test.m:46:8: VarDecl=bee:46:8 (Definition) [Extent=46:8:46:10]
+// CHECK: c-index-api-loadTU-test.m:46:2: ObjCClassRef=Baz:32:12 [Extent=46:2:46:4]
 // CHECK: c-index-api-loadTU-test.m:47:5: VarDecl=a:47:5 (Definition) [Extent=47:5:47:17]
 // CHECK: c-index-api-loadTU-test.m:47:2: TypeRef=id:0:0 [Extent=47:2:47:3]
 // CHECK: c-index-api-loadTU-test.m:48:12: VarDecl=c:48:12 (Definition) [Extent=48:12:48:25]
+// CHECK: c-index-api-loadTU-test.m:48:2: TypeRef=id:0:0 [Extent=48:2:48:3]
+// CHECK: c-index-api-loadTU-test.m:48:6: ObjCProtocolRef=SubP:28:1 [Extent=48:6:48:9]
 // 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]

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

==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndex.cpp Thu Jan 21 11:29:07 2010
@@ -146,9 +146,10 @@
 {
   ASTUnit *TU;
   CXCursor Parent;
+  Decl *StmtParent;
   CXCursorVisitor Visitor;
   CXClientData ClientData;
-  
+
   // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
   // to the visitor. Declarations with a PCH level greater than this value will
   // be suppressed.
@@ -166,6 +167,7 @@
     Parent.data[0] = 0;
     Parent.data[1] = 0;
     Parent.data[2] = 0;
+    StmtParent = 0;
   }
   
   bool Visit(CXCursor Cursor);
@@ -183,7 +185,21 @@
   bool VisitTagDecl(TagDecl *D);
 
   // Type visitors
+  // FIXME: QualifiedTypeLoc doesn't provide any location information
+  bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
   bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
+  bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
+  bool VisitTagTypeLoc(TagTypeLoc TL);
+  // FIXME: TemplateTypeParmTypeLoc doesn't provide any location information
+  bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
+  bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
+  bool VisitPointerTypeLoc(PointerTypeLoc TL);
+  bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
+  bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
+  bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
+  bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
+  bool VisitFunctionTypeLoc(FunctionTypeLoc TL);
+  bool VisitArrayTypeLoc(ArrayTypeLoc TL);
 };
   
 } // end anonymous namespace
@@ -230,19 +246,24 @@
   // done.
   class SetParentRAII {
     CXCursor &Parent;
+    Decl *&StmtParent;
     CXCursor OldParent;
-    
+
   public:
-    SetParentRAII(CXCursor &Parent, CXCursor NewParent)
-      : Parent(Parent), OldParent(Parent) 
+    SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
+      : Parent(Parent), StmtParent(StmtParent), OldParent(Parent) 
     {
       Parent = NewParent;
+      if (clang_isDeclaration(Parent.kind))
+        StmtParent = getCursorDecl(Parent);
     }
     
     ~SetParentRAII() {
       Parent = OldParent;
+      if (clang_isDeclaration(Parent.kind))
+        StmtParent = getCursorDecl(Parent);
     }
-  } SetParent(Parent, Cursor);
+  } SetParent(Parent, StmtParent, Cursor);
   
   if (clang_isDeclaration(Cursor.kind)) {
     Decl *D = getCursorDecl(Cursor);
@@ -296,8 +317,10 @@
 }
 
 bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
-  // FIXME: This is wrong. We always want to visit the parameters and
-  // the body, if available.
+  if (VisitDeclaratorDecl(ND))
+    return true;
+
+  // FIXME: This is wrong. We want to visit the body as a statement.
   if (ND->isThisDeclarationADefinition()) {
     return VisitDeclContext(ND);
     
@@ -365,10 +388,150 @@
   return VisitDeclContext(D);
 }
 
+bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
+  ASTContext &Context = TU->getASTContext();
+
+  // Some builtin types (such as Objective-C's "id", "sel", and
+  // "Class") have associated declarations. Create cursors for those.
+  QualType VisitType;
+  switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
+  case BuiltinType::Void:
+  case BuiltinType::Bool:
+  case BuiltinType::Char_U:
+  case BuiltinType::UChar:
+  case BuiltinType::Char16:
+  case BuiltinType::Char32:
+  case BuiltinType::UShort:
+  case BuiltinType::UInt:
+  case BuiltinType::ULong:
+  case BuiltinType::ULongLong:
+  case BuiltinType::UInt128:
+  case BuiltinType::Char_S:
+  case BuiltinType::SChar:
+  case BuiltinType::WChar:
+  case BuiltinType::Short:
+  case BuiltinType::Int:
+  case BuiltinType::Long:
+  case BuiltinType::LongLong:
+  case BuiltinType::Int128:
+  case BuiltinType::Float: 
+  case BuiltinType::Double: 
+  case BuiltinType::LongDouble:
+  case BuiltinType::NullPtr:
+  case BuiltinType::Overload:
+  case BuiltinType::Dependent:
+    break;
+
+  case BuiltinType::UndeducedAuto: // FIXME: Deserves a cursor?
+    break;
+
+  case BuiltinType::ObjCId:
+    VisitType = Context.getObjCIdType();
+    break;
+
+  case BuiltinType::ObjCClass:
+    VisitType = Context.getObjCClassType();
+    break;
+
+  case BuiltinType::ObjCSel:
+    VisitType = Context.getObjCSelType();
+    break;
+  }
+
+  if (!VisitType.isNull()) {
+    if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
+      return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), 
+                                     TU));
+  }
+
+  return false;
+}
+
 bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
   return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU));
 }
 
+bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
+  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
+}
+
+bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
+  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
+}
+
+bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+  if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
+    return true;
+
+  for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
+    if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
+                                        TU)))
+      return true;
+  }
+
+  return false;
+}
+
+bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
+  if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseTypeLoc()))
+    return true;
+
+  if (TL.hasProtocolsAsWritten()) {
+    for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
+      if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), 
+                                          TL.getProtocolLoc(I),
+                                          TU)))
+        return true;
+    }
+  }
+  
+  return false;
+}
+
+bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());
+}
+
+bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());
+}
+
+bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());
+}
+
+bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());  
+}
+
+bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());  
+}
+
+bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
+  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;
+
+  return false;
+}
+
+bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
+  if (Visit(TL.getElementLoc()))
+    return true;
+
+  if (Expr *Size = TL.getSizeExpr())
+    return Visit(MakeCXCursor(Size, StmtParent, TU));
+
+  return false;
+}
+
 CXString CIndexer::createCXString(const char *String, bool DupString){
   CXString Str;
   if (DupString) {





More information about the cfe-commits mailing list