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