For a CXXOperatorCallExpr, fix the order that StmtLocResolver uses to check subexpres...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 31 Jul 2009 19:02:11 +0000 (19:02 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 31 Jul 2009 19:02:11 +0000 (19:02 +0000)
llvm-svn: 77713

clang/lib/Index/ResolveLocation.cpp
clang/test/Index/cxx-operator-overload.cpp

index ba8134f..ce8512d 100644 (file)
@@ -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<Expr *, 3> 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;
index 8f12f16..6a913d6 100644 (file)
@@ -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'