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