Path: blob/main/contrib/llvm-project/clang/lib/AST/ByteCode/EvaluationResult.h
213799 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 setFunctionPointer(const FunctionPointer &P) {64assert(empty());65Value = P;66Kind = LValue;67}68void setInvalid() {69// We are NOT asserting empty() here, since setting it to invalid70// is allowed even if there is already a result.71Kind = Invalid;72}73void setValid() {74assert(empty());75Kind = Valid;76}7778public:79EvaluationResult(const Context *Ctx) : Ctx(Ctx) {}8081bool empty() const { return Kind == Empty; }82bool isInvalid() const { return Kind == Invalid; }83bool isLValue() const { return Kind == LValue; }84bool isRValue() const { return Kind == RValue; }85bool isPointer() const { return std::holds_alternative<Pointer>(Value); }8687/// Returns an APValue for the evaluation result. The returned88/// APValue might be an LValue or RValue.89APValue toAPValue() const;9091/// If the result is an LValue, convert that to an RValue92/// and return it. This may fail, e.g. if the result is an93/// LValue and we can't read from it.94std::optional<APValue> toRValue() const;9596/// Check that all subobjects of the given pointer have been initialized.97bool checkFullyInitialized(InterpState &S, const Pointer &Ptr) const;98/// Check that none of the blocks the given pointer (transitively) points99/// to are dynamically allocated.100bool checkReturnValue(InterpState &S, const Context &Ctx, const Pointer &Ptr,101const SourceInfo &Info);102103QualType getSourceType() const {104if (const auto *D =105dyn_cast_if_present<ValueDecl>(Source.dyn_cast<const Decl *>()))106return D->getType();107else if (const auto *E = Source.dyn_cast<const Expr *>())108return E->getType();109return QualType();110}111112/// Dump to stderr.113void dump() const;114115friend class EvalEmitter;116friend class InterpState;117};118119} // namespace interp120} // namespace clang121122#endif123124125