From: Argyrios Kyrtzidis Date: Fri, 31 Jul 2009 19:02:11 +0000 (+0000) Subject: For a CXXOperatorCallExpr, fix the order that StmtLocResolver uses to check subexpres... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8c4dc1ffd20a8fe90a90c7f471cd9842b981078e;p=clang For a CXXOperatorCallExpr, fix the order that StmtLocResolver uses to check subexpressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77713 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Index/ResolveLocation.cpp b/lib/Index/ResolveLocation.cpp index ba8134fb88..ce8512ddf3 100644 --- a/lib/Index/ResolveLocation.cpp +++ b/lib/Index/ResolveLocation.cpp @@ -78,6 +78,7 @@ public: StmtLocResolver(ASTContext &ctx, SourceLocation loc, Decl *parent) : LocResolverBase(ctx, loc), Parent(parent) {} + ASTLocation VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node); ASTLocation VisitDeclStmt(DeclStmt *Node); ASTLocation VisitStmt(Stmt *Node); }; @@ -101,6 +102,35 @@ public: } // anonymous namespace +ASTLocation +StmtLocResolver::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) { + assert(ContainsLocation(Node) && + "Should visit only after verifying that loc is in range"); + + if (Node->getNumArgs() == 1) + // Unary operator. Let normal child traversal handle it. + return VisitCallExpr(Node); + + assert(Node->getNumArgs() == 2 && + "Wrong args for the C++ operator call expr ?"); + + llvm::SmallVector Nodes; + // Binary operator. Check in order of 1-left arg, 2-callee, 3-right arg. + Nodes.push_back(Node->getArg(0)); + Nodes.push_back(Node->getCallee()); + Nodes.push_back(Node->getArg(1)); + + for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { + RangePos RP = CheckRange(Nodes[i]); + if (RP == AfterLoc) + break; + if (RP == ContainsLoc) + return Visit(Nodes[i]); + } + + return ASTLocation(Parent, Node); +} + ASTLocation StmtLocResolver::VisitDeclStmt(DeclStmt *Node) { assert(ContainsLocation(Node) && "Should visit only after verifying that loc is in range"); @@ -125,6 +155,9 @@ ASTLocation StmtLocResolver::VisitStmt(Stmt *Node) { // Search the child statements. for (Stmt::child_iterator I = Node->child_begin(), E = Node->child_end(); I != E; ++I) { + if (*I == NULL) + continue; + RangePos RP = CheckRange(*I); if (RP == AfterLoc) break; diff --git a/test/Index/cxx-operator-overload.cpp b/test/Index/cxx-operator-overload.cpp index 8f12f1661f..6a913d670c 100644 --- a/test/Index/cxx-operator-overload.cpp +++ b/test/Index/cxx-operator-overload.cpp @@ -23,4 +23,6 @@ Cls Cls::operator +(const Cls &RHS) { while (1) {} } // RUN: index-test %t.ast -point-at %s:5:15 -print-refs > %t && // RUN: cat %t | count 2 && // RUN: grep ':10:17,' %t && -// RUN: grep ':10:22,' %t +// RUN: grep ':10:22,' %t && + +// RUN: index-test %t.ast -point-at %s:10:14 | grep 'DeclRefExpr x1'