summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorLeonard Chan <leonardchan@google.com>2018-12-06 00:10:36 +0000
committerLeonard Chan <leonardchan@google.com>2018-12-06 00:10:36 +0000
commitbf5fe2dbba0899bee4323f5eaa075acc43a18e2e (patch)
tree7da64aa7b23b86b938988140fce137b5b7d2c663 /clang/lib/Sema/SemaDecl.cpp
parentd4e7d0749bfde91d1f86a1f3adb02079c55a830f (diff)
downloadbcm5719-llvm-bf5fe2dbba0899bee4323f5eaa075acc43a18e2e.tar.gz
bcm5719-llvm-bf5fe2dbba0899bee4323f5eaa075acc43a18e2e.zip
[Sema] Push and Pop Expression Evaluation Context Records at the start and end of function definitions
This patch creates a new context for every function definition we enter. Currently we do not push and pop on these, usually working off of the global context record added in the Sema constructor, which never gets popped. Differential Revision: https://reviews.llvm.org/D54014 llvm-svn: 348434
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index da6d414a42e..083089fc994 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12828,6 +12828,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
// Parsing the function declaration failed in some way. Push on a fake scope
// anyway so we can try to parse the function body.
PushFunctionScope();
+ PushExpressionEvaluationContext(ExprEvalContexts.back().Context);
return D;
}
@@ -12838,6 +12839,11 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
else
FD = cast<FunctionDecl>(D);
+ // Do not push if it is a lambda because one is already pushed when building
+ // the lambda in ActOnStartOfLambdaDefinition().
+ if (!isLambdaCallOperator(FD))
+ PushExpressionEvaluationContext(ExprEvalContexts.back().Context);
+
// Check for defining attributes before the check for redefinition.
if (const auto *Attr = FD->getAttr<AliasAttr>()) {
Diag(Attr->getLocation(), diag::err_alias_is_definition) << FD << 0;
@@ -13046,6 +13052,21 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) {
return ActOnFinishFunctionBody(D, BodyArg, false);
}
+/// RAII object that pops an ExpressionEvaluationContext when exiting a function
+/// body.
+class ExitFunctionBodyRAII {
+public:
+ ExitFunctionBodyRAII(Sema &S, bool IsLambda) : S(S), IsLambda(IsLambda) {}
+ ~ExitFunctionBodyRAII() {
+ if (!IsLambda)
+ S.PopExpressionEvaluationContext();
+ }
+
+private:
+ Sema &S;
+ bool IsLambda = false;
+};
+
Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
bool IsInstantiation) {
FunctionDecl *FD = dcl ? dcl->getAsFunction() : nullptr;
@@ -13056,6 +13077,11 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
if (getLangOpts().CoroutinesTS && getCurFunction()->isCoroutine())
CheckCompletedCoroutineBody(FD, Body);
+ // Do not call PopExpressionEvaluationContext() if it is a lambda because one
+ // is already popped when finishing the lambda in BuildLambdaExpr(). This is
+ // meant to pop the context added in ActOnStartOfFunctionDef().
+ ExitFunctionBodyRAII ExitRAII(*this, isLambdaCallOperator(FD));
+
if (FD) {
FD->setBody(Body);
FD->setWillHaveBody(false);
OpenPOWER on IntegriCloud