From 341350ee62abd1ad818e1e3d926cd718960e439b Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 18 Oct 2011 16:47:30 +0000 Subject: [PATCH] Make it possible to compute the type of 'this' without capturing it. Refactoring to be used in a moment. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142360 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/Sema.h | 9 ++++++--- lib/Sema/SemaExprCXX.cpp | 14 ++++++++------ lib/Sema/SemaExprMember.cpp | 4 ++-- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 1b1e07abbf..d6649bd70b 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -3019,9 +3019,12 @@ public: //// ActOnCXXThis - Parse 'this' pointer. ExprResult ActOnCXXThis(SourceLocation loc); - /// getAndCaptureCurrentThisType - Try to capture a 'this' pointer. Returns - /// the type of the 'this' pointer, or a null type if this is not possible. - QualType getAndCaptureCurrentThisType(); + /// \brief Try to retrieve the type of the 'this' pointer. + /// + /// \param Capture If true, capture 'this' in this context. + /// + /// \returns The type of 'this', if possible. Otherwise, returns a NULL type. + QualType getCurrentThisType(bool Capture = true); /// ActOnCXXBoolLiteral - Parse {true,false} literals. ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 3300444a1c..4cd2af1c4e 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -636,7 +636,7 @@ ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E, return Owned(E); } -QualType Sema::getAndCaptureCurrentThisType() { +QualType Sema::getCurrentThisType(bool Capture) { // Ignore block scopes: we can capture through them. // Ignore nested enum scopes: we'll diagnose non-constant expressions // where they're invalid, and other uses are legitimate. @@ -666,11 +666,13 @@ QualType Sema::getAndCaptureCurrentThisType() { ThisTy = Context.getPointerType(Context.getRecordType(RD)); } + if (!Capture || ThisTy.isNull()) + return ThisTy; + // Mark that we're closing on 'this' in all the block scopes we ignored. - if (!ThisTy.isNull()) - for (unsigned idx = FunctionScopes.size() - 1; - NumBlocks; --idx, --NumBlocks) - cast(FunctionScopes[idx])->CapturesCXXThis = true; + for (unsigned idx = FunctionScopes.size() - 1; + NumBlocks; --idx, --NumBlocks) + cast(FunctionScopes[idx])->CapturesCXXThis = true; return ThisTy; } @@ -680,7 +682,7 @@ ExprResult Sema::ActOnCXXThis(SourceLocation Loc) { /// is a non-lvalue expression whose value is the address of the object for /// which the function is called. - QualType ThisTy = getAndCaptureCurrentThisType(); + QualType ThisTy = getCurrentThisType(); if (ThisTy.isNull()) return Diag(Loc, diag::err_invalid_this_use); return Owned(new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/false)); diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 32a5194cec..16c17fb890 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -697,7 +697,7 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, // We've found a member of an anonymous struct/union that is // inside a non-anonymous struct/union, so in a well-formed // program our base object expression is "this". - QualType ThisTy = getAndCaptureCurrentThisType(); + QualType ThisTy = getCurrentThisType(); if (ThisTy.isNull()) { Diag(loc, diag::err_invalid_member_use_in_static_method) << indirectField->getDeclName(); @@ -1569,7 +1569,7 @@ Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS, // If this is known to be an instance access, go ahead and build an // implicit 'this' expression now. // 'this' expression now. - QualType ThisTy = getAndCaptureCurrentThisType(); + QualType ThisTy = getCurrentThisType(); assert(!ThisTy.isNull() && "didn't correctly pre-flight capture of 'this'"); Expr *baseExpr = 0; // null signifies implicit access -- 2.40.0