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