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