From: Steve Naroff Date: Wed, 23 Sep 2009 17:52:52 +0000 (+0000) Subject: More work to enable more exhaustive testing of the indexing API. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4ade6d6eae934f796ca43c81a5aa185e456dde9b;p=clang More work to enable more exhaustive testing of the indexing API. Next step: Add actual some test cases:-) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82636 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index d13c08c394..24f3c54ba5 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -192,7 +192,15 @@ unsigned clang_getCursorColumn(CXCursor); const char *clang_getCursorSource(CXCursor); const char *clang_getCursorSpelling(CXCursor); -const char *clang_getCursorKindSpelling(enum CXCursorKind Kind); /* for debug */ +/* for debug/testing */ +const char *clang_getCursorKindSpelling(enum CXCursorKind Kind); +void clang_getDefinitionSpellingAndExtent(CXCursor, + const char **startBuf, + const char **endBuf, + unsigned *startLine, + unsigned *startColumn, + unsigned *endLine, + unsigned *endColumn); /* * If CXCursorKind == Cursor_Reference, then this will return the referenced diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index d0c1ea5c67..37f2d8695c 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -28,6 +28,21 @@ using namespace idx; namespace { +static enum CXCursorKind TranslateDeclRefExpr(DeclRefExpr *DRE) +{ + NamedDecl *D = DRE->getDecl(); + if (isa(D)) + return CXCursor_VarRef; + else if (isa(D)) + return CXCursor_FunctionRef; + else if (isa(D)) + return CXCursor_EnumConstantRef; + else + return CXCursor_NotImplemented; +} + +#if 0 +// Will be useful one day. class CRefVisitor : public StmtVisitor { CXDecl CDecl; CXDeclIterator Callback; @@ -48,13 +63,7 @@ public: 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); + Call(TranslateDeclRefExpr(Node), Node); } void VisitMemberExpr(MemberExpr *Node) { Call(CXCursor_MemberRef, Node); @@ -66,6 +75,7 @@ public: Call(CXCursor_ObjCIvarRef, Node); } }; +#endif // Translation Unit Visitor. class TUVisitor : public DeclVisitor { @@ -208,9 +218,12 @@ public: void VisitFunctionDecl(FunctionDecl *ND) { if (ND->isThisDeclarationADefinition()) { VisitDeclContext(dyn_cast(ND)); - +#if 0 + // Not currently needed. + CompoundStmt *Body = dyn_cast(ND->getBody()); CRefVisitor RVisit(CDecl, Callback, CData); - RVisit.Visit(ND->getBody()); + RVisit.Visit(Body); +#endif } } void VisitObjCMethodDecl(ObjCMethodDecl *ND) { @@ -476,7 +489,18 @@ CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name, ASTLocation ALoc = ResolveLocationInAST(CXXUnit->getASTContext(), SLoc); Decl *Dcl = ALoc.getDecl(); - if (Dcl) { + Stmt *Stm = ALoc.getStmt(); + if (Dcl) { + if (Stm) { + if (DeclRefExpr *DRE = dyn_cast(Stm)) { + CXCursor C = { TranslateDeclRefExpr(DRE), Dcl, Stm }; + return C; + } else if (ObjCMessageExpr *MExp = dyn_cast(Stm)) { + CXCursor C = { CXCursor_ObjCSelectorRef, Dcl, MExp }; + return C; + } + // Fall through...treat as a decl, not a ref. + } CXCursor C = { TranslateKind(Dcl), Dcl, 0 }; return C; } @@ -613,4 +637,27 @@ const char *clang_getCursorSource(CXCursor C) return SourceMgr.getBufferName(SLoc); } +void clang_getDefinitionSpellingAndExtent(CXCursor C, + const char **startBuf, + const char **endBuf, + unsigned *startLine, + unsigned *startColumn, + unsigned *endLine, + unsigned *endColumn) +{ + assert(C.decl && "CXCursor has null decl"); + NamedDecl *ND = static_cast(C.decl); + FunctionDecl *FD = dyn_cast(ND); + CompoundStmt *Body = dyn_cast(FD->getBody()); + + SourceManager &SM = FD->getASTContext().getSourceManager(); + *startBuf = SM.getCharacterData(Body->getLBracLoc()); + *endBuf = SM.getCharacterData(Body->getRBracLoc()); + *startLine = SM.getSpellingLineNumber(Body->getLBracLoc()); + *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc()); + *endLine = SM.getSpellingLineNumber(Body->getRBracLoc()); + *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc()); +} + + } // end extern "C" diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports index a06d7bc558..1b804b1819 100644 --- a/tools/CIndex/CIndex.exports +++ b/tools/CIndex/CIndex.exports @@ -22,4 +22,5 @@ _clang_isDefinition _clang_isInvalid _clang_getCursorSpelling _clang_getCursorKindSpelling +_clang_getDefinitionSpellingAndExtent _clang_getTranslationUnitSpelling diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index e7043c1482..b403863992 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -32,6 +32,32 @@ static void TranslationUnitVisitor(CXTranslationUnit Unit, CXCursor Cursor, clang_getCursorLine(Cursor), clang_getCursorColumn(Cursor)); + if (Cursor.kind == CXCursor_FunctionDefn) { + const char *startBuf, *endBuf; + unsigned startLine, startColumn, endLine, endColumn; + clang_getDefinitionSpellingAndExtent(Cursor, &startBuf, &endBuf, + &startLine, &startColumn, + &endLine, &endColumn); + /* Probe the entire body, looking for "refs". */ + unsigned curLine = startLine, curColumn = startColumn; + while (startBuf <= endBuf) { + if (*startBuf == '\n') { + startBuf++; + curLine++; + curColumn = 1; + } + CXCursor Ref = clang_getCursor(Unit, clang_getCursorSource(Cursor), + curLine, curColumn); + if (Ref.kind != CXCursor_FunctionDecl) { + PrintCursor(Ref); + printf("(Context: %s", clang_getDeclSpelling(Ref.decl)); + printf(" Source: %s (%d:%d))\n", clang_getCursorSource(Ref), + curLine, curColumn); + } + startBuf++; + curColumn++; + } + } clang_loadDeclaration(Cursor.decl, DeclVisitor, 0); } }