[cfe-commits] r81004 - in /cfe/trunk: include/clang/Frontend/ASTUnit.h lib/Frontend/ASTUnit.cpp tools/CIndex/CIndex.cpp tools/c-index-test/c-index-test.c

Steve Naroff snaroff at apple.com
Fri Sep 4 08:44:05 PDT 2009


Author: snaroff
Date: Fri Sep  4 10:44:05 2009
New Revision: 81004

URL: http://llvm.org/viewvc/llvm-project?rev=81004&view=rev
Log:
Implement accessors clang_getCursorKind(), clang_getCursorDecl().
Implement clang_getCursor() - wired up to Argiris's work.
Implement callbacks for CXCursor_ObjCProtocolRef.


Modified:
    cfe/trunk/include/clang/Frontend/ASTUnit.h
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/tools/CIndex/CIndex.cpp
    cfe/trunk/tools/c-index-test/c-index-test.c

Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=81004&r1=81003&r2=81004&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Fri Sep  4 10:44:05 2009
@@ -59,6 +59,7 @@
   const Diagnostic &getDiagnostic() const { return *Diags.get(); }
         Diagnostic &getDiagnostic()       { return *Diags.get(); }
         
+  FileManager &getFileManager();
   const std::string &getOriginalSourceFileName();
 
   /// \brief Create a ASTUnit from a PCH file.

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=81004&r1=81003&r2=81004&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Fri Sep  4 10:44:05 2009
@@ -81,6 +81,10 @@
   return dyn_cast<PCHReader>(Ctx->getExternalSource())->getOriginalSourceFile();
 }
 
+FileManager &ASTUnit::getFileManager() {
+  return HeaderInfo->getFileMgr();
+}
+
 ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
                                   FileManager &FileMgr,
                                   std::string *ErrMsg) {

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

==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndex.cpp Fri Sep  4 10:44:05 2009
@@ -14,6 +14,8 @@
 #include "clang-c/Index.h"
 #include "clang/Index/Program.h"
 #include "clang/Index/Indexer.h"
+#include "clang/Index/ASTLocation.h"
+#include "clang/Index/Utils.h"
 #include "clang/AST/DeclVisitor.h"
 #include "clang/AST/Decl.h"
 #include "clang/Basic/FileManager.h"
@@ -119,9 +121,18 @@
     if (D->getSuperClass())
       Call(CXCursor_ObjCSuperClassRef, D);
 
-    // FIXME: Issue callbacks for protocol refs.
+    for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(), 
+         E = D->protocol_end(); I != E; ++I)
+      Call(CXCursor_ObjCProtocolRef, *I);
     VisitDeclContext(dyn_cast<DeclContext>(D));
   }
+  void VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
+    for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(), 
+         E = PID->protocol_end(); I != E; ++I)
+      Call(CXCursor_ObjCProtocolRef, *I);
+      
+    VisitDeclContext(dyn_cast<DeclContext>(PID));
+  }
   void VisitTagDecl(TagDecl *D) {
     VisitDeclContext(dyn_cast<DeclContext>(D));
   }
@@ -295,6 +306,12 @@
         assert(OID && "clang_getCursorLine(): Missing category decl");
         return OID->getClassInterface()->getIdentifier()->getName();
         }
+      case CXCursor_ObjCProtocolRef: 
+        {
+        ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
+        assert(OID && "clang_getCursorLine(): Missing protocol decl");
+        return OID->getIdentifier()->getName();
+        }
       default:
         return "<not implemented>";
     }
@@ -328,23 +345,57 @@
    case CXCursor_ObjCClassDefn: return "ObjCClassDefn";
    case CXCursor_ObjCCategoryDefn: return "ObjCCategoryDefn";
    case CXCursor_ObjCSuperClassRef: return "ObjCSuperClassRef";
+   case CXCursor_ObjCProtocolRef: return "ObjCProtocolRef";
    case CXCursor_ObjCClassRef: return "ObjCClassRef";
    default: return "<not implemented>";
   }
 }
 
+static enum CXCursorKind TranslateKind(Decl *D) {
+  switch (D->getKind()) {
+    case Decl::Function: return CXCursor_FunctionDecl;
+    case Decl::Typedef: return CXCursor_TypedefDecl;
+    case Decl::Enum: return CXCursor_EnumDecl;
+    case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
+    case Decl::Record: return CXCursor_StructDecl; // FIXME: union/class
+    case Decl::Field: return CXCursor_FieldDecl;
+    case Decl::Var: return CXCursor_VarDecl;
+    case Decl::ParmVar: return CXCursor_ParmDecl;
+    case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
+    case Decl::ObjCMethod: {
+      ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D);
+      if (MD->isInstanceMethod())
+        return CXCursor_ObjCInstanceMethodDecl;
+      return CXCursor_ObjCClassMethodDecl;
+    }
+    default: break;
+  }
+  return CXCursor_Invalid;
+}
 //
 // CXCursor Operations.
 //
