From e842bd16cef2546439042cd66411c5636b1e25fb Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Sat, 18 Jul 2009 00:33:52 +0000 Subject: [PATCH] Resolve a location that is inside an ObjCMethodDecl. llvm-svn: 76272 --- clang/lib/Index/ResolveLocation.cpp | 59 ++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/clang/lib/Index/ResolveLocation.cpp b/clang/lib/Index/ResolveLocation.cpp index dcf765409745..72781c324c78 100644 --- a/clang/lib/Index/ResolveLocation.cpp +++ b/clang/lib/Index/ResolveLocation.cpp @@ -72,13 +72,14 @@ public: class VISIBILITY_HIDDEN StmtLocResolver : public LocResolverBase, public StmtVisitor { - Decl *Parent; + Decl * const Parent; public: StmtLocResolver(ASTContext &ctx, SourceLocation loc, Decl *parent) : LocResolverBase(ctx, loc), Parent(parent) {} ASTLocation VisitDeclStmt(DeclStmt *Node); + ASTLocation VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node); ASTLocation VisitStmt(Stmt *Node); }; @@ -95,6 +96,7 @@ public: ASTLocation VisitTranslationUnitDecl(TranslationUnitDecl *TU); ASTLocation VisitVarDecl(VarDecl *D); ASTLocation VisitFunctionDecl(FunctionDecl *D); + ASTLocation VisitObjCMethodDecl(ObjCMethodDecl *D); ASTLocation VisitDecl(Decl *D); }; @@ -117,6 +119,12 @@ ASTLocation StmtLocResolver::VisitDeclStmt(DeclStmt *Node) { return ASTLocation(Parent, Node); } +ASTLocation StmtLocResolver::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { + assert(ContainsLocation(Node) && + "Should visit only after verifying that loc is in range"); + return ASTLocation(Parent, Node); +} + ASTLocation StmtLocResolver::VisitStmt(Stmt *Node) { assert(ContainsLocation(Node) && "Should visit only after verifying that loc is in range"); @@ -215,6 +223,55 @@ ASTLocation DeclLocResolver::VisitVarDecl(VarDecl *D) { return ASTLocation(D); } +ASTLocation DeclLocResolver::VisitObjCMethodDecl(ObjCMethodDecl *D) { + assert(ContainsLocation(D) && + "Should visit only after verifying that loc is in range"); + + // First, search through the parameters of the method. + for (ObjCMethodDecl::param_iterator + I = D->param_begin(), E = D->param_end(); I != E; ++I) { + RangePos RP = CheckRange(*I); + if (RP == AfterLoc) + return ASTLocation(D); + if (RP == ContainsLoc) + return Visit(*I); + } + + // We didn't find the location in the parameters and we didn't get passed it. + + if (!D->getBody()) + return ASTLocation(D); + + // Second, search through the declarations that are part of the method. + // If we find he location there, we won't have to search through its body. + + for (DeclContext::decl_iterator + I = D->decls_begin(), E = D->decls_end(); I != E; ++I) { + if (isa(*I)) + continue; // We already searched through the parameters. + + RangePos RP = CheckRange(*I); + if (RP == AfterLoc) + break; + if (RP == ContainsLoc) + return Visit(*I); + } + + // We didn't find a declaration that corresponds to the source location. + + // Finally, search through the body of the method. + Stmt *Body = D->getBody(); + assert(Body && "Expected definition"); + assert(!isBeforeLocation(Body) && + "This method is supposed to contain the loc"); + if (isAfterLocation(Body)) + return ASTLocation(D); + + // The body contains the location. + assert(ContainsLocation(Body)); + return StmtLocResolver(Ctx, Loc, D).Visit(Body); +} + ASTLocation DeclLocResolver::VisitDecl(Decl *D) { assert(ContainsLocation(D) && "Should visit only after verifying that loc is in range");