Home | History | Annotate | Line # | Download | only in Interp
      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