1 //===--- EnterExpressionEvaluationContext.h ---------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_CLANG_SEMA_ENTEREXPRESSIONEVALUATIONCONTEXT_H
10 #define LLVM_CLANG_SEMA_ENTEREXPRESSIONEVALUATIONCONTEXT_H
11 
12 #include "clang/Sema/Sema.h"
13 
14 namespace clang {
15 
16 class Decl;
17 
18 /// RAII object that enters a new expression evaluation context.
19 class EnterExpressionEvaluationContext {
20   Sema &Actions;
21   bool Entered = true;
22 
23 public:
24   EnterExpressionEvaluationContext(
25       Sema &Actions, Sema::ExpressionEvaluationContext NewContext,
26       Decl *LambdaContextDecl = nullptr,
27       Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext =
28           Sema::ExpressionEvaluationContextRecord::EK_Other,
29       bool ShouldEnter = true)
30       : Actions(Actions), Entered(ShouldEnter) {
31     if (Entered)
32       Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl,
33                                               ExprContext);
34   }
35   EnterExpressionEvaluationContext(
36       Sema &Actions, Sema::ExpressionEvaluationContext NewContext,
37       Sema::ReuseLambdaContextDecl_t,
38       Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext =
39           Sema::ExpressionEvaluationContextRecord::EK_Other)
40       : Actions(Actions) {
41     Actions.PushExpressionEvaluationContext(
42         NewContext, Sema::ReuseLambdaContextDecl, ExprContext);
43   }
44 
45   enum InitListTag { InitList };
46   EnterExpressionEvaluationContext(Sema &Actions, InitListTag,
47                                    bool ShouldEnter = true)
48       : Actions(Actions), Entered(false) {
49     // In C++11 onwards, narrowing checks are performed on the contents of
50     // braced-init-lists, even when they occur within unevaluated operands.
51     // Therefore we still need to instantiate constexpr functions used in such
52     // a context.
53     if (ShouldEnter && Actions.isUnevaluatedContext() &&
54         Actions.getLangOpts().CPlusPlus11) {
55       Actions.PushExpressionEvaluationContext(
56           Sema::ExpressionEvaluationContext::UnevaluatedList);
57       Entered = true;
58     }
59   }
60 
61   ~EnterExpressionEvaluationContext() {
62     if (Entered)
63       Actions.PopExpressionEvaluationContext();
64   }
65 };
66 
67 } // namespace clang
68 
69 #endif
70