aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-02-21 19:11:17 +0000
committerDouglas Gregor <dgregor@apple.com>2012-02-21 19:11:17 +0000
commitf4b7de1cef3007cc0479775638198287384d9af1 (patch)
tree58f71d3db597c7a0951820a96177157b77488bae /lib/Sema/SemaExpr.cpp
parentf18a87b1ce1be5ccc3b6b3dbd4f15374710e237b (diff)
Improve our handling of lambda expressions that occur within default
arguments. There are two aspects to this: - Make sure that when marking the declarations referenced in a default argument, we don't try to mark local variables, both because it's a waste of time and because the semantics are wrong: we're not in a place where we could capture these variables again even if it did make sense. - When a lambda expression occurs in a default argument of a function template, make sure that the corresponding closure type is considered dependent, so that it will get properly instantiated. The second bit is a bit of a hack; to fix it properly, we may have to rearchitect our handling of default arguments, parsing them only after creating the function definition. However, I'd like to separate that work from the lambdas work. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151076 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp26
1 files changed, 22 insertions, 4 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 1008a3ab43..be3fa6c0dc 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3146,7 +3146,8 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
// We already type-checked the argument, so we know it works.
// Just mark all of the declarations in this potentially-evaluated expression
// as being "referenced".
- MarkDeclarationsReferencedInExpr(Param->getDefaultArg());
+ MarkDeclarationsReferencedInExpr(Param->getDefaultArg(),
+ /*SkipLocalVariables=*/true);
return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param));
}
@@ -10145,13 +10146,22 @@ namespace {
/// potentially-evaluated subexpressions as "referenced".
class EvaluatedExprMarker : public EvaluatedExprVisitor<EvaluatedExprMarker> {
Sema &S;
+ bool SkipLocalVariables;
public:
typedef EvaluatedExprVisitor<EvaluatedExprMarker> Inherited;
- explicit EvaluatedExprMarker(Sema &S) : Inherited(S.Context), S(S) { }
+ EvaluatedExprMarker(Sema &S, bool SkipLocalVariables)
+ : Inherited(S.Context), S(S), SkipLocalVariables(SkipLocalVariables) { }
void VisitDeclRefExpr(DeclRefExpr *E) {
+ // If we were asked not to visit local variables, don't.
+ if (SkipLocalVariables) {
+ if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl()))
+ if (VD->hasLocalStorage())
+ return;
+ }
+
S.MarkDeclRefReferenced(E);
}
@@ -10193,6 +10203,10 @@ namespace {
}
void VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
+ // If we were asked not to visit local variables, don't.
+ if (SkipLocalVariables && E->getDecl()->hasLocalStorage())
+ return;
+
S.MarkBlockDeclRefReferenced(E);
}
@@ -10211,8 +10225,12 @@ namespace {
/// \brief Mark any declarations that appear within this expression or any
/// potentially-evaluated subexpressions as "referenced".
-void Sema::MarkDeclarationsReferencedInExpr(Expr *E) {
- EvaluatedExprMarker(*this).Visit(E);
+///
+/// \param SkipLocalVariables If true, don't mark local variables as
+/// 'referenced'.
+void Sema::MarkDeclarationsReferencedInExpr(Expr *E,
+ bool SkipLocalVariables) {
+ EvaluatedExprMarker(*this, SkipLocalVariables).Visit(E);
}
/// \brief Emit a diagnostic that describes an effect on the run-time behavior