State.h 4.2 KB

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