aboutsummaryrefslogtreecommitdiffstats
path: root/lib/AST/Interp/State.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Interp/State.h')
-rw-r--r--lib/AST/Interp/State.h133
1 files changed, 133 insertions, 0 deletions
diff --git a/lib/AST/Interp/State.h b/lib/AST/Interp/State.h
new file mode 100644
index 000000000000..d9a645a3eb3e
--- /dev/null
+++ b/lib/AST/Interp/State.h
@@ -0,0 +1,133 @@
+//===--- State.h - State chain for the VM and AST Walker --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines the base class of the interpreter and evaluator state.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_INTERP_STATE_H
+#define LLVM_CLANG_AST_INTERP_STATE_H
+
+#include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/OptionalDiagnostic.h"
+
+namespace clang {
+
+/// Kinds of access we can perform on an object, for diagnostics. Note that
+/// we consider a member function call to be a kind of access, even though
+/// it is not formally an access of the object, because it has (largely) the
+/// same set of semantic restrictions.
+enum AccessKinds {
+ AK_Read,
+ AK_ReadObjectRepresentation,
+ AK_Assign,
+ AK_Increment,
+ AK_Decrement,
+ AK_MemberCall,
+ AK_DynamicCast,
+ AK_TypeId,
+ AK_Construct,
+ AK_Destroy,
+};
+
+// The order of this enum is important for diagnostics.
+enum CheckSubobjectKind {
+ CSK_Base,
+ CSK_Derived,
+ CSK_Field,
+ CSK_ArrayToPointer,
+ CSK_ArrayIndex,
+ CSK_Real,
+ CSK_Imag
+};
+
+namespace interp {
+class Frame;
+class SourceInfo;
+
+/// Interface for the VM to interact with the AST walker's context.
+class State {
+public:
+ virtual ~State();
+
+ virtual bool checkingForUndefinedBehavior() const = 0;
+ virtual bool checkingPotentialConstantExpression() const = 0;
+ virtual bool noteUndefinedBehavior() = 0;
+ virtual bool keepEvaluatingAfterFailure() const = 0;
+ virtual Frame *getCurrentFrame() = 0;
+ virtual const Frame *getBottomFrame() const = 0;
+ virtual bool hasActiveDiagnostic() = 0;
+ virtual void setActiveDiagnostic(bool Flag) = 0;
+ virtual void setFoldFailureDiagnostic(bool Flag) = 0;
+ virtual Expr::EvalStatus &getEvalStatus() const = 0;
+ virtual ASTContext &getCtx() const = 0;
+ virtual bool hasPriorDiagnostic() = 0;
+ virtual unsigned getCallStackDepth() = 0;
+
+public:
+ // Diagnose that the evaluation could not be folded (FF => FoldFailure)
+ OptionalDiagnostic
+ FFDiag(SourceLocation Loc,
+ diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
+ unsigned ExtraNotes = 0);
+
+ OptionalDiagnostic
+ FFDiag(const Expr *E,
+ diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
+ unsigned ExtraNotes = 0);
+
+ OptionalDiagnostic
+ FFDiag(const SourceInfo &SI,
+ diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
+ unsigned ExtraNotes = 0);
+
+ /// Diagnose that the evaluation does not produce a C++11 core constant
+ /// expression.
+ ///
+ /// FIXME: Stop evaluating if we're in EM_ConstantExpression or
+ /// EM_PotentialConstantExpression mode and we produce one of these.
+ OptionalDiagnostic
+ CCEDiag(SourceLocation Loc,
+ diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
+ unsigned ExtraNotes = 0);
+
+ OptionalDiagnostic
+ CCEDiag(const Expr *E,
+ diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
+ unsigned ExtraNotes = 0);
+
+ OptionalDiagnostic
+ CCEDiag(const SourceInfo &SI,
+ diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
+ unsigned ExtraNotes = 0);
+
+ /// Add a note to a prior diagnostic.
+ OptionalDiagnostic Note(SourceLocation Loc, diag::kind DiagId);
+
+ /// Add a stack of notes to a prior diagnostic.
+ void addNotes(ArrayRef<PartialDiagnosticAt> Diags);
+
+ /// Directly reports a diagnostic message.
+ DiagnosticBuilder report(SourceLocation Loc, diag::kind DiagId);
+
+ const LangOptions &getLangOpts() const;
+
+private:
+ void addCallStack(unsigned Limit);
+
+ PartialDiagnostic &addDiag(SourceLocation Loc, diag::kind DiagId);
+
+ OptionalDiagnostic diag(SourceLocation Loc, diag::kind DiagId,
+ unsigned ExtraNotes, bool IsCCEDiag);
+};
+
+} // namespace interp
+} // namespace clang
+
+#endif