зеркало из https://github.com/microsoft/clang-1.git
Teach the cursor visitor to walk statements and expressions, including
a few important subkinds. Now we're cookin' with gas! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94116 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
b5c775575b
Коммит
a59e390ed6
|
@ -87,3 +87,15 @@ int main (int argc, const char * argv[]) {
|
||||||
// CHECK: c-index-api-loadTU-test.m:49:13: VarDecl=d:49:13 (Definition) [Extent=49:13:49:13]
|
// CHECK: c-index-api-loadTU-test.m:49:13: VarDecl=d:49:13 (Definition) [Extent=49:13:49:13]
|
||||||
// CHECK: c-index-api-loadTU-test.m:49:2: TypeRef=id:0:0 [Extent=49:2:49:3]
|
// CHECK: c-index-api-loadTU-test.m:49:2: TypeRef=id:0:0 [Extent=49:2:49:3]
|
||||||
// CHECK: c-index-api-loadTU-test.m:49:6: ObjCProtocolRef=Proto:24:1 [Extent=49:6:49:10]
|
// CHECK: c-index-api-loadTU-test.m:49:6: ObjCProtocolRef=Proto:24:1 [Extent=49:6:49:10]
|
||||||
|
// CHECK: c-index-api-loadTU-test.m:50:2: DeclRefExpr=d:49:13 [Extent=50:2:50:2]
|
||||||
|
// CHECK: c-index-api-loadTU-test.m:50:6: DeclRefExpr=c:48:12 [Extent=50:6:50:6]
|
||||||
|
// CHECK: c-index-api-loadTU-test.m:51:2: ObjCMessageExpr=pMethod:25:1 [Extent=51:2:51:12]
|
||||||
|
// CHECK: c-index-api-loadTU-test.m:51:3: DeclRefExpr=d:49:13 [Extent=51:3:51:3]
|
||||||
|
// CHECK: c-index-api-loadTU-test.m:52:2: ObjCMessageExpr=catMethodWithFloat::20:1 [Extent=52:2:52:43]
|
||||||
|
// CHECK: c-index-api-loadTU-test.m:52:3: DeclRefExpr=bee:46:8 [Extent=52:3:52:5]
|
||||||
|
// CHECK: c-index-api-loadTU-test.m:52:26: ObjCMessageExpr=floatMethod:21:1 [Extent=52:26:52:42]
|
||||||
|
// CHECK: c-index-api-loadTU-test.m:52:27: DeclRefExpr=bee:46:8 [Extent=52:27:52:29]
|
||||||
|
// CHECK: c-index-api-loadTU-test.m:53:3: CallExpr=main:45:5 [Extent=53:3:53:36]
|
||||||
|
// CHECK: c-index-api-loadTU-test.m:53:3: DeclRefExpr=main:45:5 [Extent=53:3:53:6]
|
||||||
|
// CHECK: c-index-api-loadTU-test.m:53:8: DeclRefExpr=someEnum:42:3 [Extent=53:8:53:15]
|
||||||
|
// CHECK: c-index-api-loadTU-test.m:53:33: DeclRefExpr=bee:46:8 [Extent=53:33:53:35]
|
||||||
|
|
|
@ -142,7 +142,8 @@ namespace {
|
||||||
|
|
||||||
// Cursor visitor.
|
// Cursor visitor.
|
||||||
class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
|
class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
|
||||||
public TypeLocVisitor<CursorVisitor, bool>
|
public TypeLocVisitor<CursorVisitor, bool>,
|
||||||
|
public StmtVisitor<CursorVisitor, bool>
|
||||||
{
|
{
|
||||||
ASTUnit *TU;
|
ASTUnit *TU;
|
||||||
CXCursor Parent;
|
CXCursor Parent;
|
||||||
|
@ -157,6 +158,7 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
|
||||||
|
|
||||||
using DeclVisitor<CursorVisitor, bool>::Visit;
|
using DeclVisitor<CursorVisitor, bool>::Visit;
|
||||||
using TypeLocVisitor<CursorVisitor, bool>::Visit;
|
using TypeLocVisitor<CursorVisitor, bool>::Visit;
|
||||||
|
using StmtVisitor<CursorVisitor, bool>::Visit;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData,
|
CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData,
|
||||||
|
@ -178,6 +180,7 @@ public:
|
||||||
bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
|
bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
|
||||||
bool VisitDeclaratorDecl(DeclaratorDecl *DD);
|
bool VisitDeclaratorDecl(DeclaratorDecl *DD);
|
||||||
bool VisitFunctionDecl(FunctionDecl *ND);
|
bool VisitFunctionDecl(FunctionDecl *ND);
|
||||||
|
bool VisitObjCContainerDecl(ObjCContainerDecl *D);
|
||||||
bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
|
bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
|
||||||
bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
|
bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
|
||||||
bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
|
bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
|
||||||
|
@ -205,6 +208,10 @@ public:
|
||||||
// implemented
|
// implemented
|
||||||
bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
|
bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
|
||||||
bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
|
bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
|
||||||
|
|
||||||
|
// Statement visitors
|
||||||
|
bool VisitStmt(Stmt *S);
|
||||||
|
bool VisitDeclStmt(DeclStmt *S);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
@ -247,6 +254,11 @@ bool CursorVisitor::Visit(CXCursor Cursor) {
|
||||||
/// \returns true if the visitation should be aborted, false if it
|
/// \returns true if the visitation should be aborted, false if it
|
||||||
/// should continue.
|
/// should continue.
|
||||||
bool CursorVisitor::VisitChildren(CXCursor Cursor) {
|
bool CursorVisitor::VisitChildren(CXCursor Cursor) {
|
||||||
|
if (clang_isReference(Cursor.kind)) {
|
||||||
|
// By definition, references have no children.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Set the Parent field to Cursor, then back to its old value once we're
|
// Set the Parent field to Cursor, then back to its old value once we're
|
||||||
// done.
|
// done.
|
||||||
class SetParentRAII {
|
class SetParentRAII {
|
||||||
|
@ -276,6 +288,11 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
|
||||||
return Visit(D);
|
return Visit(D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clang_isStatement(Cursor.kind))
|
||||||
|
return Visit(getCursorStmt(Cursor));
|
||||||
|
if (clang_isExpression(Cursor.kind))
|
||||||
|
return Visit(getCursorExpr(Cursor));
|
||||||
|
|
||||||
if (clang_isTranslationUnit(Cursor.kind)) {
|
if (clang_isTranslationUnit(Cursor.kind)) {
|
||||||
ASTUnit *CXXUnit = getCursorASTUnit(Cursor);
|
ASTUnit *CXXUnit = getCursorASTUnit(Cursor);
|
||||||
if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls()) {
|
if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls()) {
|
||||||
|
@ -292,9 +309,8 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nothing to visit at the moment.
|
// Nothing to visit at the moment.
|
||||||
// FIXME: Traverse statements, declarations, etc. here.
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,21 +341,17 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
|
||||||
if (VisitDeclaratorDecl(ND))
|
if (VisitDeclaratorDecl(ND))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// FIXME: This is wrong. We want to visit the body as a statement.
|
if (ND->isThisDeclarationADefinition() &&
|
||||||
if (ND->isThisDeclarationADefinition()) {
|
Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
|
||||||
return VisitDeclContext(ND);
|
return true;
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Not currently needed.
|
|
||||||
CompoundStmt *Body = dyn_cast<CompoundStmt>(ND->getBody());
|
|
||||||
CRefVisitor RVisit(CDecl, Callback, CData);
|
|
||||||
RVisit.Visit(Body);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
|
||||||
|
return VisitDeclContext(D);
|
||||||
|
}
|
||||||
|
|
||||||
bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
|
bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
|
||||||
if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
|
if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
|
||||||
TU)))
|
TU)))
|
||||||
|
@ -351,7 +363,7 @@ bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
|
||||||
if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
|
if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return VisitDeclContext(ND);
|
return VisitObjCContainerDecl(ND);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
|
bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
|
||||||
|
@ -368,13 +380,23 @@ bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
|
||||||
if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
|
if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return VisitDeclContext(D);
|
return VisitObjCContainerDecl(D);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
|
bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
|
||||||
// FIXME: Wrong in the same way that VisitFunctionDecl is wrong.
|
// FIXME: We really need a TypeLoc covering Objective-C method declarations.
|
||||||
if (ND->getBody())
|
// At the moment, we don't have information about locations in the return
|
||||||
return VisitDeclContext(ND);
|
// type.
|
||||||
|
for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
|
||||||
|
PEnd = ND->param_end();
|
||||||
|
P != PEnd; ++P) {
|
||||||
|
if (Visit(MakeCXCursor(*P, TU)))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ND->isThisDeclarationADefinition() &&
|
||||||
|
Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -386,7 +408,7 @@ bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
|
||||||
if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
|
if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return VisitDeclContext(PID);
|
return VisitObjCContainerDecl(PID);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CursorVisitor::VisitTagDecl(TagDecl *D) {
|
bool CursorVisitor::VisitTagDecl(TagDecl *D) {
|
||||||
|
@ -517,9 +539,6 @@ bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
|
||||||
if (Visit(TL.getResultLoc()))
|
if (Visit(TL.getResultLoc()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// FIXME: For function definitions, this means that we'll end up
|
|
||||||
// visiting the parameters twice, because VisitFunctionDecl is
|
|
||||||
// walking the DeclContext.
|
|
||||||
for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
|
for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
|
||||||
if (Visit(MakeCXCursor(TL.getArg(I), TU)))
|
if (Visit(MakeCXCursor(TL.getArg(I), TU)))
|
||||||
return true;
|
return true;
|
||||||
|
@ -548,6 +567,26 @@ bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CursorVisitor::VisitStmt(Stmt *S) {
|
||||||
|
for (Stmt::child_iterator Child = S->child_begin(), ChildEnd = S->child_end();
|
||||||
|
Child != ChildEnd; ++Child) {
|
||||||
|
if (Visit(MakeCXCursor(*Child, StmtParent, TU)))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CursorVisitor::VisitDeclStmt(DeclStmt *S) {
|
||||||
|
for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
|
||||||
|
D != DEnd; ++D) {
|
||||||
|
if (Visit(MakeCXCursor(*D, TU)))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CXString CIndexer::createCXString(const char *String, bool DupString){
|
CXString CIndexer::createCXString(const char *String, bool DupString){
|
||||||
CXString Str;
|
CXString Str;
|
||||||
if (DupString) {
|
if (DupString) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче