More work to enable more exhaustive testing of the indexing API.

Next step: Add actual some test cases:-)

llvm-svn: 82636
This commit is contained in:
Steve Naroff 2009-09-23 17:52:52 +00:00
parent e4e8181111
commit 76b8f13fcb
4 changed files with 93 additions and 11 deletions

View File

@ -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

View File

@ -28,6 +28,21 @@ using namespace idx;
namespace {
static enum CXCursorKind TranslateDeclRefExpr(DeclRefExpr *DRE)
{
NamedDecl *D = DRE->getDecl();
if (isa<VarDecl>(D))
return CXCursor_VarRef;
else if (isa<FunctionDecl>(D))
return CXCursor_FunctionRef;
else if (isa<EnumConstantDecl>(D))
return CXCursor_EnumConstantRef;
else
return CXCursor_NotImplemented;
}
#if 0
// Will be useful one day.
class CRefVisitor : public StmtVisitor<CRefVisitor> {
CXDecl CDecl;
CXDeclIterator Callback;
@ -48,13 +63,7 @@ public:
Visit(*C);
}
void VisitDeclRefExpr(DeclRefExpr *Node) {
NamedDecl *D = Node->getDecl();
if (isa<VarDecl>(D))
Call(CXCursor_VarRef, Node);
else if (isa<FunctionDecl>(D))
Call(CXCursor_FunctionRef, Node);
else if (isa<EnumConstantDecl>(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<TUVisitor> {
@ -208,9 +218,12 @@ public:
void VisitFunctionDecl(FunctionDecl *ND) {
if (ND->isThisDeclarationADefinition()) {
VisitDeclContext(dyn_cast<DeclContext>(ND));
#if 0
// Not currently needed.
CompoundStmt *Body = dyn_cast<CompoundStmt>(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();
Stmt *Stm = ALoc.getStmt();
if (Dcl) {
if (Stm) {
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Stm)) {
CXCursor C = { TranslateDeclRefExpr(DRE), Dcl, Stm };
return C;
} else if (ObjCMessageExpr *MExp = dyn_cast<ObjCMessageExpr>(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<NamedDecl *>(C.decl);
FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
CompoundStmt *Body = dyn_cast<CompoundStmt>(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"

View File

@ -22,4 +22,5 @@ _clang_isDefinition
_clang_isInvalid
_clang_getCursorSpelling
_clang_getCursorKindSpelling
_clang_getDefinitionSpellingAndExtent
_clang_getTranslationUnitSpelling

View File

@ -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);
}
}