clang 20.0.0git
EvaluationResult.h
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_AST_INTERP_EVALUATION_RESULT_H
10#define LLVM_CLANG_AST_INTERP_EVALUATION_RESULT_H
11
12#include "FunctionPointer.h"
13#include "Pointer.h"
14#include "clang/AST/APValue.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/Expr.h"
17#include <optional>
18#include <variant>
19
20namespace clang {
21namespace interp {
22class EvalEmitter;
23class Context;
24
25/// Defines the result of an evaluation.
26///
27/// The result might be in different forms--one of the pointer types,
28/// an APValue, or nothing.
29///
30/// We use this class to inspect and diagnose the result, as well as
31/// convert it to the requested form.
32class EvaluationResult final {
33public:
35 Empty, // Initial state.
36 LValue, // Result is an lvalue/pointer.
37 RValue, // Result is an rvalue.
38 Invalid, // Result is invalid.
39 Valid, // Result is valid and empty.
40 };
41
42 using DeclTy = llvm::PointerUnion<const Decl *, const Expr *>;
43
44private:
45 const Context *Ctx = nullptr;
46 std::variant<std::monostate, Pointer, FunctionPointer, APValue> Value;
47 ResultKind Kind = Empty;
48 DeclTy Source = nullptr; // Currently only needed for dump().
49
50 EvaluationResult(ResultKind Kind) : Kind(Kind) {
51 // Leave everything empty. Can be used as an
52 // error marker or for void return values.
53 assert(Kind == Valid || Kind == Invalid);
54 }
55
56 void setSource(DeclTy D) { Source = D; }
57
58 void setValue(const APValue &V) {
59 // V could still be an LValue.
60 assert(empty());
61 Value = std::move(V);
62 Kind = RValue;
63 }
64 void setPointer(const Pointer P) {
65 assert(empty());
66 Value = P;
67 Kind = LValue;
68 }
69 void setFunctionPointer(const FunctionPointer &P) {
70 assert(empty());
71 Value = P;
72 Kind = LValue;
73 }
74 void setInvalid() {
75 // We are NOT asserting empty() here, since setting it to invalid
76 // is allowed even if there is already a result.
77 Kind = Invalid;
78 }
79 void setValid() {
80 assert(empty());
81 Kind = Valid;
82 }
83
84public:
85 EvaluationResult(const Context *Ctx) : Ctx(Ctx) {}
86
87 bool empty() const { return Kind == Empty; }
88 bool isInvalid() const { return Kind == Invalid; }
89 bool isLValue() const { return Kind == LValue; }
90 bool isRValue() const { return Kind == RValue; }
91
92 /// Returns an APValue for the evaluation result. The returned
93 /// APValue might be an LValue or RValue.
94 APValue toAPValue() const;
95
96 /// If the result is an LValue, convert that to an RValue
97 /// and return it. This may fail, e.g. if the result is an
98 /// LValue and we can't read from it.
99 std::optional<APValue> toRValue() const;
100
101 /// Check that all subobjects of the given pointer have been initialized.
102 bool checkFullyInitialized(InterpState &S, const Pointer &Ptr) const;
103 /// Check that none of the blocks the given pointer (transitively) points
104 /// to are dynamically allocated.
105 bool checkReturnValue(InterpState &S, const Context &Ctx, const Pointer &Ptr,
106 const SourceInfo &Info);
107
109 if (const auto *D =
110 dyn_cast_if_present<ValueDecl>(Source.dyn_cast<const Decl *>()))
111 return D->getType();
112 else if (const auto *E = Source.dyn_cast<const Expr *>())
113 return E->getType();
114 return QualType();
115 }
116
117 /// Dump to stderr.
118 void dump() const;
119
120 friend class EvalEmitter;
121 friend class InterpState;
122};
123
124} // namespace interp
125} // namespace clang
126
127#endif
#define V(N, I)
Definition: ASTContext.h:3341
StringRef P
const Decl * D
Expr * E
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
This represents one expression.
Definition: Expr.h:110
A (possibly-)qualified type.
Definition: Type.h:941
Holds all information required to evaluate constexpr code in a module.
Definition: Context.h:40
An emitter which evaluates opcodes as they are emitted.
Definition: EvalEmitter.h:31
Defines the result of an evaluation.
std::optional< APValue > toRValue() const
If the result is an LValue, convert that to an RValue and return it.
APValue toAPValue() const
Returns an APValue for the evaluation result.
bool checkReturnValue(InterpState &S, const Context &Ctx, const Pointer &Ptr, const SourceInfo &Info)
Check that none of the blocks the given pointer (transitively) points to are dynamically allocated.
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
bool checkFullyInitialized(InterpState &S, const Pointer &Ptr) const
Check that all subobjects of the given pointer have been initialized.
EvaluationResult(const Context *Ctx)
void dump() const
Dump to stderr.
Definition: Disasm.cpp:352
Interpreter context.
Definition: InterpState.h:36
A pointer to a memory block, live or dead.
Definition: Pointer.h:82
Describes the statement/declaration an opcode was generated from.
Definition: Source.h:77
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
Definition: Descriptor.h:28
The JSON file list parser is used to communicate input to InstallAPI.