]> granicus.if.org Git - clang/commitdiff
Add an "implicit" bit to CXXThisExpr, so that we can track
authorDouglas Gregor <dgregor@apple.com>
Thu, 7 Jan 2010 23:12:05 +0000 (23:12 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 7 Jan 2010 23:12:05 +0000 (23:12 +0000)
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

include/clang/AST/ExprCXX.h
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaOverload.cpp
lib/Sema/TreeTransform.h

index d0e21f576d75e98bee4003fd9b62f7632f7e4809..55d5108e6174ae0c8b591ed16a9a40eed1facbe0 100644 (file)
@@ -324,17 +324,21 @@ public:
 /// @endcode
 class CXXThisExpr : public Expr {
   SourceLocation Loc;
-
+  bool Implicit : 1;
+  
 public:
-  CXXThisExpr(SourceLocation L, QualType Type)
+  CXXThisExpr(SourceLocation L, QualType Type, bool isImplicit)
     : Expr(CXXThisExprClass, Type,
            // 'this' is type-dependent if the class type of the enclosing
            // member function is dependent (C++ [temp.dep.expr]p2)
            Type->isDependentType(), Type->isDependentType()),
-      Loc(L) { }
+      Loc(L), Implicit(isImplicit) { }
 
   virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
 
+  bool isImplicit() const { return Implicit; }
+  void setImplicit(bool I) { Implicit = I; }
+  
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXThisExprClass;
   }
index 730375e5cd34d0d78665162f8d19479436ee7af6..216e2e60980ac378480b4e67d7fb76330d089f69 100644 (file)
@@ -565,7 +565,8 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
             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 @@ Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS,
   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 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
     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;
index 130b6e857b7e165fc82e56b08d5a3d06a754cadd..fa1a62b14a73f54f5237af2ecb67ab57aa250ecb 100644 (file)
@@ -179,7 +179,8 @@ Action::OwningExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
   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));
 }
index d2bd4eea98f7861f092939ac5eadd348d22c1720..423657e3cd6f21f40824045b73dc3bcb21763726 100644 (file)
@@ -6064,9 +6064,14 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
                                    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();
 
index 208c8851e5965fd199faff3af1c6380fed4d98b1..e966daa9764e3083f51d589147338c43c530faa1 100644 (file)
@@ -1344,9 +1344,11 @@ public:
   /// 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 @@ TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
       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>