aboutsummaryrefslogtreecommitdiff
path: root/lib/Index/ResolveLocation.cpp
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2009-10-28 20:44:47 +0000
committerSteve Naroff <snaroff@apple.com>2009-10-28 20:44:47 +0000
commitf96b524306ccfa623235d375deee79637bd38f29 (patch)
treea29834d962c52bbdcce2c5851ab73f0089a928c5 /lib/Index/ResolveLocation.cpp
parent7d0f5c9ca12d1bae19c3c19500b3b0cf5aedbc29 (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.cpp45
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());
}