clang 18.0.0git
ByteCodeExprGen.h
Go to the documentation of this file.
1//===--- ByteCodeExprGen.h - Code generator for expressions -----*- 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 constexpr bytecode compiler.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_INTERP_BYTECODEEXPRGEN_H
14#define LLVM_CLANG_AST_INTERP_BYTECODEEXPRGEN_H
15
16#include "ByteCodeEmitter.h"
17#include "EvalEmitter.h"
18#include "Pointer.h"
19#include "PrimType.h"
20#include "Record.h"
21#include "clang/AST/Decl.h"
22#include "clang/AST/Expr.h"
25
26namespace clang {
27class QualType;
28
29namespace interp {
30
31template <class Emitter> class LocalScope;
32template <class Emitter> class DestructorScope;
33template <class Emitter> class RecordScope;
34template <class Emitter> class VariableScope;
35template <class Emitter> class DeclScope;
36template <class Emitter> class OptionScope;
37template <class Emitter> class ArrayIndexScope;
38template <class Emitter> class SourceLocScope;
39
40/// Compilation context for expressions.
41template <class Emitter>
42class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
43 public Emitter {
44protected:
45 // Aliases for types defined in the emitter.
46 using LabelTy = typename Emitter::LabelTy;
47 using AddrTy = typename Emitter::AddrTy;
48
49 /// Current compilation context.
51 /// Program to link to.
53
54public:
55 /// Initializes the compiler and the backend emitter.
56 template <typename... Tys>
57 ByteCodeExprGen(Context &Ctx, Program &P, Tys &&... Args)
58 : Emitter(Ctx, P, Args...), Ctx(Ctx), P(P) {}
59
60 // Expression visitors - result returned on interp stack.
61 bool VisitCastExpr(const CastExpr *E);
64 bool VisitParenExpr(const ParenExpr *E);
66 bool VisitLogicalBinOp(const BinaryOperator *E);
69 bool VisitCallExpr(const CallExpr *E);
70 bool VisitBuiltinCallExpr(const CallExpr *E);
74 bool VisitGNUNullExpr(const GNUNullExpr *E);
75 bool VisitCXXThisExpr(const CXXThisExpr *E);
76 bool VisitUnaryOperator(const UnaryOperator *E);
77 bool VisitDeclRefExpr(const DeclRefExpr *E);
81 bool VisitInitListExpr(const InitListExpr *E);
83 bool VisitConstantExpr(const ConstantExpr *E);
85 bool VisitMemberExpr(const MemberExpr *E);
90 bool VisitStringLiteral(const StringLiteral *E);
99 bool VisitTypeTraitExpr(const TypeTraitExpr *E);
100 bool VisitLambdaExpr(const LambdaExpr *E);
101 bool VisitPredefinedExpr(const PredefinedExpr *E);
102 bool VisitCXXThrowExpr(const CXXThrowExpr *E);
106 bool VisitSourceLocExpr(const SourceLocExpr *E);
107 bool VisitOffsetOfExpr(const OffsetOfExpr *E);
109 bool VisitSizeOfPackExpr(const SizeOfPackExpr *E);
110
111protected:
112 bool visitExpr(const Expr *E) override;
113 bool visitDecl(const VarDecl *VD) override;
114
115protected:
116 /// Emits scope cleanup instructions.
117 void emitCleanup();
118
119 /// Returns a record type from a record or pointer type.
121
122 /// Returns a record from a record or pointer type.
124 Record *getRecord(const RecordDecl *RD);
125
126 // Returns a function for the given FunctionDecl.
127 // If the function does not exist yet, it is compiled.
128 const Function *getFunction(const FunctionDecl *FD);
129
130 /// Classifies a type.
131 std::optional<PrimType> classify(const Expr *E) const {
132 if (E->isGLValue()) {
133 if (E->getType()->isFunctionType())
134 return PT_FnPtr;
135 return PT_Ptr;
136 }
137
138 return classify(E->getType());
139 }
140 std::optional<PrimType> classify(QualType Ty) const {
141 return Ctx.classify(Ty);
142 }
143
144 /// Classifies a known primitive type
146 if (auto T = classify(Ty)) {
147 return *T;
148 }
149 llvm_unreachable("not a primitive type");
150 }
151 /// Evaluates an expression and places the result on the stack. If the
152 /// expression is of composite type, a local variable will be created
153 /// and a pointer to said variable will be placed on the stack.
154 bool visit(const Expr *E);
155 /// Compiles an initializer. This is like visit() but it will never
156 /// create a variable and instead rely on a variable already having
157 /// been created. visitInitializer() then relies on a pointer to this
158 /// variable being on top of the stack.
159 bool visitInitializer(const Expr *E);
160 /// Evaluates an expression for side effects and discards the result.
161 bool discard(const Expr *E);
162 /// Just pass evaluation on to \p E. This leaves all the parsing flags
163 /// intact.
164 bool delegate(const Expr *E);
165
166 /// Creates and initializes a variable from the given decl.
167 bool visitVarDecl(const VarDecl *VD);
168 /// Visit an APValue.
169 bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E);
170
171 /// Visits an expression and converts it to a boolean.
172 bool visitBool(const Expr *E);
173
174 /// Visits an initializer for a local.
175 bool visitLocalInitializer(const Expr *Init, unsigned I) {
176 if (!this->emitGetPtrLocal(I, Init))
177 return false;
178
180 return false;
181
182 return this->emitPopPtr(Init);
183 }
184
185 /// Visits an initializer for a global.
186 bool visitGlobalInitializer(const Expr *Init, unsigned I) {
187 if (!this->emitGetPtrGlobal(I, Init))
188 return false;
189
191 return false;
192
193 if ((Init->getType()->isArrayType() || Init->getType()->isRecordType()) &&
194 !this->emitCheckGlobalCtor(Init))
195 return false;
196
197 return this->emitPopPtr(Init);
198 }
199
200 /// Visits a delegated initializer.
201 bool visitThisInitializer(const Expr *I) {
202 if (!this->emitThis(I))
203 return false;
204
205 if (!visitInitializer(I))
206 return false;
207
208 return this->emitPopPtr(I);
209 }
210
211 bool visitInitList(ArrayRef<const Expr *> Inits, const Expr *E);
212 bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init);
213
214 /// Creates a local primitive value.
215 unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst,
216 bool IsExtended = false);
217
218 /// Allocates a space storing a local given its type.
219 std::optional<unsigned> allocateLocal(DeclTy &&Decl, bool IsExtended = false);
220
221private:
222 friend class VariableScope<Emitter>;
223 friend class LocalScope<Emitter>;
224 friend class DestructorScope<Emitter>;
225 friend class RecordScope<Emitter>;
226 friend class DeclScope<Emitter>;
227 friend class OptionScope<Emitter>;
228 friend class ArrayIndexScope<Emitter>;
229 friend class SourceLocScope<Emitter>;
230
231 /// Emits a zero initializer.
232 bool visitZeroInitializer(PrimType T, QualType QT, const Expr *E);
233 bool visitZeroRecordInitializer(const Record *R, const Expr *E);
234
235 enum class DerefKind {
236 /// Value is read and pushed to stack.
237 Read,
238 /// Direct method generates a value which is written. Returns pointer.
239 Write,
240 /// Direct method receives the value, pushes mutated value. Returns pointer.
241 ReadWrite,
242 };
243
244 /// Method to directly load a value. If the value can be fetched directly,
245 /// the direct handler is called. Otherwise, a pointer is left on the stack
246 /// and the indirect handler is expected to operate on that.
247 bool dereference(const Expr *LV, DerefKind AK,
248 llvm::function_ref<bool(PrimType)> Direct,
249 llvm::function_ref<bool(PrimType)> Indirect);
250 bool dereferenceParam(const Expr *LV, PrimType T, const ParmVarDecl *PD,
251 DerefKind AK,
252 llvm::function_ref<bool(PrimType)> Direct,
253 llvm::function_ref<bool(PrimType)> Indirect);
254 bool dereferenceVar(const Expr *LV, PrimType T, const VarDecl *PD,
255 DerefKind AK, llvm::function_ref<bool(PrimType)> Direct,
256 llvm::function_ref<bool(PrimType)> Indirect);
257
258 /// Emits an APSInt constant.
259 bool emitConst(const llvm::APSInt &Value, PrimType Ty, const Expr *E);
260 bool emitConst(const llvm::APSInt &Value, const Expr *E);
261 bool emitConst(const llvm::APInt &Value, const Expr *E) {
262 return emitConst(static_cast<llvm::APSInt>(Value), E);
263 }
264
265 /// Emits an integer constant.
266 template <typename T> bool emitConst(T Value, PrimType Ty, const Expr *E);
267 template <typename T> bool emitConst(T Value, const Expr *E);
268
269 /// Returns the CXXRecordDecl for the type of the given expression,
270 /// or nullptr if no such decl exists.
271 const CXXRecordDecl *getRecordDecl(const Expr *E) const {
272 QualType T = E->getType();
273 if (const auto *RD = T->getPointeeCXXRecordDecl())
274 return RD;
275 return T->getAsCXXRecordDecl();
276 }
277
278 llvm::RoundingMode getRoundingMode(const Expr *E) const {
279 FPOptions FPO = E->getFPFeaturesInEffect(Ctx.getLangOpts());
280
281 if (FPO.getRoundingMode() == llvm::RoundingMode::Dynamic)
282 return llvm::RoundingMode::NearestTiesToEven;
283
284 return FPO.getRoundingMode();
285 }
286
287 bool emitPrimCast(PrimType FromT, PrimType ToT, QualType ToQT, const Expr *E);
288 bool emitRecordDestruction(const Descriptor *Desc);
289 unsigned collectBaseOffset(const RecordType *BaseType,
290 const RecordType *DerivedType);
291
292protected:
293 /// Variable to storage mapping.
294 llvm::DenseMap<const ValueDecl *, Scope::Local> Locals;
295
296 /// OpaqueValueExpr to location mapping.
297 llvm::DenseMap<const OpaqueValueExpr *, unsigned> OpaqueExprs;
298
299 /// Current scope.
301
302 /// Current argument index. Needed to emit ArrayInitIndexExpr.
303 std::optional<uint64_t> ArrayIndex;
304
305 /// DefaultInit- or DefaultArgExpr, needed for SourceLocExpr.
306 const Expr *SourceLocDefaultExpr = nullptr;
307
308 /// Flag indicating if return value is to be discarded.
309 bool DiscardResult = false;
310
311 /// Flag inidicating if we're initializing an already created
312 /// variable. This is set in visitInitializer().
313 bool Initializing = false;
314
315 /// Flag indicating if we're initializing a global variable.
316 bool GlobalDecl = false;
317};
318
319extern template class ByteCodeExprGen<ByteCodeEmitter>;
320extern template class ByteCodeExprGen<EvalEmitter>;
321
322/// Scope chain managing the variable lifetimes.
323template <class Emitter> class VariableScope {
324public:
326 : Ctx(Ctx), Parent(Ctx->VarScope) {
327 Ctx->VarScope = this;
328 }
329
330 virtual ~VariableScope() { Ctx->VarScope = this->Parent; }
331
332 void add(const Scope::Local &Local, bool IsExtended) {
333 if (IsExtended)
334 this->addExtended(Local);
335 else
336 this->addLocal(Local);
337 }
338
339 virtual void addLocal(const Scope::Local &Local) {
340 if (this->Parent)
341 this->Parent->addLocal(Local);
342 }
343
344 virtual void addExtended(const Scope::Local &Local) {
345 if (this->Parent)
346 this->Parent->addExtended(Local);
347 }
348
349 virtual void emitDestruction() {}
350 virtual void emitDestructors() {}
351 VariableScope *getParent() const { return Parent; }
352
353protected:
354 /// ByteCodeExprGen instance.
356 /// Link to the parent scope.
358};
359
360/// Generic scope for local variables.
361template <class Emitter> class LocalScope : public VariableScope<Emitter> {
362public:
364
365 /// Emit a Destroy op for this scope.
366 ~LocalScope() override {
367 if (!Idx)
368 return;
369 this->Ctx->emitDestroy(*Idx, SourceInfo{});
370 }
371
372 /// Overriden to support explicit destruction.
373 void emitDestruction() override {
374 if (!Idx)
375 return;
376 this->emitDestructors();
377 this->Ctx->emitDestroy(*Idx, SourceInfo{});
378 this->Idx = std::nullopt;
379 }
380
381 void addLocal(const Scope::Local &Local) override {
382 if (!Idx) {
383 Idx = this->Ctx->Descriptors.size();
384 this->Ctx->Descriptors.emplace_back();
385 }
386
387 this->Ctx->Descriptors[*Idx].emplace_back(Local);
388 }
389
390 void emitDestructors() override {
391 if (!Idx)
392 return;
393 // Emit destructor calls for local variables of record
394 // type with a destructor.
395 for (Scope::Local &Local : this->Ctx->Descriptors[*Idx]) {
396 if (!Local.Desc->isPrimitive() && !Local.Desc->isPrimitiveArray()) {
397 this->Ctx->emitGetPtrLocal(Local.Offset, SourceInfo{});
398 this->Ctx->emitRecordDestruction(Local.Desc);
399 }
400 }
401 }
402
403 /// Index of the scope in the chain.
404 std::optional<unsigned> Idx;
405};
406
407/// Emits the destructors of the variables of \param OtherScope
408/// when this scope is destroyed. Does not create a Scope in the bytecode at
409/// all, this is just a RAII object to emit destructors.
410template <class Emitter> class DestructorScope final {
411public:
412 DestructorScope(LocalScope<Emitter> &OtherScope) : OtherScope(OtherScope) {}
413
414 ~DestructorScope() { OtherScope.emitDestructors(); }
415
416private:
417 LocalScope<Emitter> &OtherScope;
418};
419
420/// Like a regular LocalScope, except that the destructors of all local
421/// variables are automatically emitted when the AutoScope is destroyed.
422template <class Emitter> class AutoScope : public LocalScope<Emitter> {
423public:
425 : LocalScope<Emitter>(Ctx), DS(*this) {}
426
427private:
429};
430
431/// Scope for storage declared in a compound statement.
432template <class Emitter> class BlockScope final : public AutoScope<Emitter> {
433public:
435
436 void addExtended(const Scope::Local &Local) override {
437 // If we to this point, just add the variable as a normal local
438 // variable. It will be destroyed at the end of the block just
439 // like all others.
440 this->addLocal(Local);
441 }
442};
443
444/// Expression scope which tracks potentially lifetime extended
445/// temporaries which are hoisted to the parent scope on exit.
446template <class Emitter> class ExprScope final : public AutoScope<Emitter> {
447public:
449
450 void addExtended(const Scope::Local &Local) override {
451 if (this->Parent)
452 this->Parent->addLocal(Local);
453 }
454};
455
456template <class Emitter> class ArrayIndexScope final {
457public:
458 ArrayIndexScope(ByteCodeExprGen<Emitter> *Ctx, uint64_t Index) : Ctx(Ctx) {
459 OldArrayIndex = Ctx->ArrayIndex;
460 Ctx->ArrayIndex = Index;
461 }
462
463 ~ArrayIndexScope() { Ctx->ArrayIndex = OldArrayIndex; }
464
465private:
467 std::optional<uint64_t> OldArrayIndex;
468};
469
470template <class Emitter> class SourceLocScope final {
471public:
473 : Ctx(Ctx) {
474 assert(DefaultExpr);
475 // We only switch if the current SourceLocDefaultExpr is null.
476 if (!Ctx->SourceLocDefaultExpr) {
477 Enabled = true;
478 Ctx->SourceLocDefaultExpr = DefaultExpr;
479 }
480 }
481
483 if (Enabled)
484 Ctx->SourceLocDefaultExpr = nullptr;
485 }
486
487private:
489 bool Enabled = false;
490};
491
492} // namespace interp
493} // namespace clang
494
495#endif
NodeId Parent
Definition: ASTDiff.cpp:191
@ Write
Definition: CGBuiltin.cpp:8116
static std::optional< DereferenceInfo > dereference(ProgramStateRef State, const FieldRegion *FR)
Dereferences FR and returns with the pointee's region, and whether it needs to be casted back to it's...
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Definition: Expr.h:4163
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition: Expr.h:5575
Represents a loop initializing the elements of an array.
Definition: Expr.h:5522
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2691
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3862
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1475
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition: ExprCXX.h:720
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1530
A default argument (C++ [dcl.fct.default]).
Definition: ExprCXX.h:1254
A use of a default initializer in a constructor or in aggregate initialization.
Definition: ExprCXX.h:1361
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition: ExprCXX.h:4101
The null pointer literal (C++11 [lex.nullptr])
Definition: ExprCXX.h:765
Represents a list-initialization with parenthesis.
Definition: ExprCXX.h:4827
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
Definition: ExprCXX.h:523
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type.
Definition: ExprCXX.h:2165
Represents the this expression in C++.
Definition: ExprCXX.h:1148
A C++ throw-expression (C++ [except.throw]).
Definition: ExprCXX.h:1192
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2847
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3517
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4110
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3447
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:194
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition: Expr.h:1059
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1248
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:85
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3449
This represents one expression.
Definition: Expr.h:110
bool isGLValue() const
Definition: Expr.h:274
QualType getType() const
Definition: Expr.h:142
Represents a function declaration or definition.
Definition: Decl.h:1957
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition: Expr.h:4655
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:56
Represents an implicitly-generated value initialization of an object of a given type.
Definition: Expr.h:5611
Describes an C or C++ initializer list.
Definition: Expr.h:4858
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1938
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition: ExprCXX.h:4593
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3210
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition: Expr.h:2492
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1156
ParenExpr - This represents a parethesized expression, e.g.
Definition: Expr.h:2157
Represents a parameter to a function.
Definition: Decl.h:1747
[C99 6.4.2.2] - A predefined identifier such as func.
Definition: Expr.h:2014
A (possibly-)qualified type.
Definition: Type.h:736
Represents a struct/union/class.
Definition: Decl.h:4117
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4971
Represents an expression that computes the length of a parameter pack.
Definition: ExprCXX.h:4233
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition: Expr.h:4749
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1812
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4349
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition: ExprCXX.h:2764
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1819
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
Definition: Type.cpp:1804
bool isFunctionType() const
Definition: Type.h:7029
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2595
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2210
Represents a variable declaration or definition.
Definition: Decl.h:916
ArrayIndexScope(ByteCodeExprGen< Emitter > *Ctx, uint64_t Index)
Like a regular LocalScope, except that the destructors of all local variables are automatically emitt...
AutoScope(ByteCodeExprGen< Emitter > *Ctx)
Scope for storage declared in a compound statement.
BlockScope(ByteCodeExprGen< Emitter > *Ctx)
void addExtended(const Scope::Local &Local) override
Compilation context for expressions.
bool visitExpr(const Expr *E) override
std::optional< unsigned > allocateLocal(DeclTy &&Decl, bool IsExtended=false)
Allocates a space storing a local given its type.
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsExtended=false)
Creates a local primitive value.
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool VisitDeclRefExpr(const DeclRefExpr *E)
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
bool VisitMemberExpr(const MemberExpr *E)
bool VisitOffsetOfExpr(const OffsetOfExpr *E)
bool discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
bool visitThisInitializer(const Expr *I)
Visits a delegated initializer.
bool visitDecl(const VarDecl *VD) override
Toplevel visitDecl().
bool visitInitializer(const Expr *E)
Compiles an initializer.
bool VisitParenExpr(const ParenExpr *E)
bool Initializing
Flag inidicating if we're initializing an already created variable.
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool VisitLambdaExpr(const LambdaExpr *E)
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
Program & P
Program to link to.
bool VisitBuiltinCallExpr(const CallExpr *E)
PrimType classifyPrim(QualType Ty) const
Classifies a known primitive type.
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E)
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init)
Pointer to the array(not the element!) must be on the stack when calling this.
llvm::DenseMap< const ValueDecl *, Scope::Local > Locals
Variable to storage mapping.
void emitCleanup()
Emits scope cleanup instructions.
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
Context & Ctx
Current compilation context.
bool visitGlobalInitializer(const Expr *Init, unsigned I)
Visits an initializer for a global.
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitPredefinedExpr(const PredefinedExpr *E)
VariableScope< Emitter > * VarScope
Current scope.
std::optional< PrimType > classify(QualType Ty) const
bool VisitBinaryOperator(const BinaryOperator *E)
bool VisitTypeTraitExpr(const TypeTraitExpr *E)
bool visit(const Expr *E)
Evaluates an expression and places the result on the stack.
bool VisitInitListExpr(const InitListExpr *E)
bool VisitFloatingLiteral(const FloatingLiteral *E)
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool visitInitList(ArrayRef< const Expr * > Inits, const Expr *E)
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E)
std::optional< uint64_t > ArrayIndex
Current argument index. Needed to emit ArrayInitIndexExpr.
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
std::optional< PrimType > classify(const Expr *E) const
Classifies a type.
bool DiscardResult
Flag indicating if return value is to be discarded.
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
const Function * getFunction(const FunctionDecl *FD)
bool visitLocalInitializer(const Expr *Init, unsigned I)
Visits an initializer for a local.
bool VisitLogicalBinOp(const BinaryOperator *E)
bool visitVarDecl(const VarDecl *VD)
Creates and initializes a variable from the given decl.
bool VisitStringLiteral(const StringLiteral *E)
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
ByteCodeExprGen(Context &Ctx, Program &P, Tys &&... Args)
Initializes the compiler and the backend emitter.
const Expr * SourceLocDefaultExpr
DefaultInit- or DefaultArgExpr, needed for SourceLocExpr.
bool VisitGNUNullExpr(const GNUNullExpr *E)
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
llvm::DenseMap< const OpaqueValueExpr *, unsigned > OpaqueExprs
OpaqueValueExpr to location mapping.
bool VisitSourceLocExpr(const SourceLocExpr *E)
bool VisitOpaqueValueExpr(const OpaqueValueExpr *E)
bool VisitCXXThisExpr(const CXXThisExpr *E)
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
typename Emitter::LabelTy LabelTy
bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E)
Visit an APValue.
bool VisitPointerArithBinOp(const BinaryOperator *E)
Perform addition/subtraction of a pointer and an integer or subtraction of two pointers.
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitCompoundAssignOperator(const CompoundAssignOperator *E)
bool VisitCallExpr(const CallExpr *E)
const RecordType * getRecordTy(QualType Ty)
Returns a record type from a record or pointer type.
bool delegate(const Expr *E)
Just pass evaluation on to E.
bool VisitConstantExpr(const ConstantExpr *E)
bool VisitCastExpr(const CastExpr *E)
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E)
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
typename Emitter::AddrTy AddrTy
Holds all information required to evaluate constexpr code in a module.
Definition: Context.h:40
const LangOptions & getLangOpts() const
Returns the language options.
Definition: Context.cpp:89
std::optional< PrimType > classify(QualType T) const
Classifies an expression.
Definition: Context.cpp:91
Scope used to handle temporaries in toplevel variable declarations.
Emits the destructors of the variables of.
DestructorScope(LocalScope< Emitter > &OtherScope)
Expression scope which tracks potentially lifetime extended temporaries which are hoisted to the pare...
void addExtended(const Scope::Local &Local) override
ExprScope(ByteCodeExprGen< Emitter > *Ctx)
Bytecode function.
Definition: Function.h:76
Generic scope for local variables.
~LocalScope() override
Emit a Destroy op for this scope.
void emitDestruction() override
Overriden to support explicit destruction.
void emitDestructors() override
void addLocal(const Scope::Local &Local) override
std::optional< unsigned > Idx
Index of the scope in the chain.
LocalScope(ByteCodeExprGen< Emitter > *Ctx)
Scope used to handle initialization methods.
The program contains and links the bytecode for all functions.
Definition: Program.h:40
Structure/Class descriptor.
Definition: Record.h:25
Describes the statement/declaration an opcode was generated from.
Definition: Source.h:72
SourceLocScope(ByteCodeExprGen< Emitter > *Ctx, const Expr *DefaultExpr)
Scope chain managing the variable lifetimes.
virtual void addExtended(const Scope::Local &Local)
void add(const Scope::Local &Local, bool IsExtended)
VariableScope * Parent
Link to the parent scope.
virtual void addLocal(const Scope::Local &Local)
VariableScope(ByteCodeExprGen< Emitter > *Ctx)
VariableScope * getParent() const
ByteCodeExprGen< Emitter > * Ctx
ByteCodeExprGen instance.
Defines the clang::TargetInfo interface.
PrimType
Enumeration of the primitive types of the VM.
Definition: PrimType.h:32
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
Definition: Descriptor.h:27
Information about a local's storage.
Definition: Function.h:37