summaryrefslogtreecommitdiffstats
path: root/lib/Index/ResolveLocation.cpp
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2009-11-04 15:04:32 +0000
committerrdivacky <rdivacky@FreeBSD.org>2009-11-04 15:04:32 +0000
commitb6d5e15aae202f157c6cd63da8fa4b089e7b31e9 (patch)
tree59e0e47a9831dcf0e21e547927c8ebb7e113bfd1 /lib/Index/ResolveLocation.cpp
parent5563df30b9c8d1fe87a54baae0d6bd86642563f4 (diff)
downloadFreeBSD-src-b6d5e15aae202f157c6cd63da8fa4b089e7b31e9.zip
FreeBSD-src-b6d5e15aae202f157c6cd63da8fa4b089e7b31e9.tar.gz
Update clang to r86025.
Diffstat (limited to 'lib/Index/ResolveLocation.cpp')
-rw-r--r--lib/Index/ResolveLocation.cpp79
1 files changed, 71 insertions, 8 deletions
diff --git a/lib/Index/ResolveLocation.cpp b/lib/Index/ResolveLocation.cpp
index 8edd634..73b584b 100644
--- a/lib/Index/ResolveLocation.cpp
+++ b/lib/Index/ResolveLocation.cpp
@@ -45,6 +45,9 @@ protected:
if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
if (ContainsLocation(DD->getDeclaratorInfo()))
return ContainsLoc;
+ if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
+ if (ContainsLocation(TD->getTypeDeclaratorInfo()))
+ return ContainsLoc;
return CheckRange(D->getSourceRange());
}
@@ -57,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;
}
@@ -69,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.
@@ -89,6 +92,7 @@ public:
StmtLocResolver(ASTContext &ctx, SourceLocation loc, Decl *parent)
: LocResolverBase(ctx, loc), Parent(parent) {}
+ ASTLocation VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node);
ASTLocation VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node);
ASTLocation VisitDeclStmt(DeclStmt *Node);
ASTLocation VisitStmt(Stmt *Node);
@@ -109,6 +113,7 @@ public:
ASTLocation VisitVarDecl(VarDecl *D);
ASTLocation VisitFunctionDecl(FunctionDecl *D);
ASTLocation VisitObjCMethodDecl(ObjCMethodDecl *D);
+ ASTLocation VisitTypedefDecl(TypedefDecl *D);
ASTLocation VisitDecl(Decl *D);
};
@@ -132,6 +137,25 @@ public:
} // anonymous namespace
ASTLocation
+StmtLocResolver::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
+ assert(ContainsLocation(Node) &&
+ "Should visit only after verifying that loc is in range");
+
+ if (Node->isArgumentType()) {
+ DeclaratorInfo *DInfo = Node->getArgumentTypeInfo();
+ if (ContainsLocation(DInfo))
+ return ResolveInDeclarator(Parent, Node, DInfo);
+ } else {
+ Expr *SubNode = Node->getArgumentExpr();
+ if (ContainsLocation(SubNode))
+ return Visit(SubNode);
+ }
+
+ return ASTLocation(Parent, Node);
+}
+
+
+ASTLocation
StmtLocResolver::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
assert(ContainsLocation(Node) &&
"Should visit only after verifying that loc is in range");
@@ -278,6 +302,16 @@ ASTLocation DeclLocResolver::VisitDeclaratorDecl(DeclaratorDecl *D) {
return ASTLocation(D);
}
+ASTLocation DeclLocResolver::VisitTypedefDecl(TypedefDecl *D) {
+ assert(ContainsLocation(D) &&
+ "Should visit only after verifying that loc is in range");
+
+ if (ContainsLocation(D->getTypeDeclaratorInfo()))
+ return ResolveInDeclarator(D, /*Stmt=*/0, D->getTypeDeclaratorInfo());
+
+ return ASTLocation(D);
+}
+
ASTLocation DeclLocResolver::VisitVarDecl(VarDecl *D) {
assert(ContainsLocation(D) &&
"Should visit only after verifying that loc is in range");
@@ -529,11 +563,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());
}
OpenPOWER on IntegriCloud