clang 10.0.0git

ByteCodeExprGen.cpp
Go to the documentation of this file.
1 //===--- ByteCodeExprGen.cpp - 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 #include "ByteCodeExprGen.h"
10 #include "ByteCodeEmitter.h"
11 #include "ByteCodeGenError.h"
12 #include "Context.h"
13 #include "Function.h"
14 #include "PrimType.h"
15 #include "Program.h"
16 #include "State.h"
17
18 using namespace clang;
19 using namespace clang::interp;
20
21 using APSInt = llvm::APSInt;
22 template <typename T> using Expected = llvm::Expected<T>;
23 template <typename T> using Optional = llvm::Optional<T>;
24
25 namespace clang {
26 namespace interp {
27
28 /// Scope used to handle temporaries in toplevel variable declarations.
29 template <class Emitter> class DeclScope final : public LocalScope<Emitter> {
30 public:
31 DeclScope(ByteCodeExprGen<Emitter> *Ctx, const VarDecl *VD)
32 : LocalScope<Emitter>(Ctx), Scope(Ctx->P, VD) {}
33
34 void addExtended(const Scope::Local &Local) override {
35 return this->addLocal(Local);
36 }
37
38 private:
39 Program::DeclScope Scope;
40 };
41
42 /// Scope used to handle initialization methods.
43 template <class Emitter> class OptionScope {
44 public:
45 using InitFnRef = typename ByteCodeExprGen<Emitter>::InitFnRef;
46 using ChainedInitFnRef = std::function<bool(InitFnRef)>;
47
48 /// Root constructor, compiling or discarding primitives.
49 OptionScope(ByteCodeExprGen<Emitter> *Ctx, bool NewDiscardResult)
50 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
51 OldInitFn(std::move(Ctx->InitFn)) {
52 Ctx->DiscardResult = NewDiscardResult;
53 Ctx->InitFn = llvm::Optional<InitFnRef>{};
54 }
55
56 /// Root constructor, setting up compilation state.
57 OptionScope(ByteCodeExprGen<Emitter> *Ctx, InitFnRef NewInitFn)
58 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
59 OldInitFn(std::move(Ctx->InitFn)) {
60 Ctx->DiscardResult = true;
61 Ctx->InitFn = NewInitFn;
62 }
63
64 /// Extends the chain of initialisation pointers.
65 OptionScope(ByteCodeExprGen<Emitter> *Ctx, ChainedInitFnRef NewInitFn)
66 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
67 OldInitFn(std::move(Ctx->InitFn)) {
68 assert(OldInitFn && "missing initializer");
69 Ctx->InitFn = [this, NewInitFn] { return NewInitFn(*OldInitFn); };
70 }
71
72 ~OptionScope() {
73 Ctx->DiscardResult = OldDiscardResult;
74 Ctx->InitFn = std::move(OldInitFn);
75 }
76
77 private:
78 /// Parent context.
79 ByteCodeExprGen<Emitter> *Ctx;
80 /// Old discard flag to restore.
81 bool OldDiscardResult;
82 /// Old pointer emitter to restore.
83 llvm::Optional<InitFnRef> OldInitFn;
84 };
85
86 } // namespace interp
87 } // namespace clang
88
89 template <class Emitter>
90 bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
91 auto *SubExpr = CE->getSubExpr();
92 switch (CE->getCastKind()) {
93
94 case CK_LValueToRValue: {
95 return dereference(
96 CE->getSubExpr(), DerefKind::Read,
97 [](PrimType) {
98 // Value loaded - nothing to do here.
99 return true;
100 },
101 [this, CE](PrimType T) {
102 // Pointer on stack - dereference it.
103 if (!this->emitLoadPop(T, CE))
104 return false;
105 return DiscardResult ? this->emitPop(T, CE) : true;
106 });
107 }
108
109 case CK_ArrayToPointerDecay:
110 case CK_AtomicToNonAtomic:
111 case CK_ConstructorConversion:
112 case CK_FunctionToPointerDecay:
113 case CK_NonAtomicToAtomic:
114 case CK_NoOp:
115 case CK_UserDefinedConversion:
116 return this->Visit(SubExpr);
117
118 case CK_ToVoid:
119 return discard(SubExpr);
120
121 default: {
122 // TODO: implement other casts.
123 return this->bail(CE);
124 }
125 }
126 }
127
128 template <class Emitter>
129 bool ByteCodeExprGen<Emitter>::VisitIntegerLiteral(const IntegerLiteral *LE) {
130 if (DiscardResult)
131 return true;
132
133 auto Val = LE->getValue();
134 QualType LitTy = LE->getType();
135 if (Optional<PrimType> T = classify(LitTy))
136 return emitConst(*T, getIntWidth(LitTy), LE->getValue(), LE);
137 return this->bail(LE);
138 }
139
140 template <class Emitter>
141 bool ByteCodeExprGen<Emitter>::VisitParenExpr(const ParenExpr *PE) {
142 return this->Visit(PE->getSubExpr());
143 }
144
145 template <class Emitter>
146 bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
147 const Expr *LHS = BO->getLHS();
148 const Expr *RHS = BO->getRHS();
149
150 // Deal with operations which have composite or void types.
151 switch (BO->getOpcode()) {
152 case BO_Comma:
153 if (!discard(LHS))
154 return false;
155 if (!this->Visit(RHS))
156 return false;
157 return true;
158 default:
159 break;
160 }
161
162 // Typecheck the args.
163 Optional<PrimType> LT = classify(LHS->getType());
164 Optional<PrimType> RT = classify(RHS->getType());
165 if (!LT || !RT) {
166 return this->bail(BO);
167 }
168
169 if (Optional<PrimType> T = classify(BO->getType())) {
170 if (!visit(LHS))
171 return false;
172 if (!visit(RHS))
173 return false;
174
175 auto Discard = [this, T, BO](bool Result) {
176 if (!Result)
177 return false;
178 return DiscardResult ? this->emitPop(*T, BO) : true;
179 };
180
181 switch (BO->getOpcode()) {
182 case BO_EQ:
183 return Discard(this->emitEQ(*LT, BO));
184 case BO_NE:
185 return Discard(this->emitNE(*LT, BO));
186 case BO_LT:
187 return Discard(this->emitLT(*LT, BO));
188 case BO_LE:
189 return Discard(this->emitLE(*LT, BO));
190 case BO_GT:
191 return Discard(this->emitGT(*LT, BO));
192 case BO_GE:
193 return Discard(this->emitGE(*LT, BO));
194 case BO_Sub:
195 return Discard(this->emitSub(*T, BO));
196 case BO_Add:
197 return Discard(this->emitAdd(*T, BO));
198 case BO_Mul:
199 return Discard(this->emitMul(*T, BO));
200 default:
201 return this->bail(BO);
202 }
203 }
204
205 return this->bail(BO);
206 }
207
208 template <class Emitter>
209 bool ByteCodeExprGen<Emitter>::discard(const Expr *E) {
210 OptionScope<Emitter> Scope(this, /*discardResult=*/true);
211 return this->Visit(E);
212 }
213
214 template <class Emitter>
215 bool ByteCodeExprGen<Emitter>::visit(const Expr *E) {
216 OptionScope<Emitter> Scope(this, /*discardResult=*/false);
217 return this->Visit(E);
218 }
219
220 template <class Emitter>
221 bool ByteCodeExprGen<Emitter>::visitBool(const Expr *E) {
222 if (Optional<PrimType> T = classify(E->getType())) {
223 return visit(E);
224 } else {
225 return this->bail(E);
226 }
227 }
228
229 template <class Emitter>
230 bool ByteCodeExprGen<Emitter>::visitZeroInitializer(PrimType T, const Expr *E) {
231 switch (T) {
232 case PT_Bool:
233 return this->emitZeroBool(E);
234 case PT_Sint8:
235 return this->emitZeroSint8(E);
236 case PT_Uint8:
237 return this->emitZeroUint8(E);
238 case PT_Sint16:
239 return this->emitZeroSint16(E);
240 case PT_Uint16:
241 return this->emitZeroUint16(E);
242 case PT_Sint32:
243 return this->emitZeroSint32(E);
244 case PT_Uint32:
245 return this->emitZeroUint32(E);
246 case PT_Sint64:
247 return this->emitZeroSint64(E);
248 case PT_Uint64:
249 return this->emitZeroUint64(E);
250 case PT_Ptr:
251 return this->emitNullPtr(E);
252 }
253 llvm_unreachable("unknown primitive type");
254 }
255
256 template <class Emitter>
257 bool ByteCodeExprGen<Emitter>::dereference(
258 const Expr *LV, DerefKind AK, llvm::function_ref<bool(PrimType)> Direct,
259 llvm::function_ref<bool(PrimType)> Indirect) {
260 if (Optional<PrimType> T = classify(LV->getType())) {
261 if (!LV->refersToBitField()) {
262 // Only primitive, non bit-field types can be dereferenced directly.
263 if (auto *DE = dyn_cast<DeclRefExpr>(LV)) {
264 if (!DE->getDecl()->getType()->isReferenceType()) {
265 if (auto *PD = dyn_cast<ParmVarDecl>(DE->getDecl()))
266 return dereferenceParam(LV, *T, PD, AK, Direct, Indirect);
267 if (auto *VD = dyn_cast<VarDecl>(DE->getDecl()))
268 return dereferenceVar(LV, *T, VD, AK, Direct, Indirect);
269 }
270 }
271 }
272
273 if (!visit(LV))
274 return false;
275 return Indirect(*T);
276 }
277
278 return false;
279 }
280
281 template <class Emitter>
282 bool ByteCodeExprGen<Emitter>::dereferenceParam(
283 const Expr *LV, PrimType T, const ParmVarDecl *PD, DerefKind AK,
284 llvm::function_ref<bool(PrimType)> Direct,
285 llvm::function_ref<bool(PrimType)> Indirect) {
286 auto It = this->Params.find(PD);
287 if (It != this->Params.end()) {
288 unsigned Idx = It->second;
289 switch (AK) {
290 case DerefKind::Read:
291 return DiscardResult ? true : this->emitGetParam(T, Idx, LV);
292
293 case DerefKind::Write:
294 if (!Direct(T))
295 return false;
296 if (!this->emitSetParam(T, Idx, LV))
297 return false;
298 return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
299
300 case DerefKind::ReadWrite:
301 if (!this->emitGetParam(T, Idx, LV))
302 return false;
303 if (!Direct(T))
304 return false;
305 if (!this->emitSetParam(T, Idx, LV))
306 return false;
307 return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
308 }
309 return true;
310 }
311
312 // If the param is a pointer, we can dereference a dummy value.
313 if (!DiscardResult && T == PT_Ptr && AK == DerefKind::Read) {
314 if (auto Idx = P.getOrCreateDummy(PD))
315 return this->emitGetPtrGlobal(*Idx, PD);
316 return false;
317 }
318
319 // Value cannot be produced - try to emit pointer and do stuff with it.
320 return visit(LV) && Indirect(T);
321 }
322
323 template <class Emitter>
324 bool ByteCodeExprGen<Emitter>::dereferenceVar(
325 const Expr *LV, PrimType T, const VarDecl *VD, DerefKind AK,
326 llvm::function_ref<bool(PrimType)> Direct,
327 llvm::function_ref<bool(PrimType)> Indirect) {
328 auto It = Locals.find(VD);
329 if (It != Locals.end()) {
330 const auto &L = It->second;
331 switch (AK) {
332 case DerefKind::Read:
333 if (!this->emitGetLocal(T, L.Offset, LV))
334 return false;
335 return DiscardResult ? this->emitPop(T, LV) : true;
336
337 case DerefKind::Write:
338 if (!Direct(T))
339 return false;
340 if (!this->emitSetLocal(T, L.Offset, LV))
341 return false;
342 return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV);
343
344 case DerefKind::ReadWrite:
345 if (!this->emitGetLocal(T, L.Offset, LV))
346 return false;
347 if (!Direct(T))
348 return false;
349 if (!this->emitSetLocal(T, L.Offset, LV))
350 return false;
351 return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV);
352 }
353 } else if (auto Idx = getGlobalIdx(VD)) {
354 switch (AK) {
355 case DerefKind::Read:
356 if (!this->emitGetGlobal(T, *Idx, LV))
357 return false;
358 return DiscardResult ? this->emitPop(T, LV) : true;
359
360 case DerefKind::Write:
361 if (!Direct(T))
362 return false;
363 if (!this->emitSetGlobal(T, *Idx, LV))
364 return false;
365 return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV);
366
367 case DerefKind::ReadWrite:
368 if (!this->emitGetGlobal(T, *Idx, LV))
369 return false;
370 if (!Direct(T))
371 return false;
372 if (!this->emitSetGlobal(T, *Idx, LV))
373 return false;
374 return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV);
375 }
376 }
377
378 // If the declaration is a constant value, emit it here even
379 // though the declaration was not evaluated in the current scope.
380 // The access mode can only be read in this case.
381 if (!DiscardResult && AK == DerefKind::Read) {
382 if (VD->hasLocalStorage() && VD->hasInit() && !VD->isConstexpr()) {
383 QualType VT = VD->getType();
384 if (VT.isConstQualified() && VT->isFundamentalType())
385 return this->Visit(VD->getInit());
386 }
387 }
388
389 // Value cannot be produced - try to emit pointer.
390 return visit(LV) && Indirect(T);
391 }
392
393 template <class Emitter>
394 bool ByteCodeExprGen<Emitter>::emitConst(PrimType T, unsigned NumBits,
395 const APInt &Value, const Expr *E) {
396 switch (T) {
397 case PT_Sint8:
398 return this->emitConstSint8(Value.getSExtValue(), E);
399 case PT_Uint8:
400 return this->emitConstUint8(Value.getZExtValue(), E);
401 case PT_Sint16:
402 return this->emitConstSint16(Value.getSExtValue(), E);
403 case PT_Uint16:
404 return this->emitConstUint16(Value.getZExtValue(), E);
405 case PT_Sint32:
406 return this->emitConstSint32(Value.getSExtValue(), E);
407 case PT_Uint32:
408 return this->emitConstUint32(Value.getZExtValue(), E);
409 case PT_Sint64:
410 return this->emitConstSint64(Value.getSExtValue(), E);
411 case PT_Uint64:
412 return this->emitConstUint64(Value.getZExtValue(), E);
413 case PT_Bool:
414 return this->emitConstBool(Value.getBoolValue(), E);
415 case PT_Ptr:
416 llvm_unreachable("Invalid integral type");
417 break;
418 }
419 llvm_unreachable("unknown primitive type");
420 }
421
422 template <class Emitter>
423 unsigned ByteCodeExprGen<Emitter>::allocateLocalPrimitive(DeclTy &&Src,
424 PrimType Ty,
425 bool IsConst,
426 bool IsExtended) {
427 Descriptor *D = P.createDescriptor(Src, Ty, IsConst, Src.is<const Expr *>());
428 Scope::Local Local = this->createLocal(D);
429 if (auto *VD = dyn_cast_or_null<ValueDecl>(Src.dyn_cast<const Decl *>()))
430 Locals.insert({VD, Local});
431 VarScope->add(Local, IsExtended);
432 return Local.Offset;
433 }
434
435 template <class Emitter>
436 llvm::Optional<unsigned>
437 ByteCodeExprGen<Emitter>::allocateLocal(DeclTy &&Src, bool IsExtended) {
438 QualType Ty;
439
440 const ValueDecl *Key = nullptr;
441 bool IsTemporary = false;
442 if (auto *VD = dyn_cast_or_null<ValueDecl>(Src.dyn_cast<const Decl *>())) {
443 Key = VD;
444 Ty = VD->getType();
445 }
446 if (auto *E = Src.dyn_cast<const Expr *>()) {
447 IsTemporary = true;
448 Ty = E->getType();
449 }
450
451 Descriptor *D = P.createDescriptor(Src, Ty.getTypePtr(),
452 Ty.isConstQualified(), IsTemporary);
453 if (!D)
454 return {};
455
456 Scope::Local Local = this->createLocal(D);
457 if (Key)
458 Locals.insert({Key, Local});
459 VarScope->add(Local, IsExtended);
460 return Local.Offset;
461 }
462
463 template <class Emitter>
464 bool ByteCodeExprGen<Emitter>::visitInitializer(
465 const Expr *Init, InitFnRef InitFn) {
466 OptionScope<Emitter> Scope(this, InitFn);
467 return this->Visit(Init);
468 }
469
470 template <class Emitter>
471 bool ByteCodeExprGen<Emitter>::getPtrVarDecl(const VarDecl *VD, const Expr *E) {
472 // Generate a pointer to the local, loading refs.
473 if (Optional<unsigned> Idx = getGlobalIdx(VD)) {
474 if (VD->getType()->isReferenceType())
475 return this->emitGetGlobalPtr(*Idx, E);
476 else
477 return this->emitGetPtrGlobal(*Idx, E);
478 }
479 return this->bail(VD);
480 }
481
482 template <class Emitter>
483 llvm::Optional<unsigned>
484 ByteCodeExprGen<Emitter>::getGlobalIdx(const VarDecl *VD) {
485 if (VD->isConstexpr()) {
486 // Constexpr decl - it must have already been defined.
487 return P.getGlobal(VD);
488 }
489 if (!VD->hasLocalStorage()) {
490 // Not constexpr, but a global var - can have pointer taken.
491 Program::DeclScope Scope(P, VD);
492 return P.getOrCreateGlobal(VD);
493 }
494 return {};
495 }
496
497 template <class Emitter>
498 const RecordType *ByteCodeExprGen<Emitter>::getRecordTy(QualType Ty) {
499 if (auto *PT = dyn_cast<PointerType>(Ty))
500 return PT->getPointeeType()->getAs<RecordType>();
501 else
502 return Ty->getAs<RecordType>();
503 }
504
505 template <class Emitter>
506 Record *ByteCodeExprGen<Emitter>::getRecord(QualType Ty) {
507 if (auto *RecordTy = getRecordTy(Ty)) {
508 return getRecord(RecordTy->getDecl());
509 }
510 return nullptr;
511 }
512
513 template <class Emitter>
514 Record *ByteCodeExprGen<Emitter>::getRecord(const RecordDecl *RD) {
515 return P.getOrCreateRecord(RD);
516 }
517
518 template <class Emitter>
519 bool ByteCodeExprGen<Emitter>::visitExpr(const Expr *Exp) {
520 ExprScope<Emitter> RootScope(this);
521 if (!visit(Exp))
522 return false;
523
524 if (Optional<PrimType> T = classify(Exp))
525 return this->emitRet(*T, Exp);
526 else
527 return this->emitRetValue(Exp);
528 }
529
530 template <class Emitter>
531 bool ByteCodeExprGen<Emitter>::visitDecl(const VarDecl *VD) {
532 const Expr *Init = VD->getInit();
533
534 if (Optional<unsigned> I = P.createGlobal(VD)) {
535 if (Optional<PrimType> T = classify(VD->getType())) {
536 {
537 // Primitive declarations - compute the value and set it.
538 DeclScope<Emitter> LocalScope(this, VD);
539 if (!visit(Init))
540 return false;
541 }
542
543 // If the declaration is global, save the value for later use.
544 if (!this->emitDup(*T, VD))
545 return false;
546 if (!this->emitInitGlobal(*T, *I, VD))
547 return false;
548 return this->emitRet(*T, VD);
549 } else {
550 {
551 // Composite declarations - allocate storage and initialize it.
552 DeclScope<Emitter> LocalScope(this, VD);
553 if (!visitGlobalInitializer(Init, *I))
554 return false;
555 }
556
557 // Return a pointer to the global.
558 if (!this->emitGetPtrGlobal(*I, VD))
559 return false;
560 return this->emitRetValue(VD);
561 }
562 }
563
564 return this->bail(VD);
565 }
566
567 template <class Emitter>
568 void ByteCodeExprGen<Emitter>::emitCleanup() {
569 for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent())
570 C->emitDestruction();
571 }
572
573 namespace clang {
574 namespace interp {
575
576 template class ByteCodeExprGen<ByteCodeEmitter>;
577 template class ByteCodeExprGen<EvalEmitter>;
578
579 } // namespace interp
580 } // namespace clang
clang::interp::DeclTy
unsigned llvm::PointerUnion< const Decl *, const Expr * > DeclTy
Definition: Descriptor.h:26
clang::interp::VariableScope
Scope chain managing the variable lifetimes.
Definition: ByteCodeExprGen.h:35
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:654
clang::interp::OptionScope::ChainedInitFnRef
std::function< bool(InitFnRef)> ChainedInitFnRef
Definition: ByteCodeExprGen.cpp:46
clang::interp::PT_Sint64
Definition: PrimType.h:34
clang::Type::getPointeeType
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:557
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
clang::BinaryOperator::getOpcode
Opcode getOpcode() const
Definition: Expr.h:3469
P
StringRef P
Definition: ASTMatchersInternal.cpp:485
clang::ParenExpr
ParenExpr - This represents a parethesized expression, e.g.
Definition: Expr.h:1994
clang::interp::ByteCodeExprGen::VisitCastExpr
bool VisitCastExpr(const CastExpr *E)
Definition: ByteCodeExprGen.cpp:90
clang::IntegerLiteral
Definition: Expr.h:1446
ByteCodeEmitter.h
Value
Value
Definition: UninitializedValues.cpp:101
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:820
clang::interp::ByteCodeExprGen::visitInitializer
bool visitInitializer(const Expr *E, InitFnRef GenPtr)
Compiles an initializer for a local.
Definition: ByteCodeExprGen.cpp:464
clang::interp::PT_Sint16
Definition: PrimType.h:30
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:7002
clang::ParmVarDecl
Represents a parameter to a function.
Definition: Decl.h:1595
clang::interp::ByteCodeExprGen::VisitIntegerLiteral
bool VisitIntegerLiteral(const IntegerLiteral *E)
Definition: ByteCodeExprGen.cpp:129
clang::RecordDecl
Represents a struct/union/class.
Definition: Decl.h:3748
clang::interp::ByteCodeExprGen::visitDecl
bool visitDecl(const VarDecl *VD) override
Definition: ByteCodeExprGen.cpp:531
llvm::Optional
Definition: LLVM.h:37
clang::interp::PT_Uint8
Definition: PrimType.h:29
std
Definition: Format.h:2445
clang::Type::isReferenceType
bool isReferenceType() const
Definition: Type.h:6516
dereference
static llvm::Optional< DereferenceInfo > dereference(ProgramStateRef State, const FieldRegion *FR)
Dereferences FR and returns with the pointee&#39;s region, and whether it needs to be casted back to it&#39;s...
Definition: UninitializedPointee.cpp:222
clang::interp::ByteCodeExprGen::visit
bool visit(const Expr *E)
Evaluates an expression and places result on stack.
Definition: ByteCodeExprGen.cpp:215
clang::interp::ByteCodeExprGen::InitFn
llvm::Optional< InitFnRef > InitFn
Expression being initialized.
Definition: ByteCodeExprGen.h:233
PrimType.h
clang::CastExpr::getSubExpr
Expr * getSubExpr()
Definition: Expr.h:3202
clang::interp::PT_Bool
Definition: PrimType.h:36
clang::interp::Record
Structure/Class descriptor.
Definition: Record.h:23
clang::interp::OptionScope::InitFnRef
typename ByteCodeExprGen< Emitter >::InitFnRef InitFnRef
Definition: ByteCodeExprGen.cpp:45
Context.h
llvm::Expected
Definition: LLVM.h:38
clang::interp::ByteCodeExprGen::visitBool
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
Definition: ByteCodeExprGen.cpp:221
clang::Expr::refersToBitField
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
Definition: Expr.h:446
clang::interp::PrimType
PrimType
Enumeration of the primitive types of the VM.
Definition: PrimType.h:27
clang::interp::Program::DeclScope
Context to manage declaration lifetimes.
Definition: Program.h:114
clang::BinaryOperator
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3434
clang::VarDecl::isConstexpr
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition: Decl.h:1412
clang::QualType::getTypePtr
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6256
clang::CastExpr
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3150
clang::interp::Descriptor
Describes a memory block created by an allocation site.
Definition: Descriptor.h:51
clang::interp::ExprScope
Expression scope which tracks potentially lifetime extended temporaries which are hoisted to the pare...
Definition: ByteCodeExprGen.h:319
clang::interp::ByteCodeExprGen::VisitBinaryOperator
bool VisitBinaryOperator(const BinaryOperator *E)
Definition: ByteCodeExprGen.cpp:146
clang::interp::OptionScope::OptionScope
OptionScope(ByteCodeExprGen< Emitter > *Ctx, InitFnRef NewInitFn)
Root constructor, setting up compilation state.
Definition: ByteCodeExprGen.cpp:57
clang::interp::ByteCodeExprGen::discard
bool discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
Definition: ByteCodeExprGen.cpp:209
clang::ValueDecl
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:619
clang::Expr
This represents one expression.
Definition: Expr.h:108
clang::VarDecl::hasLocalStorage
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Definition: Decl.h:1045
clang::interp::Scope::Local
Information about a local&#39;s storage.
Definition: Function.h:35
clang::interp::ByteCodeExprGen::InitFnRef
std::function< bool()> InitFnRef
Definition: ByteCodeExprGen.h:55
clang::Expr::getType
QualType getType() const
Definition: Expr.h:137
clang::interp::ByteCodeExprGen::emitCleanup
void emitCleanup()
Emits scope cleanup instructions.
Definition: ByteCodeExprGen.cpp:568
clang::interp::Scope::Local::Offset
unsigned Offset
Offset of the local in frame.
Definition: Function.h:37
clang::ParenExpr::getSubExpr
const Expr * getSubExpr() const
Definition: Expr.h:2010
Program.h
clang::interp::OptionScope::OptionScope
OptionScope(ByteCodeExprGen< Emitter > *Ctx, ChainedInitFnRef NewInitFn)
Extends the chain of initialisation pointers.
Definition: ByteCodeExprGen.cpp:65
ByteCodeGenError.h
APSInt
llvm::APSInt APSInt
Definition: ByteCodeExprGen.cpp:21
clang::QualType::isConstQualified
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:6315
APSInt
llvm::APSInt APSInt
Definition: ByteCodeEmitter.cpp:18
clang::CastExpr::getCastKind
CastKind getCastKind() const
Definition: Expr.h:3196
clang::interp::PT_Sint32
Definition: PrimType.h:32
clang::interp::DeclScope::addExtended
void addExtended(const Scope::Local &Local) override
Definition: ByteCodeExprGen.cpp:34
clang::interp::PT_Uint16
Definition: PrimType.h:31
clang::interp::ByteCodeExprGen::getRecord
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
Definition: ByteCodeExprGen.cpp:506
clang::interp::DeclScope
Scope used to handle temporaries in toplevel variable declarations.
Definition: ByteCodeExprGen.cpp:29
clang::interp::APInt
llvm::APInt APInt
Definition: Integral.h:27
clang::interp::OptionScope
Scope used to handle initialization methods.
Definition: ByteCodeExprGen.cpp:43
Emitter
clang::BinaryOperator::getLHS
Expr * getLHS() const
Definition: Expr.h:3474
State.h
clang
Dataflow Directional Tag Classes.
Definition: CFGReachabilityAnalysis.h:21
clang::interp::ByteCodeExprGen::DiscardResult
bool DiscardResult
Flag indicating if return value is to be discarded.
Definition: ByteCodeExprGen.h:230
Function.h
clang::VarDecl::getInit
const Expr * getInit() const
Definition: Decl.h:1229
clang::interp::PT_Ptr
Definition: PrimType.h:37
clang::interp::DeclScope::DeclScope
DeclScope(ByteCodeExprGen< Emitter > *Ctx, const VarDecl *VD)
Definition: ByteCodeExprGen.cpp:31
clang::interp::ByteCodeExprGen::getRecordTy
const RecordType * getRecordTy(QualType Ty)
Returns a record type from a record or pointer type.
Definition: ByteCodeExprGen.cpp:498
clang::interp::ByteCodeExprGen::visitExpr
bool visitExpr(const Expr *E) override
Definition: ByteCodeExprGen.cpp:519
clang::APIntStorage::getValue
llvm::APInt getValue() const
Definition: Expr.h:1430
clang::interp::PT_Sint8
Definition: PrimType.h:28
clang::RecordType
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4495
clang::interp::OptionScope::~OptionScope
~OptionScope()
Definition: ByteCodeExprGen.cpp:72
clang::interp::LocalScope
Scope for local variables.
Definition: ByteCodeExprGen.h:33
clang::interp::ByteCodeExprGen::VisitParenExpr
bool VisitParenExpr(const ParenExpr *E)
Definition: ByteCodeExprGen.cpp:141
clang::interp::ByteCodeExprGen
Compilation context for expressions.
Definition: ByteCodeExprGen.h:41
clang::interp::LE
bool LE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:237
clang::interp
Definition: ASTContext.h:146
ByteCodeExprGen.h
clang::interp::Scope
Describes a scope block.
Definition: Function.h:32
clang::Type::isFundamentalType
bool isFundamentalType() const
Tests whether the type is categorized as a fundamental type.
Definition: Type.h:6467
clang::BinaryOperator::getRHS
Expr * getRHS() const
Definition: Expr.h:3476
clang::ValueDecl::getType
QualType getType() const
Definition: Decl.h:630
true
#define true
Definition: stdbool.h:16
clang::interp::PT_Uint64
Definition: PrimType.h:35
clang::interp::OptionScope::OptionScope
OptionScope(ByteCodeExprGen< Emitter > *Ctx, bool NewDiscardResult)
Root constructor, compiling or discarding primitives.
Definition: ByteCodeExprGen.cpp:49
clang::interp::ByteCodeExprGen::allocateLocal
llvm::Optional< unsigned > allocateLocal(DeclTy &&Decl, bool IsExtended=false)
Allocates a space storing a local given its type.
Definition: ByteCodeExprGen.cpp:437
clang::interp::ByteCodeExprGen::allocateLocalPrimitive
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsMutable, bool IsExtended=false)
Creates a local primitive value.
Definition: ByteCodeExprGen.cpp:423
clang::VarDecl::hasInit
bool hasInit() const
Definition: Decl.cpp:2226
clang::interp::LT
bool LT(InterpState &S, CodePtr OpPC)
Definition: Interp.h:230
clang::interp::PT_Uint32
Definition: PrimType.h:33