clang 24.0.0git
EvalEmitter.h
Go to the documentation of this file.
1//===--- EvalEmitter.h - Instruction emitter 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// Defines the instruction emitters.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_INTERP_EVALEMITTER_H
14#define LLVM_CLANG_AST_INTERP_EVALEMITTER_H
15
16#include "EvaluationResult.h"
17#include "InterpState.h"
18#include "PrimType.h"
19#include "Record.h"
20#include "Source.h"
21
22namespace clang {
23namespace interp {
24class Context;
25class Function;
26class InterpStack;
27class FrameAllocator;
28class Program;
29enum Opcode : uint32_t;
30
31/// An emitter which evaluates opcodes as they are emitted.
32class EvalEmitter : public SourceMapper {
33public:
34 using LabelTy = uint32_t;
38 llvm::function_ref<bool(InterpState &S, CodePtr OpPC, const Pointer &)>;
39
41 return interpretExpr(E, /*ConvertResultToRValue=*/E->isGLValue(),
42 /*DestroyToplevelScope=*/false);
43 }
44
45 EvaluationResult interpretExpr(const Expr *E, bool ConvertResultToRValue,
46 bool DestroyToplevelScope = false);
47
51 /// Interpret the given Expr to a Pointer.
54 /// Interpret the given expression as if it was in the body of the given
55 /// function, i.e. the parameters of the function are available for use.
56 bool interpretCall(const FunctionDecl *FD, const Expr *E);
57
58 std::optional<bool> interpretWithSubstitutions(const FunctionDecl *Callee,
60 const Expr *This,
61 const Expr *Condition);
62
63 /// Clean up all resources.
64 void cleanup();
65
66 /// Returns the source location of the current opcode.
67 SourceInfo getSource(CodePtr PC) const override { return CurrentSource; }
68
69 bool constantFolding() const {
70 return S.EvalMode == EvaluationMode::ConstantFold;
71 }
72
73protected:
74 EvalEmitter(Context &Ctx, Program &P, const EvalSettings &Settings,
75 InterpStack &Stk, FrameAllocator &FrameAlloc);
76
78 InterpStack &Stk, FrameAllocator &FrameAlloc);
79
80 /// Define a label.
81 void emitLabel(LabelTy Label);
82 /// Create a label.
84
85 /// Methods implemented by the compiler.
86 virtual bool visitExpr(const Expr *E, bool DestroyToplevelScope) = 0;
87 virtual bool visitLValueExpr(const Expr *E, bool DestroyToplevelScope) = 0;
88 virtual bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
89 bool ConstantContext) = 0;
90 virtual bool visitDtorCall(const VarDecl *VD, const APValue &Value) = 0;
91 virtual bool visitWithSubstitutions(const FunctionDecl *Callee,
93 const Expr *This,
94 const Expr *Condition) = 0;
95 virtual bool visitFunc(const FunctionDecl *F) = 0;
96 virtual bool visit(const Expr *E) = 0;
97 virtual bool emitBool(bool V, const Expr *E) = 0;
98
99 /// Emits jumps.
100 bool jumpTrue(const LabelTy &Label, SourceInfo SI);
101 bool jumpFalse(const LabelTy &Label, SourceInfo SI);
102 bool jump(const LabelTy &Label, SourceInfo SI);
103 bool fallthrough(const LabelTy &Label);
104 /// Speculative execution.
105 bool speculate(const CallExpr *E, const LabelTy &EndLabel);
106
107 /// Since expressions can only jump forward, predicated execution is
108 /// used to deal with if-else statements.
109 bool isActive() const { return CurrentLabel == ActiveLabel; }
111 return S.checkingForUndefinedBehavior();
112 }
113
114 /// Callback for registering a local.
115 Local createLocal(const Descriptor *D);
116
117 /// Parameter indices.
118 llvm::DenseMap<const ParmVarDecl *, FuncParam> Params;
119 /// Local descriptors.
121 std::optional<SourceInfo> LocOverride = std::nullopt;
122
123private:
124 /// Current compilation context.
125 Context &Ctx;
126 /// Current program.
127 Program &P;
128 /// Callee evaluation state.
129 InterpState S;
130 /// Location to write the result to.
131 EvaluationResult EvalResult;
132 ConstantExprKind ConstexprKind = ConstantExprKind::Normal;
133 /// Whether the result should be converted to an RValue.
134 bool ConvertResultToRValue = false;
135 /// Whether we should check if the result has been fully
136 /// initialized.
137 bool CheckFullyInitialized = false;
138 /// Callback to call when using interpretAsPointer.
139 std::optional<PtrCallback> PtrCB;
140
141 /// Temporaries which require storage.
143
144 Block *getLocal(unsigned Index) const {
145 assert(Index < Locals.size());
146 return reinterpret_cast<Block *>(Locals[Index]);
147 }
148
149 void updateGlobalTemporaries();
150
151 /// Location of the current instruction.
152 SourceInfo CurrentSource;
153
154 /// Next label ID to generate - first label is 1.
155 LabelTy NextLabel = 1;
156 /// Label being executed - 0 is the entry label.
157 LabelTy CurrentLabel = 0;
158 /// Active block which should be executed.
159 LabelTy ActiveLabel = 0;
160
161protected:
162#define GET_EVAL_PROTO
163#include "Opcodes.inc"
164#undef GET_EVAL_PROTO
165};
166
167} // namespace interp
168} // namespace clang
169
170#endif
#define V(N, I)
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:158
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2991
This represents one expression.
Definition Expr.h:113
bool isGLValue() const
Definition Expr.h:288
Represents a function declaration or definition.
Definition Decl.h:2059
Represents a variable declaration or definition.
Definition Decl.h:933
A memory block, either on the stack or in the heap.
Definition InterpBlock.h:43
Pointer into the code segment.
Definition Source.h:31
Holds all information required to evaluate constexpr code in a module.
Definition Context.h:49
std::optional< SourceInfo > LocOverride
llvm::DenseMap< const ParmVarDecl *, FuncParam > Params
Parameter indices.
virtual bool visitFunc(const FunctionDecl *F)=0
EvaluationResult interpretDecl(const VarDecl *VD, const Expr *Init, bool CheckFullyInitialized)
EvaluationResult interpretDestructor(const VarDecl *VD, const APValue &Value)
bool jump(const LabelTy &Label, SourceInfo SI)
bool checkingForUndefinedBehavior() const
virtual bool visit(const Expr *E)=0
bool speculate(const CallExpr *E, const LabelTy &EndLabel)
Speculative execution.
Local createLocal(const Descriptor *D)
Callback for registering a local.
std::optional< bool > interpretWithSubstitutions(const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This, const Expr *Condition)
virtual bool visitDtorCall(const VarDecl *VD, const APValue &Value)=0
bool jumpFalse(const LabelTy &Label, SourceInfo SI)
EvalEmitter(Context &Ctx, Program &P, const EvalSettings &Settings, InterpStack &Stk, FrameAllocator &FrameAlloc)
bool interpretCall(const FunctionDecl *FD, const Expr *E)
Interpret the given expression as if it was in the body of the given function, i.e.
void emitLabel(LabelTy Label)
Define a label.
EvaluationResult interpretExpr(const Expr *E)
Definition EvalEmitter.h:40
bool isActive() const
Since expressions can only jump forward, predicated execution is used to deal with if-else statements...
virtual bool visitWithSubstitutions(const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This, const Expr *Condition)=0
EvaluationResult interpretAsLValuePointer(const Expr *E, PtrCallback PtrCB)
virtual bool visitExpr(const Expr *E, bool DestroyToplevelScope)=0
Methods implemented by the compiler.
bool fallthrough(const LabelTy &Label)
virtual bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init, bool ConstantContext)=0
void cleanup()
Clean up all resources.
LabelTy getLabel()
Create a label.
EvaluationResult interpretAsPointer(const Expr *E, PtrCallback PtrCB)
Interpret the given Expr to a Pointer.
SourceInfo getSource(CodePtr PC) const override
Returns the source location of the current opcode.
Definition EvalEmitter.h:67
llvm::SmallVector< SmallVector< Local, 2 >, 1 > Descriptors
Local descriptors.
virtual bool emitBool(bool V, const Expr *E)=0
bool jumpTrue(const LabelTy &Label, SourceInfo SI)
Emits jumps.
virtual bool visitLValueExpr(const Expr *E, bool DestroyToplevelScope)=0
llvm::function_ref< bool(InterpState &S, CodePtr OpPC, const Pointer &)> PtrCallback
Definition EvalEmitter.h:37
Defines the result of an evaluation.
Allocator for function frames.
Bytecode function.
Definition Function.h:98
Stack frame storing temporaries and parameters.
Definition InterpStack.h:26
Interpreter context.
Definition InterpState.h:47
A pointer to a memory block, live or dead.
Definition Pointer.h:546
The program contains and links the bytecode for all functions.
Definition Program.h:38
Describes the statement/declaration an opcode was generated from.
Definition Source.h:77
Interface for classes which map locations to sources.
Definition Source.h:138
bool This(InterpState &S, CodePtr OpPC)
Definition Interp.h:3223
bool Init(InterpState &S, CodePtr OpPC)
Definition Interp.h:2420
Top level wrappers for InstallAPI frontend operations.
Expr::ConstantExprKind ConstantExprKind
Definition Expr.h:1066
@ ConstantFold
Fold the expression to a constant.
Definition State.h:67
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
EvalStatus is a struct with detailed info about an evaluation in progress.
Definition Expr.h:622
Describes a memory block created by an allocation site.
Definition Descriptor.h:123
Information about a local's storage.
Definition Function.h:38