diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index ddf393d46e21..60480d98bebe 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -5223,6 +5223,10 @@ public: //// ActOnCXXThis - Parse 'this' pointer. ExprResult ActOnCXXThis(SourceLocation loc); + /// Build a CXXThisExpr and mark it referenced in the current context. + Expr *BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit); + void MarkThisReferenced(CXXThisExpr *This); + /// Try to retrieve the type of the 'this' pointer. /// /// \returns The type of 'this', if possible. Otherwise, returns a NULL type. diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 455a71bd0ac0..e3286e8943f2 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1298,10 +1298,20 @@ ExprResult Sema::ActOnCXXThis(SourceLocation Loc) { /// which the function is called. QualType ThisTy = getCurrentThisType(); - if (ThisTy.isNull()) return Diag(Loc, diag::err_invalid_this_use); + if (ThisTy.isNull()) + return Diag(Loc, diag::err_invalid_this_use); + return BuildCXXThisExpr(Loc, ThisTy, /*isImplicit=*/false); +} - CheckCXXThisCapture(Loc); - return new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/false); +Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type, + bool IsImplicit) { + auto *This = new (Context) CXXThisExpr(Loc, Type, IsImplicit); + MarkThisReferenced(This); + return This; +} + +void Sema::MarkThisReferenced(CXXThisExpr *This) { + CheckCXXThisCapture(This->getExprLoc()); } bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) { diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index b07bba5584bd..3d7b8db2f671 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -1092,8 +1092,7 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, SourceLocation Loc = R.getNameLoc(); if (SS.getRange().isValid()) Loc = SS.getRange().getBegin(); - CheckCXXThisCapture(Loc); - BaseExpr = new (Context) CXXThisExpr(Loc, BaseExprType,/*isImplicit=*/true); + BaseExpr = BuildCXXThisExpr(Loc, BaseExprType, /*isImplicit=*/true); } // Check the use of this member. @@ -1836,8 +1835,7 @@ Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS, SourceLocation Loc = R.getNameLoc(); if (SS.getRange().isValid()) Loc = SS.getRange().getBegin(); - CheckCXXThisCapture(Loc); - baseExpr = new (Context) CXXThisExpr(loc, ThisTy, /*isImplicit=*/true); + baseExpr = BuildCXXThisExpr(loc, ThisTy, /*isImplicit=*/true); } return BuildMemberReferenceExpr(baseExpr, ThisTy, diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index eadc01e5efb6..e5cbd1d0a81c 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -13910,10 +13910,8 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, SourceLocation Loc = MemExpr->getMemberLoc(); if (MemExpr->getQualifier()) Loc = MemExpr->getQualifierLoc().getBeginLoc(); - CheckCXXThisCapture(Loc); - Base = new (Context) CXXThisExpr(Loc, - MemExpr->getBaseType(), - /*isImplicit=*/true); + Base = + BuildCXXThisExpr(Loc, MemExpr->getBaseType(), /*isImplicit=*/true); } } else Base = MemExpr->getBase(); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index c653fb1d6e2c..b5114eeef301 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2697,8 +2697,7 @@ public: ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc, QualType ThisType, bool isImplicit) { - getSema().CheckCXXThisCapture(ThisLoc); - return new (getSema().Context) CXXThisExpr(ThisLoc, ThisType, isImplicit); + return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit); } /// Build a new C++ throw expression. @@ -10355,8 +10354,9 @@ TreeTransform::TransformCXXThisExpr(CXXThisExpr *E) { QualType T = getSema().getCurrentThisType(); if (!getDerived().AlwaysRebuild() && T == E->getType()) { - // Make sure that we capture 'this'. - getSema().CheckCXXThisCapture(E->getBeginLoc()); + // Mark it referenced in the new context regardless. + // FIXME: this is a bit instantiation-specific. + getSema().MarkThisReferenced(E); return E; }