brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · c296cc9 Raw
111 lines · c
1//===------ EvaluationResult.h - Result class  for the VM -------*- 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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_AST_INTERP_EVALUATION_RESULT_H10#define LLVM_CLANG_AST_INTERP_EVALUATION_RESULT_H11 12#include "clang/AST/APValue.h"13#include "clang/AST/Decl.h"14#include "clang/AST/Expr.h"15 16namespace clang {17namespace interp {18class EvalEmitter;19class Context;20class Pointer;21class SourceInfo;22class InterpState;23 24/// Defines the result of an evaluation.25///26/// The Kind defined if the evaluation was invalid, valid (but empty, e.g. for27/// void expressions) or if we have a valid evaluation result.28///29/// We use this class to inspect and diagnose the result, as well as30/// convert it to the requested form.31class EvaluationResult final {32public:33  enum ResultKind {34    Empty,   // Initial state.35    Invalid, // Result is invalid.36    Valid,   // Result is valid and empty.37  };38 39  using DeclTy = llvm::PointerUnion<const Decl *, const Expr *>;40 41private:42#ifndef NDEBUG43  const Context *Ctx = nullptr;44#endif45  APValue Value;46  ResultKind Kind = Empty;47  DeclTy Source = nullptr;48 49  void setSource(DeclTy D) { Source = D; }50 51  void takeValue(APValue &&V) {52    assert(empty());53    Value = std::move(V);54  }55  void setInvalid() {56    // We are NOT asserting empty() here, since setting it to invalid57    // is allowed even if there is already a result.58    Kind = Invalid;59  }60  void setValid() {61    assert(empty());62    Kind = Valid;63  }64 65public:66#ifndef NDEBUG67  EvaluationResult(const Context *Ctx) : Ctx(Ctx) {}68#else69  EvaluationResult(const Context *Ctx) {}70#endif71 72  bool empty() const { return Kind == Empty; }73  bool isInvalid() const { return Kind == Invalid; }74 75  /// Returns an APValue for the evaluation result.76  APValue toAPValue() const {77    assert(!empty());78    assert(!isInvalid());79    return Value;80  }81 82  APValue stealAPValue() { return std::move(Value); }83 84  /// Check that all subobjects of the given pointer have been initialized.85  bool checkFullyInitialized(InterpState &S, const Pointer &Ptr) const;86  /// Check that none of the blocks the given pointer (transitively) points87  /// to are dynamically allocated.88  bool checkReturnValue(InterpState &S, const Context &Ctx, const Pointer &Ptr,89                        const SourceInfo &Info);90 91  QualType getSourceType() const {92    if (const auto *D =93            dyn_cast_if_present<ValueDecl>(Source.dyn_cast<const Decl *>()))94      return D->getType();95    if (const auto *E = Source.dyn_cast<const Expr *>())96      return E->getType();97    return QualType();98  }99 100  /// Dump to stderr.101  void dump() const;102 103  friend class EvalEmitter;104  friend class InterpState;105};106 107} // namespace interp108} // namespace clang109 110#endif111