Make it possible to compute the type of 'this' without capturing

it. Refactoring to be used in a moment.

llvm-svn: 142360
This commit is contained in:
Douglas Gregor 2011-10-18 16:47:30 +00:00
parent 35c7f98734
commit 09deffa067
3 changed files with 16 additions and 11 deletions

View File

@ -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);

View File

@ -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<BlockScopeInfo>(FunctionScopes[idx])->CapturesCXXThis = true;
for (unsigned idx = FunctionScopes.size() - 1;
NumBlocks; --idx, --NumBlocks)
cast<BlockScopeInfo>(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));

View File

@ -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