diff options
author | Steve Naroff <snaroff@apple.com> | 2009-10-28 20:44:47 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2009-10-28 20:44:47 +0000 |
commit | f96b524306ccfa623235d375deee79637bd38f29 (patch) | |
tree | a29834d962c52bbdcce2c5851ab73f0089a928c5 /lib/Index/ResolveLocation.cpp | |
parent | 7d0f5c9ca12d1bae19c3c19500b3b0cf5aedbc29 (diff) |
Remove _clang_initCXLookupHint() and _clang_getCursorWithHint(). Related to <rdar://problem/7310688>.
Localize the optimization to ResolveLocationInAST(). The last valid AST location is now stored with ASTUnit. There still isn't optimal, however it's an improvement (with a much cleaner API). Having the client manage an "hint" is error prone and complex.
I wanted to land the major changes before finishing up the optimizations.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85425 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Index/ResolveLocation.cpp')
-rw-r--r-- | lib/Index/ResolveLocation.cpp | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/lib/Index/ResolveLocation.cpp b/lib/Index/ResolveLocation.cpp index 4e992f752b..ec8c1dcb38 100644 --- a/lib/Index/ResolveLocation.cpp +++ b/lib/Index/ResolveLocation.cpp @@ -60,11 +60,6 @@ protected: } template <typename T> - bool ContainsLocation(T Node) { - return CheckRange(Node) == ContainsLoc; - } - - template <typename T> bool isAfterLocation(T Node) { return CheckRange(Node) == AfterLoc; } @@ -72,6 +67,11 @@ protected: public: LocResolverBase(ASTContext &ctx, SourceLocation loc) : Ctx(ctx), Loc(loc) {} + + template <typename T> + bool ContainsLocation(T Node) { + return CheckRange(Node) == ContainsLoc; + } #ifndef NDEBUG /// \brief Debugging output. @@ -543,11 +543,40 @@ void LocResolverBase::print(Stmt *Node) { /// \brief Returns the AST node that a source location points to. /// ASTLocation idx::ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc, - Decl *RelativeToDecl) { + ASTLocation *LastLoc) { if (Loc.isInvalid()) return ASTLocation(); - if (RelativeToDecl) - return DeclLocResolver(Ctx, Loc).Visit(RelativeToDecl); + if (LastLoc && LastLoc->isValid()) { + DeclContext *DC = 0; + + if (Decl *Dcl = LastLoc->dyn_AsDecl()) { + DC = Dcl->getDeclContext(); + } else if (LastLoc->isStmt()) { + Decl *Parent = LastLoc->getParentDecl(); + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Parent)) + DC = FD; + else { + // This is needed to handle statements within an initializer. + // Example: + // void func() { long double fabsf = __builtin_fabsl(__x); } + // In this case, the 'parent' of __builtin_fabsl is fabsf. + DC = Parent->getDeclContext(); + } + } else { // We have 'N_NamedRef' or 'N_Type' + DC = LastLoc->getParentDecl()->getDeclContext(); + } + assert(DC && "Missing DeclContext"); + + FunctionDecl *FD = dyn_cast<FunctionDecl>(DC); + DeclLocResolver DLocResolver(Ctx, Loc); + + if (FD && FD->isThisDeclarationADefinition() && + DLocResolver.ContainsLocation(FD)) { + return DLocResolver.VisitFunctionDecl(FD); + } + // Fall through and try the slow path... + // FIXME: Optimize more cases. + } return DeclLocResolver(Ctx, Loc).Visit(Ctx.getTranslationUnitDecl()); } |