Path: blob/main/contrib/llvm-project/clang/lib/AST/Interp/EvaluationResult.h
35292 views
//===------ EvaluationResult.h - Result class for the VM -------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLVM_CLANG_AST_INTERP_EVALUATION_RESULT_H9#define LLVM_CLANG_AST_INTERP_EVALUATION_RESULT_H1011#include "FunctionPointer.h"12#include "Pointer.h"13#include "clang/AST/APValue.h"14#include "clang/AST/Decl.h"15#include "clang/AST/Expr.h"16#include <optional>17#include <variant>1819namespace clang {20namespace interp {21class EvalEmitter;22class Context;2324/// Defines the result of an evaluation.25///26/// The result might be in different forms--one of the pointer types,27/// an APValue, or nothing.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:33enum ResultKind {34Empty, // Initial state.35LValue, // Result is an lvalue/pointer.36RValue, // Result is an rvalue.37Invalid, // Result is invalid.38Valid, // Result is valid and empty.39};4041using DeclTy = llvm::PointerUnion<const Decl *, const Expr *>;4243private:44const Context *Ctx = nullptr;45std::variant<std::monostate, Pointer, FunctionPointer, APValue> Value;46ResultKind Kind = Empty;47DeclTy Source = nullptr; // Currently only needed for dump().4849EvaluationResult(ResultKind Kind) : Kind(Kind) {50// Leave everything empty. Can be used as an51// error marker or for void return values.52assert(Kind == Valid || Kind == Invalid);53}5455void setSource(DeclTy D) { Source = D; }5657void setValue(const APValue &V) {58// V could still be an LValue.59assert(empty());60Value = std::move(V);61Kind = RValue;62}63void setPointer(const Pointer P) {64assert(empty());65Value = P;66Kind = LValue;67}68void setFunctionPointer(const FunctionPointer &P) {69assert(empty());70Value = P;71Kind = LValue;72}73void setInvalid() {74// We are NOT asserting empty() here, since setting it to invalid75// is allowed even if there is already a result.76Kind = Invalid;77}78void setValid() {79assert(empty());80Kind = Valid;81}8283public:84EvaluationResult(const Context *Ctx) : Ctx(Ctx) {}8586bool empty() const { return Kind == Empty; }87bool isInvalid() const { return Kind == Invalid; }88bool isLValue() const { return Kind == LValue; }89bool isRValue() const { return Kind == RValue; }9091/// Returns an APValue for the evaluation result. The returned92/// APValue might be an LValue or RValue.93APValue toAPValue() const;9495/// If the result is an LValue, convert that to an RValue96/// and return it. This may fail, e.g. if the result is an97/// LValue and we can't read from it.98std::optional<APValue> toRValue() const;99100/// Check that all subobjects of the given pointer have been initialized.101bool checkFullyInitialized(InterpState &S, const Pointer &Ptr) const;102/// Check that none of the blocks the given pointer (transitively) points103/// to are dynamically allocated.104bool checkReturnValue(InterpState &S, const Context &Ctx, const Pointer &Ptr,105const SourceInfo &Info);106107QualType getSourceType() const {108if (const auto *D =109dyn_cast_if_present<ValueDecl>(Source.dyn_cast<const Decl *>()))110return D->getType();111else if (const auto *E = Source.dyn_cast<const Expr *>())112return E->getType();113return QualType();114}115116/// Dump to stderr.117void dump() const;118119friend class EvalEmitter;120friend class InterpState;121};122123} // namespace interp124} // namespace clang125126#endif127128129