xref: /freebsd/contrib/llvm-project/clang/lib/AST/ByteCode/State.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1*700637cbSDimitry Andric //===--- State.h - State chain for the VM and AST Walker --------*- C++ -*-===//
2*700637cbSDimitry Andric //
3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric //
7*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
8*700637cbSDimitry Andric //
9*700637cbSDimitry Andric // Defines the base class of the interpreter and evaluator state.
10*700637cbSDimitry Andric //
11*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
12*700637cbSDimitry Andric 
13*700637cbSDimitry Andric #ifndef LLVM_CLANG_AST_INTERP_STATE_H
14*700637cbSDimitry Andric #define LLVM_CLANG_AST_INTERP_STATE_H
15*700637cbSDimitry Andric 
16*700637cbSDimitry Andric #include "clang/AST/ASTDiagnostic.h"
17*700637cbSDimitry Andric #include "clang/AST/Expr.h"
18*700637cbSDimitry Andric 
19*700637cbSDimitry Andric namespace clang {
20*700637cbSDimitry Andric class OptionalDiagnostic;
21*700637cbSDimitry Andric 
22*700637cbSDimitry Andric /// Kinds of access we can perform on an object, for diagnostics. Note that
23*700637cbSDimitry Andric /// we consider a member function call to be a kind of access, even though
24*700637cbSDimitry Andric /// it is not formally an access of the object, because it has (largely) the
25*700637cbSDimitry Andric /// same set of semantic restrictions.
26*700637cbSDimitry Andric enum AccessKinds {
27*700637cbSDimitry Andric   AK_Read,
28*700637cbSDimitry Andric   AK_ReadObjectRepresentation,
29*700637cbSDimitry Andric   AK_Assign,
30*700637cbSDimitry Andric   AK_Increment,
31*700637cbSDimitry Andric   AK_Decrement,
32*700637cbSDimitry Andric   AK_MemberCall,
33*700637cbSDimitry Andric   AK_DynamicCast,
34*700637cbSDimitry Andric   AK_TypeId,
35*700637cbSDimitry Andric   AK_Construct,
36*700637cbSDimitry Andric   AK_Destroy,
37*700637cbSDimitry Andric   AK_IsWithinLifetime,
38*700637cbSDimitry Andric };
39*700637cbSDimitry Andric 
40*700637cbSDimitry Andric /// The order of this enum is important for diagnostics.
41*700637cbSDimitry Andric enum CheckSubobjectKind {
42*700637cbSDimitry Andric   CSK_Base,
43*700637cbSDimitry Andric   CSK_Derived,
44*700637cbSDimitry Andric   CSK_Field,
45*700637cbSDimitry Andric   CSK_ArrayToPointer,
46*700637cbSDimitry Andric   CSK_ArrayIndex,
47*700637cbSDimitry Andric   CSK_Real,
48*700637cbSDimitry Andric   CSK_Imag,
49*700637cbSDimitry Andric   CSK_VectorElement
50*700637cbSDimitry Andric };
51*700637cbSDimitry Andric 
52*700637cbSDimitry Andric namespace interp {
53*700637cbSDimitry Andric class Frame;
54*700637cbSDimitry Andric class SourceInfo;
55*700637cbSDimitry Andric 
56*700637cbSDimitry Andric /// Interface for the VM to interact with the AST walker's context.
57*700637cbSDimitry Andric class State {
58*700637cbSDimitry Andric public:
59*700637cbSDimitry Andric   virtual ~State();
60*700637cbSDimitry Andric 
61*700637cbSDimitry Andric   virtual bool checkingForUndefinedBehavior() const = 0;
62*700637cbSDimitry Andric   virtual bool checkingPotentialConstantExpression() const = 0;
63*700637cbSDimitry Andric   virtual bool noteUndefinedBehavior() = 0;
64*700637cbSDimitry Andric   virtual bool keepEvaluatingAfterFailure() const = 0;
65*700637cbSDimitry Andric   virtual bool keepEvaluatingAfterSideEffect() const = 0;
66*700637cbSDimitry Andric   virtual Frame *getCurrentFrame() = 0;
67*700637cbSDimitry Andric   virtual const Frame *getBottomFrame() const = 0;
68*700637cbSDimitry Andric   virtual bool hasActiveDiagnostic() = 0;
69*700637cbSDimitry Andric   virtual void setActiveDiagnostic(bool Flag) = 0;
70*700637cbSDimitry Andric   virtual void setFoldFailureDiagnostic(bool Flag) = 0;
71*700637cbSDimitry Andric   virtual Expr::EvalStatus &getEvalStatus() const = 0;
72*700637cbSDimitry Andric   virtual ASTContext &getASTContext() const = 0;
73*700637cbSDimitry Andric   virtual bool hasPriorDiagnostic() = 0;
74*700637cbSDimitry Andric   virtual unsigned getCallStackDepth() = 0;
75*700637cbSDimitry Andric   virtual bool noteSideEffect() = 0;
76*700637cbSDimitry Andric 
77*700637cbSDimitry Andric public:
78*700637cbSDimitry Andric   State() = default;
79*700637cbSDimitry Andric   /// Diagnose that the evaluation could not be folded (FF => FoldFailure)
80*700637cbSDimitry Andric   OptionalDiagnostic
81*700637cbSDimitry Andric   FFDiag(SourceLocation Loc,
82*700637cbSDimitry Andric          diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
83*700637cbSDimitry Andric          unsigned ExtraNotes = 0);
84*700637cbSDimitry Andric 
85*700637cbSDimitry Andric   OptionalDiagnostic
86*700637cbSDimitry Andric   FFDiag(const Expr *E,
87*700637cbSDimitry Andric          diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
88*700637cbSDimitry Andric          unsigned ExtraNotes = 0);
89*700637cbSDimitry Andric 
90*700637cbSDimitry Andric   OptionalDiagnostic
91*700637cbSDimitry Andric   FFDiag(const SourceInfo &SI,
92*700637cbSDimitry Andric          diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
93*700637cbSDimitry Andric          unsigned ExtraNotes = 0);
94*700637cbSDimitry Andric 
95*700637cbSDimitry Andric   /// Diagnose that the evaluation does not produce a C++11 core constant
96*700637cbSDimitry Andric   /// expression.
97*700637cbSDimitry Andric   ///
98*700637cbSDimitry Andric   /// FIXME: Stop evaluating if we're in EM_ConstantExpression or
99*700637cbSDimitry Andric   /// EM_PotentialConstantExpression mode and we produce one of these.
100*700637cbSDimitry Andric   OptionalDiagnostic
101*700637cbSDimitry Andric   CCEDiag(SourceLocation Loc,
102*700637cbSDimitry Andric           diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
103*700637cbSDimitry Andric           unsigned ExtraNotes = 0);
104*700637cbSDimitry Andric 
105*700637cbSDimitry Andric   OptionalDiagnostic
106*700637cbSDimitry Andric   CCEDiag(const Expr *E,
107*700637cbSDimitry Andric           diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
108*700637cbSDimitry Andric           unsigned ExtraNotes = 0);
109*700637cbSDimitry Andric 
110*700637cbSDimitry Andric   OptionalDiagnostic
111*700637cbSDimitry Andric   CCEDiag(const SourceInfo &SI,
112*700637cbSDimitry Andric           diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
113*700637cbSDimitry Andric           unsigned ExtraNotes = 0);
114*700637cbSDimitry Andric 
115*700637cbSDimitry Andric   /// Add a note to a prior diagnostic.
116*700637cbSDimitry Andric   OptionalDiagnostic Note(SourceLocation Loc, diag::kind DiagId);
117*700637cbSDimitry Andric 
118*700637cbSDimitry Andric   /// Add a stack of notes to a prior diagnostic.
119*700637cbSDimitry Andric   void addNotes(ArrayRef<PartialDiagnosticAt> Diags);
120*700637cbSDimitry Andric 
121*700637cbSDimitry Andric   /// Directly reports a diagnostic message.
122*700637cbSDimitry Andric   DiagnosticBuilder report(SourceLocation Loc, diag::kind DiagId);
123*700637cbSDimitry Andric 
124*700637cbSDimitry Andric   const LangOptions &getLangOpts() const;
125*700637cbSDimitry Andric 
126*700637cbSDimitry Andric   /// Whether or not we're in a context where the front end requires a
127*700637cbSDimitry Andric   /// constant value.
128*700637cbSDimitry Andric   bool InConstantContext = false;
129*700637cbSDimitry Andric 
130*700637cbSDimitry Andric private:
131*700637cbSDimitry Andric   void addCallStack(unsigned Limit);
132*700637cbSDimitry Andric 
133*700637cbSDimitry Andric   PartialDiagnostic &addDiag(SourceLocation Loc, diag::kind DiagId);
134*700637cbSDimitry Andric 
135*700637cbSDimitry Andric   OptionalDiagnostic diag(SourceLocation Loc, diag::kind DiagId,
136*700637cbSDimitry Andric                           unsigned ExtraNotes, bool IsCCEDiag);
137*700637cbSDimitry Andric };
138*700637cbSDimitry Andric 
139*700637cbSDimitry Andric } // namespace interp
140*700637cbSDimitry Andric } // namespace clang
141*700637cbSDimitry Andric 
142*700637cbSDimitry Andric #endif
143