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