diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2009-07-18 00:33:52 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2009-07-18 00:33:52 +0000 |
commit | 0df134715d75c62422502af0f5610885a5a4f472 (patch) | |
tree | 6d7e0b1d68a0640e6dba57c28653d9183e35b281 /lib/Index/ResolveLocation.cpp | |
parent | cc1ccb74c8675a6379d9363433e843a8d78ccf5c (diff) |
Resolve a location that is inside an ObjCMethodDecl.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76272 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Index/ResolveLocation.cpp')
-rw-r--r-- | lib/Index/ResolveLocation.cpp | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/lib/Index/ResolveLocation.cpp b/lib/Index/ResolveLocation.cpp index dcf7654097..72781c324c 100644 --- a/lib/Index/ResolveLocation.cpp +++ b/lib/Index/ResolveLocation.cpp @@ -72,13 +72,14 @@ public: class VISIBILITY_HIDDEN StmtLocResolver : public LocResolverBase, public StmtVisitor<StmtLocResolver, ASTLocation > { - 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<ParmVarDecl>(*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"); |