Start issuing callback for references (add some predicates, refactor some code).

llvm-svn: 80810
This commit is contained in:
Steve Naroff 2009-09-02 18:26:48 +00:00
parent b7cb99bf50
commit 80a766bf50
4 changed files with 83 additions and 24 deletions

View File

@ -71,11 +71,11 @@ enum CXCursorKind {
/* References */
CXCursor_FirstRef = 40,
CXCursor_ObjCClassRef = 41,
CXCursor_ObjCProtocolRef = 42,
CXCursor_ObjCMessageRef = 43,
CXCursor_ObjCSelectorRef = 44,
CXCursor_LastRef = 44
CXCursor_ObjCSuperClassRef = 40,
CXCursor_ObjCProtocolRef = 41,
CXCursor_ObjCMessageRef = 42,
CXCursor_ObjCSelectorRef = 43,
CXCursor_LastRef = 43
};
/* A cursor into the CXTranslationUnit. */
@ -167,11 +167,15 @@ CXCursor clang_getCursor(CXTranslationUnit, const char *source_name,
enum CXCursorKind clang_getCursorKind(CXCursor);
unsigned clang_isDeclaration(enum CXCursorKind);
unsigned clang_isReference(enum CXCursorKind);
unsigned clang_isDefinition(enum CXCursorKind);
unsigned clang_getCursorLine(CXCursor);
unsigned clang_getCursorColumn(CXCursor);
const char *clang_getCursorSource(CXCursor);
const char *clang_getKindSpelling(enum CXCursorKind Kind);
const char *clang_getCursorSpelling(CXCursor);
const char *clang_getCursorKindSpelling(enum CXCursorKind Kind); /* for debug */
/*
* If CXCursorKind == Cursor_Reference, then this will return the referenced declaration.

View File

@ -103,6 +103,10 @@ public:
CDecl(C), Callback(cback), CData(D) {}
void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
// Issue callbacks for super class and protocols.
if (D->getSuperClass())
Call(CXCursor_ObjCSuperClassRef, D);
VisitDeclContext(dyn_cast<DeclContext>(D));
}
void VisitTagDecl(TagDecl *D) {
@ -241,7 +245,26 @@ const char *clang_getDeclSpelling(CXDecl AnonDecl)
else
return "";
}
const char *clang_getKindSpelling(enum CXCursorKind Kind)
const char *clang_getCursorSpelling(CXCursor C)
{
assert(C.decl && "CXCursor has null decl");
NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
if (clang_isReference(C.kind)) {
switch (C.kind) {
case CXCursor_ObjCSuperClassRef:
ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND);
assert(OID && "clang_getCursorLine(): Missing interface decl");
return OID->getSuperClass()->getIdentifier()->getName();
default:
return "<not implemented>";
}
}
return clang_getDeclSpelling(C.decl);
}
const char *clang_getCursorKindSpelling(enum CXCursorKind Kind)
{
switch (Kind) {
case CXCursor_FunctionDecl: return "FunctionDecl";
@ -266,6 +289,7 @@ const char *clang_getKindSpelling(enum CXCursorKind Kind)
case CXCursor_ObjCClassMethodDefn: return "ObjCClassMethodDefn";
case CXCursor_ObjCClassDefn: return "ObjCClassDefn";
case CXCursor_ObjCCategoryDefn: return "ObjCCategoryDefn";
case CXCursor_ObjCSuperClassRef: return "ObjCSuperClassRef";
default: return "<not implemented>";
}
}
@ -289,37 +313,65 @@ unsigned clang_isDeclaration(enum CXCursorKind K)
return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
}
unsigned clang_isReference(enum CXCursorKind K)
{
return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
}
unsigned clang_isDefinition(enum CXCursorKind K)
{
return K >= CXCursor_FirstDefn && K <= CXCursor_LastDefn;
}
static SourceLocation getLocationFromCursor(CXCursor C,
SourceManager &SourceMgr,
NamedDecl *ND) {
SourceLocation SLoc;
if (clang_isReference(C.kind)) {
switch (C.kind) {
case CXCursor_ObjCSuperClassRef:
ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND);
assert(OID && "clang_getCursorLine(): Missing interface decl");
SLoc = OID->getSuperClassLoc();
break;
default:
break;
}
} else { // We have a declaration or a definition.
SLoc = ND->getLocation();
if (SLoc.isInvalid())
return SourceLocation();
SLoc = SourceMgr.getSpellingLoc(SLoc); // handles macro instantiations.
}
return SLoc;
}
unsigned clang_getCursorLine(CXCursor C)
{
assert(C.decl && "CXCursor has null decl");
NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
SourceLocation SLoc = ND->getLocation();
if (SLoc.isInvalid())
return 0;
SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
SLoc = SourceMgr.getSpellingLoc(SLoc); // handles macro instantiations.
SourceLocation SLoc = getLocationFromCursor(C, SourceMgr, ND);
return SourceMgr.getSpellingLineNumber(SLoc);
}
unsigned clang_getCursorColumn(CXCursor C)
{
assert(C.decl && "CXCursor has null decl");
NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
SourceLocation SLoc = ND->getLocation();
if (SLoc.isInvalid())
return 0;
SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
SLoc = SourceMgr.getSpellingLoc(SLoc); // handles macro instantiations.
SourceLocation SLoc = getLocationFromCursor(C, SourceMgr, ND);
return SourceMgr.getSpellingColumnNumber(SLoc);
}
const char *clang_getCursorSource(CXCursor C)
{
assert(C.decl && "CXCursor has null decl");
NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
SourceLocation SLoc = ND->getLocation();
if (SLoc.isInvalid())
return "<invalid source location>";
SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
SLoc = SourceMgr.getSpellingLoc(SLoc); // handles macro instantiations.
SourceLocation SLoc = getLocationFromCursor(C, SourceMgr, ND);
return SourceMgr.getBufferName(SLoc);
}

View File

@ -15,4 +15,7 @@ _clang_loadDeclaration
_clang_loadTranslationUnit
_clang_createTranslationUnit
_clang_isDeclaration
_clang_getKindSpelling
_clang_isReference
_clang_isDefinition
_clang_getCursorSpelling
_clang_getCursorKindSpelling

View File

@ -6,8 +6,8 @@
static void DeclVisitor(CXDecl Dcl, CXCursor Cursor, CXClientData Filter)
{
if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) {
printf("%s => %s", clang_getKindSpelling(Cursor.kind),
clang_getDeclSpelling(Cursor.decl));
printf("%s => %s", clang_getCursorKindSpelling(Cursor.kind),
clang_getCursorSpelling(Cursor));
printf(" (%s,%d:%d)\n", clang_getCursorSource(Cursor),
clang_getCursorLine(Cursor),
clang_getCursorColumn(Cursor));
@ -17,8 +17,8 @@ static void TranslationUnitVisitor(CXTranslationUnit Unit, CXCursor Cursor,
CXClientData Filter)
{
if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) {
printf("%s => %s", clang_getKindSpelling(Cursor.kind),
clang_getDeclSpelling(Cursor.decl));
printf("%s => %s", clang_getCursorKindSpelling(Cursor.kind),
clang_getCursorSpelling(Cursor));
printf(" (%s,%d:%d)\n", clang_getCursorSource(Cursor),
clang_getCursorLine(Cursor),
clang_getCursorColumn(Cursor));