Add an "implicit" bit to CXXThisExpr, so that we can track
implicitness without losing track of the (logical or actual) location
where "this" would occur in the source.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92958 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 730375e..216e2e6 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -565,7 +565,8 @@
             IsDerivedFrom(ThisType, AnonFieldType)) {
           // Our base object expression is "this".
           BaseObjectExpr = new (Context) CXXThisExpr(Loc,
-                                                     MD->getThisType(Context));
+                                                     MD->getThisType(Context),
+                                                     /*isImplicit=*/true);
           BaseObjectIsPointer = true;
         }
       } else {
@@ -1366,7 +1367,10 @@
   QualType ThisType = cast<CXXMethodDecl>(CurContext)->getThisType(Context);
   Expr *This = 0; // null signifies implicit access
   if (IsKnownInstance) {
-    This = new (Context) CXXThisExpr(SourceLocation(), ThisType);
+    SourceLocation Loc = R.getNameLoc();
+    if (SS.getRange().isValid())
+      Loc = SS.getRange().getBegin();
+    This = new (Context) CXXThisExpr(Loc, ThisType, /*isImplicit=*/true);
   }
 
   return BuildMemberReferenceExpr(ExprArg(*this, This), ThisType,
@@ -2541,7 +2545,10 @@
     if (!IsInstanceMember(MemberDecl))
       return BuildDeclarationNameExpr(SS, R.getNameLoc(), MemberDecl);
 
-    BaseExpr = new (Context) CXXThisExpr(SourceLocation(), BaseExprType);
+    SourceLocation Loc = R.getNameLoc();
+    if (SS.getRange().isValid())
+      Loc = SS.getRange().getBegin();
+    BaseExpr = new (Context) CXXThisExpr(Loc, BaseExprType,/*isImplicit=*/true);
   }
 
   bool ShouldCheckUse = true;
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 130b6e8..fa1a62b 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -179,7 +179,8 @@
   if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext))
     if (MD->isInstance())
       return Owned(new (Context) CXXThisExpr(ThisLoc,
-                                             MD->getThisType(Context)));
+                                             MD->getThisType(Context),
+                                             /*isImplicit=*/false));
 
   return ExprError(Diag(ThisLoc, diag::err_invalid_this_use));
 }
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index d2bd4ee..423657e 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -6064,9 +6064,14 @@
                                    MemExpr->getMemberLoc(),
                                    Fn->getType(),
                                    TemplateArgs);
-      } else
-        Base = new (Context) CXXThisExpr(SourceLocation(),
-                                         MemExpr->getBaseType());
+      } else {
+        SourceLocation Loc = MemExpr->getMemberLoc();
+        if (MemExpr->getQualifier())
+          Loc = MemExpr->getQualifierRange().getBegin();
+        Base = new (Context) CXXThisExpr(Loc,
+                                         MemExpr->getBaseType(),
+                                         /*isImplicit=*/true);
+      }
     } else
       Base = MemExpr->getBase()->Retain();
 
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 208c885..e966daa 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -1344,9 +1344,11 @@
   /// semantic analysis. Subclasses may override this routine to provide
   /// different behavior.
   OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
-                                      QualType ThisType) {
+                                      QualType ThisType,
+                                      bool isImplicit) {
     return getSema().Owned(
-                      new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
+                      new (getSema().Context) CXXThisExpr(ThisLoc, ThisType,
+                                                          isImplicit));
   }
 
   /// \brief Build a new C++ throw expression.
@@ -4386,7 +4388,7 @@
       T == E->getType())
     return SemaRef.Owned(E->Retain());
 
-  return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
+  return getDerived().RebuildCXXThisExpr(E->getLocStart(), T, E->isImplicit());
 }
 
 template<typename Derived>