diff options
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 73e9778a742..81031a54eed 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -559,19 +559,22 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) { return false; } -ExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) { - /// C++ 9.3.2: In the body of a non-static member function, the keyword this - /// is a non-lvalue expression whose value is the address of the object for - /// which the function is called. - - // Ignore block scopes (but nothing else). +CXXMethodDecl *Sema::tryCaptureCXXThis() { + // 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. + // Don't ignore nested class scopes: you can't use 'this' in a local class. DeclContext *DC = CurContext; - while (isa<BlockDecl>(DC)) DC = cast<BlockDecl>(DC)->getDeclContext(); + while (true) { + if (isa<BlockDecl>(DC)) DC = cast<BlockDecl>(DC)->getDeclContext(); + else if (isa<EnumDecl>(DC)) DC = cast<EnumDecl>(DC)->getDeclContext(); + else break; + } - // If we're not an instance method, error out. + // If we're not in an instance method, error out. CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(DC); if (!method || !method->isInstance()) - return ExprError(Diag(ThisLoc, diag::err_invalid_this_use)); + return 0; // Mark that we're closing on 'this' in all the block scopes, if applicable. for (unsigned idx = FunctionScopes.size() - 1; @@ -579,7 +582,18 @@ ExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) { --idx) cast<BlockScopeInfo>(FunctionScopes[idx])->CapturesCXXThis = true; - return Owned(new (Context) CXXThisExpr(ThisLoc, method->getThisType(Context), + return method; +} + +ExprResult Sema::ActOnCXXThis(SourceLocation loc) { + /// C++ 9.3.2: In the body of a non-static member function, the keyword this + /// is a non-lvalue expression whose value is the address of the object for + /// which the function is called. + + CXXMethodDecl *method = tryCaptureCXXThis(); + if (!method) return Diag(loc, diag::err_invalid_this_use); + + return Owned(new (Context) CXXThisExpr(loc, method->getThisType(Context), /*isImplicit=*/false)); } |

