From: Steve Naroff Date: Tue, 22 Sep 2009 19:25:29 +0000 (+0000) Subject: - Implement support for various types of "refs" (initially to help test clang_getCurs... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fb5704295c6137685a7b90b92cd6b958028740c8;p=clang - Implement support for various types of "refs" (initially to help test clang_getCursor()). - Add missing prototypes for dispose functions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82564 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index d74b28c49a..d13c08c394 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -34,6 +34,7 @@ typedef void *CXIndex; /* An indexing instance. */ typedef void *CXTranslationUnit; /* A translation unit instance. */ typedef void *CXDecl; /* A specific declaration within a translation unit. */ +typedef void *CXStmt; /* A specific statement within a function/method */ /* Cursors represent declarations, definitions, and references. */ enum CXCursorKind { @@ -68,13 +69,18 @@ enum CXCursorKind { CXCursor_LastDefn = 36, /* References */ - CXCursor_FirstRef = 40, + CXCursor_FirstRef = 40, /* Decl references */ CXCursor_ObjCSuperClassRef = 40, CXCursor_ObjCProtocolRef = 41, - CXCursor_ObjCMessageRef = 42, - CXCursor_ObjCSelectorRef = 43, - CXCursor_ObjCClassRef = 44, - CXCursor_LastRef = 44, + CXCursor_ObjCClassRef = 42, + + CXCursor_ObjCSelectorRef = 43, /* Expression references */ + CXCursor_ObjCIvarRef = 44, + CXCursor_VarRef = 45, + CXCursor_FunctionRef = 46, + CXCursor_EnumConstantRef = 47, + CXCursor_MemberRef = 48, + CXCursor_LastRef = 48, /* Error conditions */ CXCursor_FirstInvalid = 70, @@ -85,23 +91,25 @@ enum CXCursorKind { }; /* A cursor into the CXTranslationUnit. */ + typedef struct { enum CXCursorKind kind; CXDecl decl; - - /* FIXME: Handle references. */ + CXStmt stmt; /* expression reference */ } CXCursor; /* A unique token for looking up "visible" CXDecls from a CXTranslationUnit. */ typedef void *CXEntity; CXIndex clang_createIndex(); +void clang_disposeIndex(CXIndex); const char *clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit); CXTranslationUnit clang_createTranslationUnit( CXIndex, const char *ast_filename ); +void clang_disposeTranslationUnit(CXTranslationUnit); /* Usage: clang_loadTranslationUnit(). Will load the toplevel declarations diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index de50b80079..d0c1ea5c67 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -17,6 +17,7 @@ #include "clang/Index/ASTLocation.h" #include "clang/Index/Utils.h" #include "clang/AST/DeclVisitor.h" +#include "clang/AST/StmtVisitor.h" #include "clang/AST/Decl.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" @@ -27,6 +28,45 @@ using namespace idx; namespace { +class CRefVisitor : public StmtVisitor { + CXDecl CDecl; + CXDeclIterator Callback; + CXClientData CData; + + void Call(enum CXCursorKind CK, Stmt *SRef) { + CXCursor C = { CK, CDecl, SRef }; + Callback(CDecl, C, CData); + } + +public: + CRefVisitor(CXDecl C, CXDeclIterator cback, CXClientData D) : + CDecl(C), Callback(cback), CData(D) {} + + void VisitStmt(Stmt *S) { + for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end(); + C != CEnd; ++C) + Visit(*C); + } + void VisitDeclRefExpr(DeclRefExpr *Node) { + NamedDecl *D = Node->getDecl(); + if (isa(D)) + Call(CXCursor_VarRef, Node); + else if (isa(D)) + Call(CXCursor_FunctionRef, Node); + else if (isa(D)) + Call(CXCursor_EnumConstantRef, Node); + } + void VisitMemberExpr(MemberExpr *Node) { + Call(CXCursor_MemberRef, Node); + } + void VisitObjCMessageExpr(ObjCMessageExpr *Node) { + Call(CXCursor_ObjCSelectorRef, Node); + } + void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { + Call(CXCursor_ObjCIvarRef, Node); + } +}; + // Translation Unit Visitor. class TUVisitor : public DeclVisitor { CXTranslationUnit TUnit; @@ -34,7 +74,7 @@ class TUVisitor : public DeclVisitor { CXClientData CData; void Call(enum CXCursorKind CK, NamedDecl *ND) { - CXCursor C = { CK, ND }; + CXCursor C = { CK, ND, 0 }; Callback(TUnit, C, CData); } public: @@ -103,7 +143,7 @@ class CDeclVisitor : public DeclVisitor { // Disable the callback when the context is equal to the visiting decl. if (CDecl == ND && !clang_isReference(CK)) return; - CXCursor C = { CK, ND }; + CXCursor C = { CK, ND, 0 }; Callback(CDecl, C, CData); } public: @@ -168,6 +208,9 @@ public: void VisitFunctionDecl(FunctionDecl *ND) { if (ND->isThisDeclarationADefinition()) { VisitDeclContext(dyn_cast(ND)); + + CRefVisitor RVisit(CDecl, Callback, CData); + RVisit.Visit(ND->getBody()); } } void VisitObjCMethodDecl(ObjCMethodDecl *ND) { @@ -323,6 +366,22 @@ const char *clang_getCursorSpelling(CXCursor C) assert(OID && "clang_getCursorLine(): Missing protocol decl"); return OID->getIdentifier()->getName(); } + case CXCursor_ObjCSelectorRef: + { + ObjCMessageExpr *OME = dyn_cast( + static_cast(C.stmt)); + assert(OME && "clang_getCursorLine(): Missing message expr"); + return OME->getSelector().getAsString().c_str(); + } + case CXCursor_VarRef: + case CXCursor_FunctionRef: + case CXCursor_EnumConstantRef: + { + DeclRefExpr *DRE = dyn_cast( + static_cast(C.stmt)); + assert(DRE && "clang_getCursorLine(): Missing decl ref expr"); + return DRE->getDecl()->getIdentifier()->getName(); + } default: return ""; } @@ -358,6 +417,13 @@ const char *clang_getCursorKindSpelling(enum CXCursorKind Kind) case CXCursor_ObjCSuperClassRef: return "ObjCSuperClassRef"; case CXCursor_ObjCProtocolRef: return "ObjCProtocolRef"; case CXCursor_ObjCClassRef: return "ObjCClassRef"; + case CXCursor_ObjCSelectorRef: return "ObjCSelectorRef"; + + case CXCursor_VarRef: return "VarRef"; + case CXCursor_FunctionRef: return "FunctionRef"; + case CXCursor_EnumConstantRef: return "EnumConstantRef"; + case CXCursor_MemberRef: return "MemberRef"; + case CXCursor_InvalidFile: return "InvalidFile"; case CXCursor_NoDeclFound: return "NoDeclFound"; case CXCursor_NotImplemented: return "NotImplemented"; @@ -376,6 +442,8 @@ static enum CXCursorKind TranslateKind(Decl *D) { case Decl::Var: return CXCursor_VarDecl; case Decl::ParmVar: return CXCursor_ParmDecl; case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl; + case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl; + case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl; case Decl::ObjCMethod: { ObjCMethodDecl *MD = dyn_cast(D); if (MD->isInstanceMethod()) @@ -399,7 +467,7 @@ CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name, const FileEntry *File = FMgr.getFile(source_name, source_name+strlen(source_name)); if (!File) { - CXCursor C = { CXCursor_InvalidFile, 0 }; + CXCursor C = { CXCursor_InvalidFile, 0, 0 }; return C; } SourceLocation SLoc = @@ -409,10 +477,10 @@ CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name, Decl *Dcl = ALoc.getDecl(); if (Dcl) { - CXCursor C = { TranslateKind(Dcl), Dcl }; + CXCursor C = { TranslateKind(Dcl), Dcl, 0 }; return C; } - CXCursor C = { CXCursor_NoDeclFound, 0 }; + CXCursor C = { CXCursor_NoDeclFound, 0, 0 }; return C; } @@ -421,7 +489,7 @@ CXCursor clang_getCursorFromDecl(CXDecl AnonDecl) assert(AnonDecl && "Passed null CXDecl"); NamedDecl *ND = static_cast(AnonDecl); - CXCursor C = { TranslateKind(ND), ND }; + CXCursor C = { TranslateKind(ND), ND, 0 }; return C; } @@ -472,6 +540,22 @@ static SourceLocation getLocationFromCursor(CXCursor C, assert(OID && "clang_getCursorLine(): Missing protocol decl"); return OID->getLocation(); } + case CXCursor_ObjCSelectorRef: + { + ObjCMessageExpr *OME = dyn_cast( + static_cast(C.stmt)); + assert(OME && "clang_getCursorLine(): Missing message expr"); + return OME->getLeftLoc(); /* FIXME: should be a range */ + } + case CXCursor_VarRef: + case CXCursor_FunctionRef: + case CXCursor_EnumConstantRef: + { + DeclRefExpr *DRE = dyn_cast( + static_cast(C.stmt)); + assert(DRE && "clang_getCursorLine(): Missing decl ref expr"); + return DRE->getLocation(); + } default: return SourceLocation(); }