Note location of operators caused the circularity.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83153 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index dafafba..4e9d7de 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1979,6 +1979,7 @@
   if (OpKind == tok::arrow) {
     // The set of types we've considered so far.
     llvm::SmallPtrSet<CanQualType,8> CTypes;
+    llvm::SmallVector<SourceLocation, 8> Locations;
     CTypes.insert(Context.getCanonicalType(BaseType));
     
     while (BaseType->isRecordType()) {
@@ -1986,11 +1987,14 @@
       BaseExpr = (Expr*)Base.get();
       if (BaseExpr == NULL)
         return ExprError();
+      if (CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(BaseExpr))
+        Locations.push_back(OpCall->getOperatorLoc());
       BaseType = BaseExpr->getType();
       CanQualType CBaseType = Context.getCanonicalType(BaseType);
       if (!CTypes.insert(CBaseType)) {
-        // TODO: note the chain of conversions
         Diag(OpLoc, diag::err_operator_arrow_circular);
+        for (unsigned i = 0; i < Locations.size(); i++)
+          Diag(Locations[i], diag::note_declared_at);
         return ExprError();
       }
     }
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 9e76617..aaf76b1 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -5065,7 +5065,7 @@
   UsualUnaryConversions(FnExpr);
   Base = new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr, &Base, 1,
                                  Method->getResultType().getNonReferenceType(),
-                                 OpLoc);
+                                 Method->getLocation());
   return Owned(Base);
 }
 
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index 31da58d..8471f3c 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -216,7 +216,7 @@
 
 
 struct AX { 
-  AX& operator ->();
+  AX& operator ->();	 // expected-note {{declared at}}
   int b;
 }; 
 
@@ -226,14 +226,14 @@
 }
 
 struct CircA {
-  struct CircB& operator->();
+  struct CircB& operator->(); // expected-note {{declared at}}
   int val;
 };
 struct CircB {
-  struct CircC& operator->();
+  struct CircC& operator->(); // expected-note {{declared at}}
 };
 struct CircC {
-  struct CircA& operator->();
+  struct CircA& operator->(); // expected-note {{declared at}}
 };
 
 void circ() {