-CXCursor clang_getCursor(CXTranslationUnit, const char *source_name, 
+CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name, 
                          unsigned line, unsigned column)
 {
-  return CXCursor();
-}
-
-CXCursorKind clang_getCursorKind(CXCursor)
-{
-  return CXCursor_Invalid;
+  assert(CTUnit && "Passed null CXTranslationUnit");
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
+  
+  FileManager &FMgr = CXXUnit->getFileManager();
+  const FileEntry *File = FMgr.getFile(source_name, 
+                                       source_name+strlen(source_name));
+  assert(File && "clang_getCursor(): FileManager returned 0");
+  
+  SourceLocation SLoc = 
+    CXXUnit->getSourceManager().getLocation(File, line, column);
+                                                                
+  ASTLocation ALoc = ResolveLocationInAST(CXXUnit->getASTContext(), SLoc);
+  
+  Decl *Dcl = ALoc.getDecl();
+  assert(Dcl && "clang_getCursor(): ASTLocation has a null decl");
+  
+  CXCursor C = { TranslateKind(Dcl), Dcl };
+  return C;
 }
 
 unsigned clang_isDeclaration(enum CXCursorKind K)
@@ -362,22 +413,55 @@
   return K >= CXCursor_FirstDefn && K <= CXCursor_LastDefn;
 }
 
+CXCursorKind clang_getCursorKind(CXCursor C)
+{
+  return C.kind;
+}
+
+CXDecl clang_getCursorDecl(CXCursor C) 
+{
+  return C.decl;
+}
+
 static SourceLocation getLocationFromCursor(CXCursor C, 
                                             SourceManager &SourceMgr,
                                             NamedDecl *ND) {
   if (clang_isReference(C.kind)) {
     switch (C.kind) {
-      case CXCursor_ObjCSuperClassRef:
+      case CXCursor_ObjCSuperClassRef: 
         {
         ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND);
         assert(OID && "clang_getCursorLine(): Missing interface decl");
         return OID->getSuperClassLoc();
         }
+      case CXCursor_ObjCProtocolRef: 
+        {
+        ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
+        assert(OID && "clang_getCursorLine(): Missing protocol decl");
+        return OID->getLocation();
+        }
       default:
         return SourceLocation();
     }
   } else { // We have a declaration or a definition.
-    SourceLocation SLoc = ND->getLocation();
+    SourceLocation SLoc;
+    switch (ND->getKind()) {
+      case Decl::ObjCInterface: 
+        {
+        SLoc = dyn_cast<ObjCInterfaceDecl>(ND)->getClassLoc();
+        break;
+        }
+      case Decl::ObjCProtocol: 
+        {
+        SLoc = ND->getLocation(); /* FIXME: need to get the name location. */
+        break;
+        }
+      default: 
+        {
+        SLoc = ND->getLocation();
+        break;
+        }
+    }
     if (SLoc.isInvalid())
       return SourceLocation();
     return SourceMgr.getSpellingLoc(SLoc); // handles macro instantiations.
@@ -413,11 +497,4 @@
   return SourceMgr.getBufferName(SLoc);
 }
 
-// If CXCursorKind == Cursor_Reference, then this will return the referenced declaration.
-// If CXCursorKind == Cursor_Declaration, then this will return the declaration.
-CXDecl clang_getCursorDecl(CXCursor) 
-{
-  return 0;
-}
-
 } // end extern "C"

Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=81004&r1=81003&r2=81004&view=diff

==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Fri Sep  4 10:44:05 2009
@@ -39,12 +39,21 @@
 int main(int argc, char **argv) {
   CXIndex Idx = clang_createIndex();
   CXTranslationUnit TU = clang_createTranslationUnit(Idx, argv[1]);
-  
-  if (argc == 2)
-    clang_loadTranslationUnit(TU, TranslationUnitVisitor, 0);
-  else if (argc == 3) {
+
+  if (argc == 2) {
+    /* malloc - returns a cursor of type CXCursor_FunctionDecl */
+    CXCursor C = clang_getCursor(TU, "/usr/include/stdlib.h", 169, 7);
+    PrintCursor(C);
+    /* methodSignature - returns a cursor of type ObjCInstanceMethodDecl */
+    C = clang_getCursor(TU, "/System/Library/Frameworks/Foundation.framework/Headers/NSInvocation.h", 22, 1);
+    PrintCursor(C);
+  } else if (argc == 3) {
     enum CXCursorKind K = CXCursor_Invalid;
     
+    if (!strcmp(argv[2], "all")) {
+      clang_loadTranslationUnit(TU, TranslationUnitVisitor, 0);
+      return 1;
+    } 
     if (!strcmp(argv[2], "category")) K = CXCursor_ObjCCategoryDecl;
     else if (!strcmp(argv[2], "interface")) K = CXCursor_ObjCInterfaceDecl;
     else if (!strcmp(argv[2], "protocol")) K = CXCursor_ObjCProtocolDecl;





More information about the cfe-commits mailing list