summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-02-03 08:15:49 +0000
committerJohn McCall <rjmccall@apple.com>2011-02-03 08:15:49 +0000
commitf3a8860ee1031a56ba05d9a33840e6a6a9dd3854 (patch)
treed44e28d27fc630f1256ffc033d9c8221cdf97b1a /clang/lib/Sema/SemaExprCXX.cpp
parent981ca313d7f5ffe701836ff3dc2c13e99e106e77 (diff)
downloadbcm5719-llvm-f3a8860ee1031a56ba05d9a33840e6a6a9dd3854.tar.gz
bcm5719-llvm-f3a8860ee1031a56ba05d9a33840e6a6a9dd3854.zip
More capturing of 'this': implicit member expressions. Getting that
right for anonymous struct/union members led to me discovering some seemingly broken code in that area of Sema, which I fixed, partly by changing the representation of member pointer constants so that IndirectFieldDecls aren't expanded. This led to assorted cleanups with member pointers in CodeGen, and while I was doing that I saw some random other things to clean up. llvm-svn: 124785
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp34
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));
}
OpenPOWER on IntegriCloud