clang 18.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 "ByteCodeStmtGen.h"
13#include "Context.h"
14#include "Floating.h"
15#include "Function.h"
16#include "PrimType.h"
17#include "Program.h"
18#include "State.h"
19
20using namespace clang;
21using namespace clang::interp;
22
23using APSInt = llvm::APSInt;
24
25namespace clang {
26namespace interp {
27
28/// Scope used to handle temporaries in toplevel variable declarations.
29template <class Emitter> class DeclScope final : public VariableScope<Emitter> {
30public:
32 : VariableScope<Emitter>(Ctx), Scope(Ctx->P, VD) {}
33
34 void addExtended(const Scope::Local &Local) override {
35 return this->addLocal(Local);
36 }
37
38private:
40};
41
42/// Scope used to handle initialization methods.
43template <class Emitter> class OptionScope final {
44public:
45 /// Root constructor, compiling or discarding primitives.
46 OptionScope(ByteCodeExprGen<Emitter> *Ctx, bool NewDiscardResult,
47 bool NewInitializing)
48 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
49 OldInitializing(Ctx->Initializing) {
50 Ctx->DiscardResult = NewDiscardResult;
51 Ctx->Initializing = NewInitializing;
52 }
53
55 Ctx->DiscardResult = OldDiscardResult;
56 Ctx->Initializing = OldInitializing;
57 }
58
59private:
60 /// Parent context.
62 /// Old discard flag to restore.
63 bool OldDiscardResult;
64 bool OldInitializing;
65};
66
67} // namespace interp
68} // namespace clang
69
70template <class Emitter>
72 auto *SubExpr = CE->getSubExpr();
73 switch (CE->getCastKind()) {
74
75 case CK_LValueToRValue: {
76 return dereference(
77 SubExpr, DerefKind::Read,
78 [](PrimType) {
79 // Value loaded - nothing to do here.
80 return true;
81 },
82 [this, CE](PrimType T) {
83 // Pointer on stack - dereference it.
84 if (!this->emitLoadPop(T, CE))
85 return false;
86 return DiscardResult ? this->emitPop(T, CE) : true;
87 });
88 }
89
90 case CK_UncheckedDerivedToBase:
91 case CK_DerivedToBase: {
92 if (!this->visit(SubExpr))
93 return false;
94
95 unsigned DerivedOffset = collectBaseOffset(getRecordTy(CE->getType()),
96 getRecordTy(SubExpr->getType()));
97
98 return this->emitGetPtrBasePop(DerivedOffset, CE);
99 }
100
101 case CK_BaseToDerived: {
102 if (!this->visit(SubExpr))
103 return false;
104
105 unsigned DerivedOffset = collectBaseOffset(getRecordTy(SubExpr->getType()),
106 getRecordTy(CE->getType()));
107
108 return this->emitGetPtrDerivedPop(DerivedOffset, CE);
109 }
110
111 case CK_FloatingCast: {
112 if (!this->visit(SubExpr))
113 return false;
114 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
115 return this->emitCastFP(TargetSemantics, getRoundingMode(CE), CE);
116 }
117
118 case CK_IntegralToFloating: {
119 std::optional<PrimType> FromT = classify(SubExpr->getType());
120 if (!FromT)
121 return false;
122
123 if (!this->visit(SubExpr))
124 return false;
125
126 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
127 llvm::RoundingMode RM = getRoundingMode(CE);
128 return this->emitCastIntegralFloating(*FromT, TargetSemantics, RM, CE);
129 }
130
131 case CK_FloatingToBoolean:
132 case CK_FloatingToIntegral: {
133 std::optional<PrimType> ToT = classify(CE->getType());
134
135 if (!ToT)
136 return false;
137
138 if (!this->visit(SubExpr))
139 return false;
140
141 return this->emitCastFloatingIntegral(*ToT, CE);
142 }
143
144 case CK_NullToPointer:
145 if (DiscardResult)
146 return true;
147 return this->emitNull(classifyPrim(CE->getType()), CE);
148
149 case CK_PointerToIntegral: {
150 // TODO: Discard handling.
151 if (!this->visit(SubExpr))
152 return false;
153
154 PrimType T = classifyPrim(CE->getType());
155 return this->emitCastPointerIntegral(T, CE);
156 }
157
158 case CK_ArrayToPointerDecay:
159 case CK_AtomicToNonAtomic:
160 case CK_ConstructorConversion:
161 case CK_FunctionToPointerDecay:
162 case CK_NonAtomicToAtomic:
163 case CK_NoOp:
164 case CK_UserDefinedConversion:
165 case CK_BitCast:
166 return this->delegate(SubExpr);
167
168 case CK_IntegralToBoolean:
169 case CK_IntegralCast: {
170 if (DiscardResult)
171 return this->discard(SubExpr);
172 std::optional<PrimType> FromT = classify(SubExpr->getType());
173 std::optional<PrimType> ToT = classify(CE->getType());
174 if (!FromT || !ToT)
175 return false;
176
177 if (!this->visit(SubExpr))
178 return false;
179
180 if (FromT == ToT)
181 return true;
182
183 return this->emitCast(*FromT, *ToT, CE);
184 }
185
186 case CK_PointerToBoolean: {
187 PrimType PtrT = classifyPrim(SubExpr->getType());
188
189 // Just emit p != nullptr for this.
190 if (!this->visit(SubExpr))
191 return false;
192
193 if (!this->emitNull(PtrT, CE))
194 return false;
195
196 return this->emitNE(PtrT, CE);
197 }
198
199 case CK_ToVoid:
200 return discard(SubExpr);
201
202 default:
203 assert(false && "Cast not implemented");
204 }
205 llvm_unreachable("Unhandled clang::CastKind enum");
206}
207
208template <class Emitter>
210 if (DiscardResult)
211 return true;
212
213 return this->emitConst(LE->getValue(), LE);
214}
215
216template <class Emitter>
218 if (DiscardResult)
219 return true;
220
221 return this->emitConstFloat(E->getValue(), E);
222}
223
224template <class Emitter>
226 return this->delegate(E->getSubExpr());
227}
228
229template <class Emitter>
231 // Need short-circuiting for these.
232 if (BO->isLogicalOp())
233 return this->VisitLogicalBinOp(BO);
234
235 const Expr *LHS = BO->getLHS();
236 const Expr *RHS = BO->getRHS();
237
238 if (BO->isPtrMemOp())
239 return this->visit(RHS);
240
241 // Typecheck the args.
242 std::optional<PrimType> LT = classify(LHS->getType());
243 std::optional<PrimType> RT = classify(RHS->getType());
244 std::optional<PrimType> T = classify(BO->getType());
245
246 // Deal with operations which have composite or void types.
247 if (BO->isCommaOp()) {
248 if (!this->discard(LHS))
249 return false;
250 if (RHS->getType()->isVoidType())
251 return this->discard(RHS);
252
253 return this->delegate(RHS);
254 }
255
256 if (!LT || !RT || !T)
257 return this->bail(BO);
258
259 // Pointer arithmetic special case.
260 if (BO->getOpcode() == BO_Add || BO->getOpcode() == BO_Sub) {
261 if (T == PT_Ptr || (LT == PT_Ptr && RT == PT_Ptr))
262 return this->VisitPointerArithBinOp(BO);
263 }
264
265 if (!visit(LHS) || !visit(RHS))
266 return false;
267
268 // For languages such as C, cast the result of one
269 // of our comparision opcodes to T (which is usually int).
270 auto MaybeCastToBool = [this, T, BO](bool Result) {
271 if (!Result)
272 return false;
273 if (DiscardResult)
274 return this->emitPop(*T, BO);
275 if (T != PT_Bool)
276 return this->emitCast(PT_Bool, *T, BO);
277 return true;
278 };
279
280 auto Discard = [this, T, BO](bool Result) {
281 if (!Result)
282 return false;
283 return DiscardResult ? this->emitPop(*T, BO) : true;
284 };
285
286 switch (BO->getOpcode()) {
287 case BO_EQ:
288 return MaybeCastToBool(this->emitEQ(*LT, BO));
289 case BO_NE:
290 return MaybeCastToBool(this->emitNE(*LT, BO));
291 case BO_LT:
292 return MaybeCastToBool(this->emitLT(*LT, BO));
293 case BO_LE:
294 return MaybeCastToBool(this->emitLE(*LT, BO));
295 case BO_GT:
296 return MaybeCastToBool(this->emitGT(*LT, BO));
297 case BO_GE:
298 return MaybeCastToBool(this->emitGE(*LT, BO));
299 case BO_Sub:
300 if (BO->getType()->isFloatingType())
301 return Discard(this->emitSubf(getRoundingMode(BO), BO));
302 return Discard(this->emitSub(*T, BO));
303 case BO_Add:
304 if (BO->getType()->isFloatingType())
305 return Discard(this->emitAddf(getRoundingMode(BO), BO));
306 return Discard(this->emitAdd(*T, BO));
307 case BO_Mul:
308 if (BO->getType()->isFloatingType())
309 return Discard(this->emitMulf(getRoundingMode(BO), BO));
310 return Discard(this->emitMul(*T, BO));
311 case BO_Rem:
312 return Discard(this->emitRem(*T, BO));
313 case BO_Div:
314 if (BO->getType()->isFloatingType())
315 return Discard(this->emitDivf(getRoundingMode(BO), BO));
316 return Discard(this->emitDiv(*T, BO));
317 case BO_Assign:
318 if (DiscardResult)
319 return this->emitStorePop(*T, BO);
320 return this->emitStore(*T, BO);
321 case BO_And:
322 return Discard(this->emitBitAnd(*T, BO));
323 case BO_Or:
324 return Discard(this->emitBitOr(*T, BO));
325 case BO_Shl:
326 return Discard(this->emitShl(*LT, *RT, BO));
327 case BO_Shr:
328 return Discard(this->emitShr(*LT, *RT, BO));
329 case BO_Xor:
330 return Discard(this->emitBitXor(*T, BO));
331 case BO_LOr:
332 case BO_LAnd:
333 llvm_unreachable("Already handled earlier");
334 default:
335 return this->bail(BO);
336 }
337
338 llvm_unreachable("Unhandled binary op");
339}
340
341/// Perform addition/subtraction of a pointer and an integer or
342/// subtraction of two pointers.
343template <class Emitter>
346 const Expr *LHS = E->getLHS();
347 const Expr *RHS = E->getRHS();
348
349 if ((Op != BO_Add && Op != BO_Sub) ||
350 (!LHS->getType()->isPointerType() && !RHS->getType()->isPointerType()))
351 return false;
352
353 std::optional<PrimType> LT = classify(LHS);
354 std::optional<PrimType> RT = classify(RHS);
355
356 if (!LT || !RT)
357 return false;
358
359 if (LHS->getType()->isPointerType() && RHS->getType()->isPointerType()) {
360 if (Op != BO_Sub)
361 return false;
362
363 assert(E->getType()->isIntegerType());
364 if (!visit(RHS) || !visit(LHS))
365 return false;
366
367 return this->emitSubPtr(classifyPrim(E->getType()), E);
368 }
369
370 PrimType OffsetType;
371 if (LHS->getType()->isIntegerType()) {
372 if (!visit(RHS) || !visit(LHS))
373 return false;
374 OffsetType = *LT;
375 } else if (RHS->getType()->isIntegerType()) {
376 if (!visit(LHS) || !visit(RHS))
377 return false;
378 OffsetType = *RT;
379 } else {
380 return false;
381 }
382
383 if (Op == BO_Add)
384 return this->emitAddOffset(OffsetType, E);
385 else if (Op == BO_Sub)
386 return this->emitSubOffset(OffsetType, E);
387
388 return this->bail(E);
389}
390
391template <class Emitter>
393 assert(E->isLogicalOp());
395 const Expr *LHS = E->getLHS();
396 const Expr *RHS = E->getRHS();
397 std::optional<PrimType> T = classify(E->getType());
398
399 if (Op == BO_LOr) {
400 // Logical OR. Visit LHS and only evaluate RHS if LHS was FALSE.
401 LabelTy LabelTrue = this->getLabel();
402 LabelTy LabelEnd = this->getLabel();
403
404 if (!this->visitBool(LHS))
405 return false;
406 if (!this->jumpTrue(LabelTrue))
407 return false;
408
409 if (!this->visitBool(RHS))
410 return false;
411 if (!this->jump(LabelEnd))
412 return false;
413
414 this->emitLabel(LabelTrue);
415 this->emitConstBool(true, E);
416 this->fallthrough(LabelEnd);
417 this->emitLabel(LabelEnd);
418
419 } else {
420 assert(Op == BO_LAnd);
421 // Logical AND.
422 // Visit LHS. Only visit RHS if LHS was TRUE.
423 LabelTy LabelFalse = this->getLabel();
424 LabelTy LabelEnd = this->getLabel();
425
426 if (!this->visitBool(LHS))
427 return false;
428 if (!this->jumpFalse(LabelFalse))
429 return false;
430
431 if (!this->visitBool(RHS))
432 return false;
433 if (!this->jump(LabelEnd))
434 return false;
435
436 this->emitLabel(LabelFalse);
437 this->emitConstBool(false, E);
438 this->fallthrough(LabelEnd);
439 this->emitLabel(LabelEnd);
440 }
441
442 if (DiscardResult)
443 return this->emitPopBool(E);
444
445 // For C, cast back to integer type.
446 assert(T);
447 if (T != PT_Bool)
448 return this->emitCast(PT_Bool, *T, E);
449 return true;
450}
451
452template <class Emitter>
454 QualType QT = E->getType();
455
456 if (classify(QT))
457 return this->visitZeroInitializer(QT, E);
458
459 if (QT->isRecordType())
460 return false;
461
462 if (QT->isArrayType()) {
463 const ArrayType *AT = QT->getAsArrayTypeUnsafe();
464 assert(AT);
465 const auto *CAT = cast<ConstantArrayType>(AT);
466 size_t NumElems = CAT->getSize().getZExtValue();
467
468 if (std::optional<PrimType> ElemT = classify(CAT->getElementType())) {
469 // TODO(perf): For int and bool types, we can probably just skip this
470 // since we memset our Block*s to 0 and so we have the desired value
471 // without this.
472 for (size_t I = 0; I != NumElems; ++I) {
473 if (!this->visitZeroInitializer(CAT->getElementType(), E))
474 return false;
475 if (!this->emitInitElem(*ElemT, I, E))
476 return false;
477 }
478 } else {
479 assert(false && "default initializer for non-primitive type");
480 }
481
482 return true;
483 }
484
485 return false;
486}
487
488template <class Emitter>
490 const ArraySubscriptExpr *E) {
491 const Expr *Base = E->getBase();
492 const Expr *Index = E->getIdx();
493
494 if (DiscardResult)
495 return this->discard(Base) && this->discard(Index);
496
497 // Take pointer of LHS, add offset from RHS.
498 // What's left on the stack after this is a pointer.
499 if (!this->visit(Base))
500 return false;
501
502 if (!this->visit(Index))
503 return false;
504
505 PrimType IndexT = classifyPrim(Index->getType());
506 return this->emitArrayElemPtrPop(IndexT, E);
507}
508
509template <class Emitter>
511 const Expr *E) {
512 assert(E->getType()->isRecordType());
513 const Record *R = getRecord(E->getType());
514
515 unsigned InitIndex = 0;
516 for (const Expr *Init : Inits) {
517 if (!this->emitDupPtr(E))
518 return false;
519
520 if (std::optional<PrimType> T = classify(Init)) {
521 const Record::Field *FieldToInit = R->getField(InitIndex);
522 if (!this->visit(Init))
523 return false;
524 if (!this->emitInitField(*T, FieldToInit->Offset, E))
525 return false;
526 if (!this->emitPopPtr(E))
527 return false;
528 ++InitIndex;
529 } else {
530 // Initializer for a direct base class.
531 if (const Record::Base *B = R->getBase(Init->getType())) {
532 if (!this->emitGetPtrBasePop(B->Offset, Init))
533 return false;
534
535 if (!this->visitInitializer(Init))
536 return false;
537
538 if (!this->emitPopPtr(E))
539 return false;
540 // Base initializers don't increase InitIndex, since they don't count
541 // into the Record's fields.
542 } else {
543 const Record::Field *FieldToInit = R->getField(InitIndex);
544 // Non-primitive case. Get a pointer to the field-to-initialize
545 // on the stack and recurse into visitInitializer().
546 if (!this->emitGetPtrField(FieldToInit->Offset, Init))
547 return false;
548
549 if (!this->visitInitializer(Init))
550 return false;
551
552 if (!this->emitPopPtr(E))
553 return false;
554 ++InitIndex;
555 }
556 }
557 }
558 return true;
559}
560
561template <class Emitter>
563 // Handle discarding first.
564 if (DiscardResult) {
565 for (const Expr *Init : E->inits()) {
566 if (!this->discard(Init))
567 return false;
568 }
569 return true;
570 }
571
572 // Primitive values.
573 if (std::optional<PrimType> T = classify(E->getType())) {
574 assert(!DiscardResult);
575 if (E->getNumInits() == 0)
576 return this->visitZeroInitializer(E->getType(), E);
577 assert(E->getNumInits() == 1);
578 return this->delegate(E->inits()[0]);
579 }
580
581 QualType T = E->getType();
582 if (T->isRecordType())
583 return this->visitInitList(E->inits(), E);
584
585 if (T->isArrayType()) {
586 // FIXME: Array fillers.
587 unsigned ElementIndex = 0;
588 for (const Expr *Init : E->inits()) {
589 if (std::optional<PrimType> T = classify(Init->getType())) {
590 // Visit the primitive element like normal.
591 if (!this->visit(Init))
592 return false;
593 if (!this->emitInitElem(*T, ElementIndex, Init))
594 return false;
595 } else {
596 // Advance the pointer currently on the stack to the given
597 // dimension.
598 if (!this->emitConstUint32(ElementIndex, Init))
599 return false;
600 if (!this->emitArrayElemPtrUint32(Init))
601 return false;
602 if (!this->visitInitializer(Init))
603 return false;
604 if (!this->emitPopPtr(Init))
605 return false;
606 }
607
608 ++ElementIndex;
609 }
610 return true;
611 }
612
613 return false;
614}
615
616template <class Emitter>
618 const CXXParenListInitExpr *E) {
619 if (DiscardResult) {
620 for (const Expr *Init : E->getInitExprs()) {
621 if (!this->discard(Init))
622 return false;
623 }
624 return true;
625 }
626
627 assert(E->getType()->isRecordType());
628 return this->visitInitList(E->getInitExprs(), E);
629}
630
631template <class Emitter>
634 return this->delegate(E->getReplacement());
635}
636
637template <class Emitter>
639 // Try to emit the APValue directly, without visiting the subexpr.
640 // This will only fail if we can't emit the APValue, so won't emit any
641 // diagnostics or any double values.
642 std::optional<PrimType> T = classify(E->getType());
643 if (T && E->hasAPValueResult() &&
644 this->visitAPValue(E->getAPValueResult(), *T, E))
645 return true;
646
647 return this->delegate(E->getSubExpr());
648}
649
650static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx,
652 bool AlignOfReturnsPreferred =
653 ASTCtx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
654
655 // C++ [expr.alignof]p3:
656 // When alignof is applied to a reference type, the result is the
657 // alignment of the referenced type.
658 if (const auto *Ref = T->getAs<ReferenceType>())
659 T = Ref->getPointeeType();
660
661 // __alignof is defined to return the preferred alignment.
662 // Before 8, clang returned the preferred alignment for alignof and
663 // _Alignof as well.
664 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
665 return ASTCtx.toCharUnitsFromBits(ASTCtx.getPreferredTypeAlign(T));
666
667 return ASTCtx.getTypeAlignInChars(T);
668}
669
670template <class Emitter>
672 const UnaryExprOrTypeTraitExpr *E) {
673 UnaryExprOrTypeTrait Kind = E->getKind();
674 ASTContext &ASTCtx = Ctx.getASTContext();
675
676 if (Kind == UETT_SizeOf) {
677 QualType ArgType = E->getTypeOfArgument();
678 CharUnits Size;
679 if (ArgType->isVoidType() || ArgType->isFunctionType())
680 Size = CharUnits::One();
681 else {
682 if (ArgType->isDependentType() || !ArgType->isConstantSizeType())
683 return false;
684
685 Size = ASTCtx.getTypeSizeInChars(ArgType);
686 }
687
688 if (DiscardResult)
689 return true;
690
691 return this->emitConst(Size.getQuantity(), E);
692 }
693
694 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
695 CharUnits Size;
696
697 if (E->isArgumentType()) {
698 QualType ArgType = E->getTypeOfArgument();
699
700 Size = AlignOfType(ArgType, ASTCtx, Kind);
701 } else {
702 // Argument is an expression, not a type.
703 const Expr *Arg = E->getArgumentExpr()->IgnoreParens();
704
705 // The kinds of expressions that we have special-case logic here for
706 // should be kept up to date with the special checks for those
707 // expressions in Sema.
708
709 // alignof decl is always accepted, even if it doesn't make sense: we
710 // default to 1 in those cases.
711 if (const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
712 Size = ASTCtx.getDeclAlign(DRE->getDecl(),
713 /*RefAsPointee*/ true);
714 else if (const auto *ME = dyn_cast<MemberExpr>(Arg))
715 Size = ASTCtx.getDeclAlign(ME->getMemberDecl(),
716 /*RefAsPointee*/ true);
717 else
718 Size = AlignOfType(Arg->getType(), ASTCtx, Kind);
719 }
720
721 if (DiscardResult)
722 return true;
723
724 return this->emitConst(Size.getQuantity(), E);
725 }
726
727 return false;
728}
729
730template <class Emitter>
732 // 'Base.Member'
733 const Expr *Base = E->getBase();
734
735 if (DiscardResult)
736 return this->discard(Base);
737
738 if (!this->visit(Base))
739 return false;
740
741 // Base above gives us a pointer on the stack.
742 // TODO: Implement non-FieldDecl members.
743 const ValueDecl *Member = E->getMemberDecl();
744 if (const auto *FD = dyn_cast<FieldDecl>(Member)) {
745 const RecordDecl *RD = FD->getParent();
746 const Record *R = getRecord(RD);
747 const Record::Field *F = R->getField(FD);
748 // Leave a pointer to the field on the stack.
749 if (F->Decl->getType()->isReferenceType())
750 return this->emitGetFieldPop(PT_Ptr, F->Offset, E);
751 return this->emitGetPtrField(F->Offset, E);
752 }
753
754 return false;
755}
756
757template <class Emitter>
759 const ArrayInitIndexExpr *E) {
760 // ArrayIndex might not be set if a ArrayInitIndexExpr is being evaluated
761 // stand-alone, e.g. via EvaluateAsInt().
762 if (!ArrayIndex)
763 return false;
764 return this->emitConst(*ArrayIndex, E);
765}
766
767template <class Emitter>
769 const ArrayInitLoopExpr *E) {
770 assert(Initializing);
771 assert(!DiscardResult);
772 // TODO: This compiles to quite a lot of bytecode if the array is larger.
773 // Investigate compiling this to a loop, or at least try to use
774 // the AILE's Common expr.
775 const Expr *SubExpr = E->getSubExpr();
776 size_t Size = E->getArraySize().getZExtValue();
777 std::optional<PrimType> ElemT = classify(SubExpr->getType());
778
779 // So, every iteration, we execute an assignment here
780 // where the LHS is on the stack (the target array)
781 // and the RHS is our SubExpr.
782 for (size_t I = 0; I != Size; ++I) {
783 ArrayIndexScope<Emitter> IndexScope(this, I);
784
785 if (ElemT) {
786 if (!this->visit(SubExpr))
787 return false;
788 if (!this->emitInitElem(*ElemT, I, E))
789 return false;
790 } else {
791 // Get to our array element and recurse into visitInitializer()
792 if (!this->emitConstUint64(I, SubExpr))
793 return false;
794 if (!this->emitArrayElemPtrUint64(SubExpr))
795 return false;
796 if (!visitInitializer(SubExpr))
797 return false;
798 if (!this->emitPopPtr(E))
799 return false;
800 }
801 }
802 return true;
803}
804
805template <class Emitter>
807 if (Initializing)
808 return this->visitInitializer(E->getSourceExpr());
809 return this->visit(E->getSourceExpr());
810}
811
812template <class Emitter>
815 const Expr *Condition = E->getCond();
816 const Expr *TrueExpr = E->getTrueExpr();
817 const Expr *FalseExpr = E->getFalseExpr();
818
819 LabelTy LabelEnd = this->getLabel(); // Label after the operator.
820 LabelTy LabelFalse = this->getLabel(); // Label for the false expr.
821
822 if (!this->visitBool(Condition))
823 return false;
824
825 if (!this->jumpFalse(LabelFalse))
826 return false;
827
828 if (!this->delegate(TrueExpr))
829 return false;
830 if (!this->jump(LabelEnd))
831 return false;
832
833 this->emitLabel(LabelFalse);
834
835 if (!this->delegate(FalseExpr))
836 return false;
837
838 this->fallthrough(LabelEnd);
839 this->emitLabel(LabelEnd);
840
841 return true;
842}
843
844template <class Emitter>
846 if (DiscardResult)
847 return true;
848
849 if (!Initializing) {
850 unsigned StringIndex = P.createGlobalString(E);
851 return this->emitGetPtrGlobal(StringIndex, E);
852 }
853
854 // We are initializing an array on the stack.
855 const ConstantArrayType *CAT =
856 Ctx.getASTContext().getAsConstantArrayType(E->getType());
857 assert(CAT && "a string literal that's not a constant array?");
858
859 // If the initializer string is too long, a diagnostic has already been
860 // emitted. Read only the array length from the string literal.
861 unsigned N =
862 std::min(unsigned(CAT->getSize().getZExtValue()), E->getLength());
863 size_t CharWidth = E->getCharByteWidth();
864
865 for (unsigned I = 0; I != N; ++I) {
866 uint32_t CodeUnit = E->getCodeUnit(I);
867
868 if (CharWidth == 1) {
869 this->emitConstSint8(CodeUnit, E);
870 this->emitInitElemSint8(I, E);
871 } else if (CharWidth == 2) {
872 this->emitConstUint16(CodeUnit, E);
873 this->emitInitElemUint16(I, E);
874 } else if (CharWidth == 4) {
875 this->emitConstUint32(CodeUnit, E);
876 this->emitInitElemUint32(I, E);
877 } else {
878 llvm_unreachable("unsupported character width");
879 }
880 }
881 return true;
882}
883
884template <class Emitter>
886 const CharacterLiteral *E) {
887 if (DiscardResult)
888 return true;
889 return this->emitConst(E->getValue(), E);
890}
891
892template <class Emitter>
894 const CompoundAssignOperator *E) {
895
896 const Expr *LHS = E->getLHS();
897 const Expr *RHS = E->getRHS();
898 QualType LHSType = LHS->getType();
899 QualType LHSComputationType = E->getComputationLHSType();
900 QualType ResultType = E->getComputationResultType();
901 std::optional<PrimType> LT = classify(LHSComputationType);
902 std::optional<PrimType> RT = classify(ResultType);
903
904 assert(ResultType->isFloatingType());
905
906 if (!LT || !RT)
907 return false;
908
909 PrimType LHST = classifyPrim(LHSType);
910
911 // C++17 onwards require that we evaluate the RHS first.
912 // Compute RHS and save it in a temporary variable so we can
913 // load it again later.
914 if (!visit(RHS))
915 return false;
916
917 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
918 if (!this->emitSetLocal(*RT, TempOffset, E))
919 return false;
920
921 // First, visit LHS.
922 if (!visit(LHS))
923 return false;
924 if (!this->emitLoad(LHST, E))
925 return false;
926
927 // If necessary, convert LHS to its computation type.
928 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
929 LHSComputationType, E))
930 return false;
931
932 // Now load RHS.
933 if (!this->emitGetLocal(*RT, TempOffset, E))
934 return false;
935
936 llvm::RoundingMode RM = getRoundingMode(E);
937 switch (E->getOpcode()) {
938 case BO_AddAssign:
939 if (!this->emitAddf(RM, E))
940 return false;
941 break;
942 case BO_SubAssign:
943 if (!this->emitSubf(RM, E))
944 return false;
945 break;
946 case BO_MulAssign:
947 if (!this->emitMulf(RM, E))
948 return false;
949 break;
950 case BO_DivAssign:
951 if (!this->emitDivf(RM, E))
952 return false;
953 break;
954 default:
955 return false;
956 }
957
958 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->getType(), E))
959 return false;
960
961 if (DiscardResult)
962 return this->emitStorePop(LHST, E);
963 return this->emitStore(LHST, E);
964}
965
966template <class Emitter>
968 const CompoundAssignOperator *E) {
970 const Expr *LHS = E->getLHS();
971 const Expr *RHS = E->getRHS();
972 std::optional<PrimType> LT = classify(LHS->getType());
973 std::optional<PrimType> RT = classify(RHS->getType());
974
975 if (Op != BO_AddAssign && Op != BO_SubAssign)
976 return false;
977
978 if (!LT || !RT)
979 return false;
980 assert(*LT == PT_Ptr);
981
982 if (!visit(LHS))
983 return false;
984
985 if (!this->emitLoadPtr(LHS))
986 return false;
987
988 if (!visit(RHS))
989 return false;
990
991 if (Op == BO_AddAssign)
992 this->emitAddOffset(*RT, E);
993 else
994 this->emitSubOffset(*RT, E);
995
996 if (DiscardResult)
997 return this->emitStorePopPtr(E);
998 return this->emitStorePtr(E);
999}
1000
1001template <class Emitter>
1003 const CompoundAssignOperator *E) {
1004
1005 const Expr *LHS = E->getLHS();
1006 const Expr *RHS = E->getRHS();
1007 std::optional<PrimType> LHSComputationT =
1008 classify(E->getComputationLHSType());
1009 std::optional<PrimType> LT = classify(LHS->getType());
1010 std::optional<PrimType> RT = classify(E->getComputationResultType());
1011 std::optional<PrimType> ResultT = classify(E->getType());
1012
1013 if (!LT || !RT || !ResultT || !LHSComputationT)
1014 return false;
1015
1016 // Handle floating point operations separately here, since they
1017 // require special care.
1018
1019 if (ResultT == PT_Float || RT == PT_Float)
1020 return VisitFloatCompoundAssignOperator(E);
1021
1022 if (E->getType()->isPointerType())
1023 return VisitPointerCompoundAssignOperator(E);
1024
1025 assert(!E->getType()->isPointerType() && "Handled above");
1026 assert(!E->getType()->isFloatingType() && "Handled above");
1027
1028 // C++17 onwards require that we evaluate the RHS first.
1029 // Compute RHS and save it in a temporary variable so we can
1030 // load it again later.
1031 // FIXME: Compound assignments are unsequenced in C, so we might
1032 // have to figure out how to reject them.
1033 if (!visit(RHS))
1034 return false;
1035
1036 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
1037
1038 if (!this->emitSetLocal(*RT, TempOffset, E))
1039 return false;
1040
1041 // Get LHS pointer, load its value and cast it to the
1042 // computation type if necessary.
1043 if (!visit(LHS))
1044 return false;
1045 if (!this->emitLoad(*LT, E))
1046 return false;
1047 if (*LT != *LHSComputationT) {
1048 if (!this->emitCast(*LT, *LHSComputationT, E))
1049 return false;
1050 }
1051
1052 // Get the RHS value on the stack.
1053 if (!this->emitGetLocal(*RT, TempOffset, E))
1054 return false;
1055
1056 // Perform operation.
1057 switch (E->getOpcode()) {
1058 case BO_AddAssign:
1059 if (!this->emitAdd(*LHSComputationT, E))
1060 return false;
1061 break;
1062 case BO_SubAssign:
1063 if (!this->emitSub(*LHSComputationT, E))
1064 return false;
1065 break;
1066 case BO_MulAssign:
1067 if (!this->emitMul(*LHSComputationT, E))
1068 return false;
1069 break;
1070 case BO_DivAssign:
1071 if (!this->emitDiv(*LHSComputationT, E))
1072 return false;
1073 break;
1074 case BO_RemAssign:
1075 if (!this->emitRem(*LHSComputationT, E))
1076 return false;
1077 break;
1078 case BO_ShlAssign:
1079 if (!this->emitShl(*LHSComputationT, *RT, E))
1080 return false;
1081 break;
1082 case BO_ShrAssign:
1083 if (!this->emitShr(*LHSComputationT, *RT, E))
1084 return false;
1085 break;
1086 case BO_AndAssign:
1087 if (!this->emitBitAnd(*LHSComputationT, E))
1088 return false;
1089 break;
1090 case BO_XorAssign:
1091 if (!this->emitBitXor(*LHSComputationT, E))
1092 return false;
1093 break;
1094 case BO_OrAssign:
1095 if (!this->emitBitOr(*LHSComputationT, E))
1096 return false;
1097 break;
1098 default:
1099 llvm_unreachable("Unimplemented compound assign operator");
1100 }
1101
1102 // And now cast from LHSComputationT to ResultT.
1103 if (*ResultT != *LHSComputationT) {
1104 if (!this->emitCast(*LHSComputationT, *ResultT, E))
1105 return false;
1106 }
1107
1108 // And store the result in LHS.
1109 if (DiscardResult)
1110 return this->emitStorePop(*ResultT, E);
1111 return this->emitStore(*ResultT, E);
1112}
1113
1114template <class Emitter>
1116 const ExprWithCleanups *E) {
1117 const Expr *SubExpr = E->getSubExpr();
1118
1119 assert(E->getNumObjects() == 0 && "TODO: Implement cleanups");
1120
1121 return this->delegate(SubExpr);
1122}
1123
1124template <class Emitter>
1126 const MaterializeTemporaryExpr *E) {
1127 const Expr *SubExpr = E->getSubExpr();
1128
1129 if (Initializing) {
1130 // We already have a value, just initialize that.
1131 return this->visitInitializer(SubExpr);
1132 }
1133 // If we don't end up using the materialized temporary anyway, don't
1134 // bother creating it.
1135 if (DiscardResult)
1136 return this->discard(SubExpr);
1137
1138 std::optional<PrimType> SubExprT = classify(SubExpr);
1139 if (E->getStorageDuration() == SD_Static) {
1140 std::optional<unsigned> GlobalIndex = P.createGlobal(E);
1141 if (!GlobalIndex)
1142 return false;
1143
1144 const LifetimeExtendedTemporaryDecl *TempDecl =
1146 assert(TempDecl);
1147
1148 if (SubExprT) {
1149 if (!this->visit(SubExpr))
1150 return false;
1151 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl, E))
1152 return false;
1153 return this->emitGetPtrGlobal(*GlobalIndex, E);
1154 }
1155
1156 // Non-primitive values.
1157 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1158 return false;
1159 if (!this->visitInitializer(SubExpr))
1160 return false;
1161 return this->emitInitGlobalTempComp(TempDecl, E);
1162 }
1163
1164 // For everyhing else, use local variables.
1165 if (SubExprT) {
1166 if (std::optional<unsigned> LocalIndex = allocateLocalPrimitive(
1167 SubExpr, *SubExprT, /*IsConst=*/true, /*IsExtended=*/true)) {
1168 if (!this->visit(SubExpr))
1169 return false;
1170 this->emitSetLocal(*SubExprT, *LocalIndex, E);
1171 return this->emitGetPtrLocal(*LocalIndex, E);
1172 }
1173 } else {
1174 if (std::optional<unsigned> LocalIndex =
1175 allocateLocal(SubExpr, /*IsExtended=*/true)) {
1176 if (!this->emitGetPtrLocal(*LocalIndex, E))
1177 return false;
1178 return this->visitInitializer(SubExpr);
1179 }
1180 }
1181 return false;
1182}
1183
1184template <class Emitter>
1186 const CXXBindTemporaryExpr *E) {
1187 if (Initializing)
1188 return this->visitInitializer(E->getSubExpr());
1189 return this->visit(E->getSubExpr());
1190}
1191
1192template <class Emitter>
1194 const CompoundLiteralExpr *E) {
1195 const Expr *Init = E->getInitializer();
1196 if (Initializing) {
1197 // We already have a value, just initialize that.
1198 return this->visitInitializer(Init);
1199 }
1200
1201 std::optional<PrimType> T = classify(E->getType());
1202 if (E->isFileScope()) {
1203 if (std::optional<unsigned> GlobalIndex = P.createGlobal(E)) {
1204 if (classify(E->getType()))
1205 return this->visit(Init);
1206 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1207 return false;
1208 return this->visitInitializer(Init);
1209 }
1210 }
1211
1212 // Otherwise, use a local variable.
1213 if (T) {
1214 // For primitive types, we just visit the initializer.
1215 return this->delegate(Init);
1216 } else {
1217 if (std::optional<unsigned> LocalIndex = allocateLocal(Init)) {
1218 if (!this->emitGetPtrLocal(*LocalIndex, E))
1219 return false;
1220 if (!this->visitInitializer(Init))
1221 return false;
1222 if (DiscardResult)
1223 return this->emitPopPtr(E);
1224 return true;
1225 }
1226 }
1227
1228 return false;
1229}
1230
1231template <class Emitter>
1233 if (DiscardResult)
1234 return true;
1235 return this->emitConstBool(E->getValue(), E);
1236}
1237
1238template <class Emitter>
1240 assert(Initializing);
1241 const Record *R = P.getOrCreateRecord(E->getLambdaClass());
1242
1243 auto *CaptureInitIt = E->capture_init_begin();
1244 // Initialize all fields (which represent lambda captures) of the
1245 // record with their initializers.
1246 for (const Record::Field &F : R->fields()) {
1247 const Expr *Init = *CaptureInitIt;
1248 ++CaptureInitIt;
1249
1250 if (std::optional<PrimType> T = classify(Init)) {
1251 if (!this->visit(Init))
1252 return false;
1253
1254 if (!this->emitSetField(*T, F.Offset, E))
1255 return false;
1256 } else {
1257 if (!this->emitDupPtr(E))
1258 return false;
1259
1260 if (!this->emitGetPtrField(F.Offset, E))
1261 return false;
1262
1263 if (!this->visitInitializer(Init))
1264 return false;
1265
1266 if (!this->emitPopPtr(E))
1267 return false;
1268 }
1269 }
1270
1271 return true;
1272}
1273
1274template <class Emitter>
1276 if (DiscardResult)
1277 return true;
1278
1279 assert(!Initializing);
1280 return this->visit(E->getFunctionName());
1281}
1282
1283template <class Emitter>
1285 if (E->getSubExpr() && !this->discard(E->getSubExpr()))
1286 return false;
1287
1288 return this->emitInvalid(E);
1289}
1290
1291template <class Emitter>
1293 const CXXReinterpretCastExpr *E) {
1294 if (!this->discard(E->getSubExpr()))
1295 return false;
1296
1297 return this->emitInvalidCast(CastKind::Reinterpret, E);
1298}
1299
1300template <class Emitter>
1302 assert(E->getType()->isBooleanType());
1303
1304 if (DiscardResult)
1305 return true;
1306 return this->emitConstBool(E->getValue(), E);
1307}
1308
1309template <class Emitter>
1311 const CXXConstructExpr *E) {
1312 QualType T = E->getType();
1313 assert(!classify(T));
1314
1315 if (T->isRecordType()) {
1316 const CXXConstructorDecl *Ctor = E->getConstructor();
1317
1318 // Trivial zero initialization.
1319 if (E->requiresZeroInitialization() && Ctor->isTrivial()) {
1320 const Record *R = getRecord(E->getType());
1321 return this->visitZeroRecordInitializer(R, E);
1322 }
1323
1324 const Function *Func = getFunction(Ctor);
1325
1326 if (!Func)
1327 return false;
1328
1329 assert(Func->hasThisPointer());
1330 assert(!Func->hasRVO());
1331
1332 // If we're discarding a construct expression, we still need
1333 // to allocate a variable and call the constructor and destructor.
1334 if (DiscardResult) {
1335 assert(!Initializing);
1336 std::optional<unsigned> LocalIndex =
1337 allocateLocal(E, /*IsExtended=*/true);
1338
1339 if (!LocalIndex)
1340 return false;
1341
1342 if (!this->emitGetPtrLocal(*LocalIndex, E))
1343 return false;
1344 }
1345
1346 // The This pointer is already on the stack because this is an initializer,
1347 // but we need to dup() so the call() below has its own copy.
1348 if (!this->emitDupPtr(E))
1349 return false;
1350
1351 // Constructor arguments.
1352 for (const auto *Arg : E->arguments()) {
1353 if (!this->visit(Arg))
1354 return false;
1355 }
1356
1357 if (!this->emitCall(Func, E))
1358 return false;
1359
1360 // Immediately call the destructor if we have to.
1361 if (DiscardResult) {
1362 if (!this->emitPopPtr(E))
1363 return false;
1364 }
1365 return true;
1366 }
1367
1368 if (T->isArrayType()) {
1369 const ConstantArrayType *CAT =
1370 Ctx.getASTContext().getAsConstantArrayType(E->getType());
1371 assert(CAT);
1372 size_t NumElems = CAT->getSize().getZExtValue();
1373 const Function *Func = getFunction(E->getConstructor());
1374 if (!Func || !Func->isConstexpr())
1375 return false;
1376
1377 // FIXME(perf): We're calling the constructor once per array element here,
1378 // in the old intepreter we had a special-case for trivial constructors.
1379 for (size_t I = 0; I != NumElems; ++I) {
1380 if (!this->emitConstUint64(I, E))
1381 return false;
1382 if (!this->emitArrayElemPtrUint64(E))
1383 return false;
1384
1385 // Constructor arguments.
1386 for (const auto *Arg : E->arguments()) {
1387 if (!this->visit(Arg))
1388 return false;
1389 }
1390
1391 if (!this->emitCall(Func, E))
1392 return false;
1393 }
1394 return true;
1395 }
1396
1397 return false;
1398}
1399
1400template <class Emitter>
1402 if (DiscardResult)
1403 return true;
1404
1405 const APValue Val =
1406 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
1407
1408 // Things like __builtin_LINE().
1409 if (E->getType()->isIntegerType()) {
1410 assert(Val.isInt());
1411 const APSInt &I = Val.getInt();
1412 return this->emitConst(I, E);
1413 }
1414 // Otherwise, the APValue is an LValue, with only one element.
1415 // Theoretically, we don't need the APValue at all of course.
1416 assert(E->getType()->isPointerType());
1417 assert(Val.isLValue());
1418 const APValue::LValueBase &Base = Val.getLValueBase();
1419 if (const Expr *LValueExpr = Base.dyn_cast<const Expr *>())
1420 return this->visit(LValueExpr);
1421
1422 // Otherwise, we have a decl (which is the case for
1423 // __builtin_source_location).
1424 assert(Base.is<const ValueDecl *>());
1425 assert(Val.getLValuePath().size() == 0);
1426 const auto *BaseDecl = Base.dyn_cast<const ValueDecl *>();
1427 assert(BaseDecl);
1428
1429 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
1430
1431 std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(UGCD);
1432 if (!GlobalIndex)
1433 return false;
1434
1435 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1436 return false;
1437
1438 const Record *R = getRecord(E->getType());
1439 const APValue &V = UGCD->getValue();
1440 for (unsigned I = 0, N = R->getNumFields(); I != N; ++I) {
1441 const Record::Field *F = R->getField(I);
1442 const APValue &FieldValue = V.getStructField(I);
1443
1444 PrimType FieldT = classifyPrim(F->Decl->getType());
1445
1446 if (!this->visitAPValue(FieldValue, FieldT, E))
1447 return false;
1448 if (!this->emitInitField(FieldT, F->Offset, E))
1449 return false;
1450 }
1451
1452 // Leave the pointer to the global on the stack.
1453 return true;
1454}
1455
1456template <class Emitter>
1458 unsigned N = E->getNumComponents();
1459 if (N == 0)
1460 return false;
1461
1462 for (unsigned I = 0; I != N; ++I) {
1463 const OffsetOfNode &Node = E->getComponent(I);
1464 if (Node.getKind() == OffsetOfNode::Array) {
1465 const Expr *ArrayIndexExpr = E->getIndexExpr(Node.getArrayExprIndex());
1466 PrimType IndexT = classifyPrim(ArrayIndexExpr->getType());
1467
1468 if (DiscardResult) {
1469 if (!this->discard(ArrayIndexExpr))
1470 return false;
1471 continue;
1472 }
1473
1474 if (!this->visit(ArrayIndexExpr))
1475 return false;
1476 // Cast to Sint64.
1477 if (IndexT != PT_Sint64) {
1478 if (!this->emitCast(IndexT, PT_Sint64, E))
1479 return false;
1480 }
1481 }
1482 }
1483
1484 if (DiscardResult)
1485 return true;
1486
1487 PrimType T = classifyPrim(E->getType());
1488 return this->emitOffsetOf(T, E, E);
1489}
1490
1491template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) {
1492 if (E->containsErrors())
1493 return false;
1494
1495 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
1496 /*NewInitializing=*/false);
1497 return this->Visit(E);
1498}
1499
1500template <class Emitter>
1502 if (E->containsErrors())
1503 return false;
1504
1505 // We're basically doing:
1506 // OptionScope<Emitter> Scope(this, DicardResult, Initializing);
1507 // but that's unnecessary of course.
1508 return this->Visit(E);
1509}
1510
1511template <class Emitter> bool ByteCodeExprGen<Emitter>::visit(const Expr *E) {
1512 if (E->containsErrors())
1513 return false;
1514
1515 if (E->getType()->isVoidType())
1516 return this->discard(E);
1517
1518 // Create local variable to hold the return value.
1519 if (!E->isGLValue() && !classify(E->getType())) {
1520 std::optional<unsigned> LocalIndex = allocateLocal(E, /*IsExtended=*/true);
1521 if (!LocalIndex)
1522 return false;
1523
1524 if (!this->emitGetPtrLocal(*LocalIndex, E))
1525 return false;
1526 return this->visitInitializer(E);
1527 }
1528
1529 // Otherwise,we have a primitive return value, produce the value directly
1530 // and push it on the stack.
1531 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
1532 /*NewInitializing=*/false);
1533 return this->Visit(E);
1534}
1535
1536template <class Emitter>
1538 assert(!classify(E->getType()));
1539
1540 if (E->containsErrors())
1541 return false;
1542
1543 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
1544 /*NewInitializing=*/true);
1545 return this->Visit(E);
1546}
1547
1548template <class Emitter>
1550 std::optional<PrimType> T = classify(E->getType());
1551 if (!T)
1552 return false;
1553
1554 if (!this->visit(E))
1555 return false;
1556
1557 if (T == PT_Bool)
1558 return true;
1559
1560 // Convert pointers to bool.
1561 if (T == PT_Ptr || T == PT_FnPtr) {
1562 if (!this->emitNull(*T, E))
1563 return false;
1564 return this->emitNE(*T, E);
1565 }
1566
1567 // Or Floats.
1568 if (T == PT_Float)
1569 return this->emitCastFloatingIntegralBool(E);
1570
1571 // Or anything else we can.
1572 return this->emitCast(*T, PT_Bool, E);
1573}
1574
1575template <class Emitter>
1577 const Expr *E) {
1578 // FIXME: We need the QualType to get the float semantics, but that means we
1579 // classify it over and over again in array situations.
1580 PrimType T = classifyPrim(QT);
1581
1582 switch (T) {
1583 case PT_Bool:
1584 return this->emitZeroBool(E);
1585 case PT_Sint8:
1586 return this->emitZeroSint8(E);
1587 case PT_Uint8:
1588 return this->emitZeroUint8(E);
1589 case PT_Sint16:
1590 return this->emitZeroSint16(E);
1591 case PT_Uint16:
1592 return this->emitZeroUint16(E);
1593 case PT_Sint32:
1594 return this->emitZeroSint32(E);
1595 case PT_Uint32:
1596 return this->emitZeroUint32(E);
1597 case PT_Sint64:
1598 return this->emitZeroSint64(E);
1599 case PT_Uint64:
1600 return this->emitZeroUint64(E);
1601 case PT_Ptr:
1602 return this->emitNullPtr(E);
1603 case PT_FnPtr:
1604 return this->emitNullFnPtr(E);
1605 case PT_Float: {
1606 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E);
1607 }
1608 }
1609 llvm_unreachable("unknown primitive type");
1610}
1611
1612template <class Emitter>
1614 const Expr *E) {
1615 assert(E);
1616 assert(R);
1617 // Fields
1618 for (const Record::Field &Field : R->fields()) {
1619 const Descriptor *D = Field.Desc;
1620 if (D->isPrimitive()) {
1621 QualType QT = D->getType();
1622 PrimType T = classifyPrim(D->getType());
1623 if (!this->visitZeroInitializer(QT, E))
1624 return false;
1625 if (!this->emitInitField(T, Field.Offset, E))
1626 return false;
1627 continue;
1628 }
1629
1630 // TODO: Add GetPtrFieldPop and get rid of this dup.
1631 if (!this->emitDupPtr(E))
1632 return false;
1633 if (!this->emitGetPtrField(Field.Offset, E))
1634 return false;
1635
1636 if (D->isPrimitiveArray()) {
1637 QualType ET = D->getElemQualType();
1638 PrimType T = classifyPrim(ET);
1639 for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
1640 if (!this->visitZeroInitializer(ET, E))
1641 return false;
1642 if (!this->emitInitElem(T, I, E))
1643 return false;
1644 }
1645 } else if (D->isCompositeArray()) {
1646 const Record *ElemRecord = D->ElemDesc->ElemRecord;
1647 assert(D->ElemDesc->ElemRecord);
1648 for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
1649 if (!this->emitConstUint32(I, E))
1650 return false;
1651 if (!this->emitArrayElemPtr(PT_Uint32, E))
1652 return false;
1653 if (!this->visitZeroRecordInitializer(ElemRecord, E))
1654 return false;
1655 if (!this->emitPopPtr(E))
1656 return false;
1657 }
1658 } else if (D->isRecord()) {
1659 if (!this->visitZeroRecordInitializer(D->ElemRecord, E))
1660 return false;
1661 } else {
1662 assert(false);
1663 }
1664
1665 if (!this->emitPopPtr(E))
1666 return false;
1667 }
1668
1669 for (const Record::Base &B : R->bases()) {
1670 if (!this->emitGetPtrBase(B.Offset, E))
1671 return false;
1672 if (!this->visitZeroRecordInitializer(B.R, E))
1673 return false;
1674 if (!this->emitPopPtr(E))
1675 return false;
1676 }
1677
1678 // FIXME: Virtual bases.
1679
1680 return true;
1681}
1682
1683template <class Emitter>
1685 const Expr *LV, DerefKind AK, llvm::function_ref<bool(PrimType)> Direct,
1686 llvm::function_ref<bool(PrimType)> Indirect) {
1687 if (std::optional<PrimType> T = classify(LV->getType())) {
1688 if (!LV->refersToBitField()) {
1689 // Only primitive, non bit-field types can be dereferenced directly.
1690 if (const auto *DE = dyn_cast<DeclRefExpr>(LV)) {
1691 if (!DE->getDecl()->getType()->isReferenceType()) {
1692 if (const auto *PD = dyn_cast<ParmVarDecl>(DE->getDecl()))
1693 return dereferenceParam(LV, *T, PD, AK, Direct, Indirect);
1694 if (const auto *VD = dyn_cast<VarDecl>(DE->getDecl()))
1695 return dereferenceVar(LV, *T, VD, AK, Direct, Indirect);
1696 }
1697 }
1698 }
1699
1700 if (!visit(LV))
1701 return false;
1702 return Indirect(*T);
1703 }
1704
1705 return false;
1706}
1707
1708template <class Emitter>
1710 const Expr *LV, PrimType T, const ParmVarDecl *PD, DerefKind AK,
1711 llvm::function_ref<bool(PrimType)> Direct,
1712 llvm::function_ref<bool(PrimType)> Indirect) {
1713 auto It = this->Params.find(PD);
1714 if (It != this->Params.end()) {
1715 unsigned Idx = It->second.Offset;
1716 switch (AK) {
1717 case DerefKind::Read:
1718 return DiscardResult ? true : this->emitGetParam(T, Idx, LV);
1719
1720 case DerefKind::Write:
1721 if (!Direct(T))
1722 return false;
1723 if (!this->emitSetParam(T, Idx, LV))
1724 return false;
1725 return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
1726
1727 case DerefKind::ReadWrite:
1728 if (!this->emitGetParam(T, Idx, LV))
1729 return false;
1730 if (!Direct(T))
1731 return false;
1732 if (!this->emitSetParam(T, Idx, LV))
1733 return false;
1734 return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
1735 }
1736 return true;
1737 }
1738
1739 // If the param is a pointer, we can dereference a dummy value.
1740 if (!DiscardResult && T == PT_Ptr && AK == DerefKind::Read) {
1741 if (auto Idx = P.getOrCreateDummy(PD))
1742 return this->emitGetPtrGlobal(*Idx, PD);
1743 return false;
1744 }
1745
1746 // Value cannot be produced - try to emit pointer and do stuff with it.
1747 return visit(LV) && Indirect(T);
1748}
1749
1750template <class Emitter>
1752 const Expr *LV, PrimType T, const VarDecl *VD, DerefKind AK,
1753 llvm::function_ref<bool(PrimType)> Direct,
1754 llvm::function_ref<bool(PrimType)> Indirect) {
1755 auto It = Locals.find(VD);
1756 if (It != Locals.end()) {
1757 const auto &L = It->second;
1758 switch (AK) {
1759 case DerefKind::Read:
1760 if (!this->emitGetLocal(T, L.Offset, LV))
1761 return false;
1762 return DiscardResult ? this->emitPop(T, LV) : true;
1763
1764 case DerefKind::Write:
1765 if (!Direct(T))
1766 return false;
1767 if (!this->emitSetLocal(T, L.Offset, LV))
1768 return false;
1769 return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV);
1770
1771 case DerefKind::ReadWrite:
1772 if (!this->emitGetLocal(T, L.Offset, LV))
1773 return false;
1774 if (!Direct(T))
1775 return false;
1776 if (!this->emitSetLocal(T, L.Offset, LV))
1777 return false;
1778 return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV);
1779 }
1780 } else if (auto Idx = P.getGlobal(VD)) {
1781 switch (AK) {
1782 case DerefKind::Read:
1783 if (!this->emitGetGlobal(T, *Idx, LV))
1784 return false;
1785 return DiscardResult ? this->emitPop(T, LV) : true;
1786
1787 case DerefKind::Write:
1788 if (!Direct(T))
1789 return false;
1790 if (!this->emitSetGlobal(T, *Idx, LV))
1791 return false;
1792 return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV);
1793
1794 case DerefKind::ReadWrite:
1795 if (!this->emitGetGlobal(T, *Idx, LV))
1796 return false;
1797 if (!Direct(T))
1798 return false;
1799 if (!this->emitSetGlobal(T, *Idx, LV))
1800 return false;
1801 return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV);
1802 }
1803 }
1804
1805 // If the declaration is a constant value, emit it here even
1806 // though the declaration was not evaluated in the current scope.
1807 // The access mode can only be read in this case.
1808 if (!DiscardResult && AK == DerefKind::Read) {
1809 if (VD->hasLocalStorage() && VD->hasInit() && !VD->isConstexpr()) {
1810 QualType VT = VD->getType();
1811 if (VT.isConstQualified() && VT->isFundamentalType())
1812 return this->visit(VD->getInit());
1813 }
1814 }
1815
1816 // Value cannot be produced - try to emit pointer.
1817 return visit(LV) && Indirect(T);
1818}
1819
1820template <class Emitter>
1821template <typename T>
1823 switch (Ty) {
1824 case PT_Sint8:
1825 return this->emitConstSint8(Value, E);
1826 case PT_Uint8:
1827 return this->emitConstUint8(Value, E);
1828 case PT_Sint16:
1829 return this->emitConstSint16(Value, E);
1830 case PT_Uint16:
1831 return this->emitConstUint16(Value, E);
1832 case PT_Sint32:
1833 return this->emitConstSint32(Value, E);
1834 case PT_Uint32:
1835 return this->emitConstUint32(Value, E);
1836 case PT_Sint64:
1837 return this->emitConstSint64(Value, E);
1838 case PT_Uint64:
1839 return this->emitConstUint64(Value, E);
1840 case PT_Bool:
1841 return this->emitConstBool(Value, E);
1842 case PT_Ptr:
1843 case PT_FnPtr:
1844 case PT_Float:
1845 llvm_unreachable("Invalid integral type");
1846 break;
1847 }
1848 llvm_unreachable("unknown primitive type");
1849}
1850
1851template <class Emitter>
1852template <typename T>
1854 return this->emitConst(Value, classifyPrim(E->getType()), E);
1855}
1856
1857template <class Emitter>
1859 const Expr *E) {
1860 if (Value.isSigned())
1861 return this->emitConst(Value.getSExtValue(), Ty, E);
1862 return this->emitConst(Value.getZExtValue(), Ty, E);
1863}
1864
1865template <class Emitter>
1867 return this->emitConst(Value, classifyPrim(E->getType()), E);
1868}
1869
1870template <class Emitter>
1872 PrimType Ty,
1873 bool IsConst,
1874 bool IsExtended) {
1875 // Make sure we don't accidentally register the same decl twice.
1876 if (const auto *VD =
1877 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
1878 assert(!P.getGlobal(VD));
1879 assert(!Locals.contains(VD));
1880 }
1881
1882 // FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
1883 // (int){12} in C. Consider using Expr::isTemporaryObject() instead
1884 // or isa<MaterializeTemporaryExpr>().
1885 Descriptor *D = P.createDescriptor(Src, Ty, Descriptor::InlineDescMD, IsConst,
1886 Src.is<const Expr *>());
1887 Scope::Local Local = this->createLocal(D);
1888 if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>()))
1889 Locals.insert({VD, Local});
1890 VarScope->add(Local, IsExtended);
1891 return Local.Offset;
1892}
1893
1894template <class Emitter>
1895std::optional<unsigned>
1897 // Make sure we don't accidentally register the same decl twice.
1898 if ([[maybe_unused]] const auto *VD =
1899 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
1900 assert(!P.getGlobal(VD));
1901 assert(!Locals.contains(VD));
1902 }
1903
1904 QualType Ty;
1905 const ValueDecl *Key = nullptr;
1906 const Expr *Init = nullptr;
1907 bool IsTemporary = false;
1908 if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
1909 Key = VD;
1910 Ty = VD->getType();
1911
1912 if (const auto *VarD = dyn_cast<VarDecl>(VD))
1913 Init = VarD->getInit();
1914 }
1915 if (auto *E = Src.dyn_cast<const Expr *>()) {
1916 IsTemporary = true;
1917 Ty = E->getType();
1918 }
1919
1920 Descriptor *D = P.createDescriptor(
1922 IsTemporary, /*IsMutable=*/false, Init);
1923 if (!D)
1924 return {};
1925
1926 Scope::Local Local = this->createLocal(D);
1927 if (Key)
1928 Locals.insert({Key, Local});
1929 VarScope->add(Local, IsExtended);
1930 return Local.Offset;
1931}
1932
1933template <class Emitter>
1935 if (const PointerType *PT = dyn_cast<PointerType>(Ty))
1936 return PT->getPointeeType()->getAs<RecordType>();
1937 return Ty->getAs<RecordType>();
1938}
1939
1940template <class Emitter>
1942 if (const auto *RecordTy = getRecordTy(Ty))
1943 return getRecord(RecordTy->getDecl());
1944 return nullptr;
1945}
1946
1947template <class Emitter>
1949 return P.getOrCreateRecord(RD);
1950}
1951
1952template <class Emitter>
1954 return Ctx.getOrCreateFunction(FD);
1955}
1956
1957template <class Emitter>
1959 ExprScope<Emitter> RootScope(this);
1960 if (!visit(E))
1961 return false;
1962
1963 if (E->getType()->isVoidType())
1964 return this->emitRetVoid(E);
1965
1966 if (std::optional<PrimType> T = classify(E))
1967 return this->emitRet(*T, E);
1968 return this->emitRetValue(E);
1969}
1970
1971/// Toplevel visitDecl().
1972/// We get here from evaluateAsInitializer().
1973/// We need to evaluate the initializer and return its value.
1974template <class Emitter>
1976 assert(!VD->isInvalidDecl() && "Trying to constant evaluate an invalid decl");
1977
1978 // Create and initialize the variable.
1979 if (!this->visitVarDecl(VD))
1980 return false;
1981
1982 // Get a pointer to the variable
1984 auto GlobalIndex = P.getGlobal(VD);
1985 assert(GlobalIndex); // visitVarDecl() didn't return false.
1986 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
1987 return false;
1988 } else {
1989 auto Local = Locals.find(VD);
1990 assert(Local != Locals.end()); // Same here.
1991 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
1992 return false;
1993 }
1994
1995 // Return the value
1996 if (std::optional<PrimType> VarT = classify(VD->getType())) {
1997 if (!this->emitLoadPop(*VarT, VD))
1998 return false;
1999
2000 return this->emitRet(*VarT, VD);
2001 }
2002
2003 return this->emitRetValue(VD);
2004}
2005
2006template <class Emitter>
2008 // We don't know what to do with these, so just return false.
2009 if (VD->getType().isNull())
2010 return false;
2011
2012 const Expr *Init = VD->getInit();
2013 std::optional<PrimType> VarT = classify(VD->getType());
2014
2016 // We've already seen and initialized this global.
2017 if (P.getGlobal(VD))
2018 return true;
2019
2020 std::optional<unsigned> GlobalIndex = P.createGlobal(VD, Init);
2021
2022 if (!GlobalIndex)
2023 return this->bail(VD);
2024
2025 assert(Init);
2026 {
2028
2029 if (VarT) {
2030 if (!this->visit(Init))
2031 return false;
2032 return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
2033 }
2034 return this->visitGlobalInitializer(Init, *GlobalIndex);
2035 }
2036 } else {
2038 if (VarT) {
2039 unsigned Offset = this->allocateLocalPrimitive(
2040 VD, *VarT, VD->getType().isConstQualified());
2041 if (Init) {
2042 // Compile the initializer in its own scope.
2044 if (!this->visit(Init))
2045 return false;
2046
2047 return this->emitSetLocal(*VarT, Offset, VD);
2048 }
2049 } else {
2050 if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
2051 if (Init)
2052 return this->visitLocalInitializer(Init, *Offset);
2053 }
2054 }
2055 return true;
2056 }
2057
2058 return false;
2059}
2060
2061template <class Emitter>
2063 PrimType ValType, const Expr *E) {
2064 assert(!DiscardResult);
2065 if (Val.isInt())
2066 return this->emitConst(Val.getInt(), ValType, E);
2067
2068 if (Val.isLValue()) {
2070 if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>())
2071 return this->visit(BaseExpr);
2072 }
2073
2074 return false;
2075}
2076
2077template <class Emitter>
2079 const Function *Func = getFunction(E->getDirectCallee());
2080 if (!Func)
2081 return false;
2082
2083 // Put arguments on the stack.
2084 for (const auto *Arg : E->arguments()) {
2085 if (!this->visit(Arg))
2086 return false;
2087 }
2088
2089 if (!this->emitCallBI(Func, E, E))
2090 return false;
2091
2092 QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
2093 if (DiscardResult && !ReturnType->isVoidType()) {
2094 PrimType T = classifyPrim(ReturnType);
2095 return this->emitPop(T, E);
2096 }
2097
2098 return true;
2099}
2100
2101template <class Emitter>
2103 if (E->getBuiltinCallee())
2104 return VisitBuiltinCallExpr(E);
2105
2106 QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
2107 std::optional<PrimType> T = classify(ReturnType);
2108 bool HasRVO = !ReturnType->isVoidType() && !T;
2109
2110 if (HasRVO) {
2111 if (DiscardResult) {
2112 // If we need to discard the return value but the function returns its
2113 // value via an RVO pointer, we need to create one such pointer just
2114 // for this call.
2115 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
2116 if (!this->emitGetPtrLocal(*LocalIndex, E))
2117 return false;
2118 }
2119 } else {
2120 assert(Initializing);
2121 if (!isa<CXXMemberCallExpr>(E)) {
2122 if (!this->emitDupPtr(E))
2123 return false;
2124 }
2125 }
2126 }
2127
2128 // Put arguments on the stack.
2129 for (const auto *Arg : E->arguments()) {
2130 if (!this->visit(Arg))
2131 return false;
2132 }
2133
2134 if (const FunctionDecl *FuncDecl = E->getDirectCallee()) {
2135 const Function *Func = getFunction(FuncDecl);
2136 if (!Func)
2137 return false;
2138 // If the function is being compiled right now, this is a recursive call.
2139 // In that case, the function can't be valid yet, even though it will be
2140 // later.
2141 // If the function is already fully compiled but not constexpr, it was
2142 // found to be faulty earlier on, so bail out.
2143 if (Func->isFullyCompiled() && !Func->isConstexpr())
2144 return false;
2145
2146 assert(HasRVO == Func->hasRVO());
2147
2148 bool HasQualifier = false;
2149 if (const auto *ME = dyn_cast<MemberExpr>(E->getCallee()))
2150 HasQualifier = ME->hasQualifier();
2151
2152 bool IsVirtual = false;
2153 if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
2154 IsVirtual = MD->isVirtual();
2155
2156 // In any case call the function. The return value will end up on the stack
2157 // and if the function has RVO, we already have the pointer on the stack to
2158 // write the result into.
2159 if (IsVirtual && !HasQualifier) {
2160 if (!this->emitCallVirt(Func, E))
2161 return false;
2162 } else {
2163 if (!this->emitCall(Func, E))
2164 return false;
2165 }
2166 } else {
2167 // Indirect call. Visit the callee, which will leave a FunctionPointer on
2168 // the stack. Cleanup of the returned value if necessary will be done after
2169 // the function call completed.
2170 if (!this->visit(E->getCallee()))
2171 return false;
2172
2173 if (!this->emitCallPtr(E))
2174 return false;
2175 }
2176
2177 // Cleanup for discarded return values.
2178 if (DiscardResult && !ReturnType->isVoidType() && T)
2179 return this->emitPop(*T, E);
2180
2181 return true;
2182}
2183
2184template <class Emitter>
2186 const CXXMemberCallExpr *E) {
2187 if (Initializing) {
2188 // If we're initializing, the current stack top is the pointer to
2189 // initialize, so dup that so this call has its own version.
2190 if (!this->emitDupPtr(E))
2191 return false;
2192 }
2193
2194 if (!this->visit(E->getImplicitObjectArgument()))
2195 return false;
2196
2197 return VisitCallExpr(E);
2198}
2199
2200template <class Emitter>
2202 const CXXDefaultInitExpr *E) {
2203 SourceLocScope<Emitter> SLS(this, E);
2204 if (Initializing)
2205 return this->visitInitializer(E->getExpr());
2206
2207 assert(classify(E->getType()));
2208 return this->visit(E->getExpr());
2209}
2210
2211template <class Emitter>
2213 const CXXDefaultArgExpr *E) {
2214 SourceLocScope<Emitter> SLS(this, E);
2215
2216 const Expr *SubExpr = E->getExpr();
2217 if (std::optional<PrimType> T = classify(E->getExpr()))
2218 return this->visit(SubExpr);
2219
2220 assert(Initializing);
2221 return this->visitInitializer(SubExpr);
2222}
2223
2224template <class Emitter>
2226 const CXXBoolLiteralExpr *E) {
2227 if (DiscardResult)
2228 return true;
2229
2230 return this->emitConstBool(E->getValue(), E);
2231}
2232
2233template <class Emitter>
2235 const CXXNullPtrLiteralExpr *E) {
2236 if (DiscardResult)
2237 return true;
2238
2239 return this->emitNullPtr(E);
2240}
2241
2242template <class Emitter>
2244 if (DiscardResult)
2245 return true;
2246
2247 assert(E->getType()->isIntegerType());
2248
2249 PrimType T = classifyPrim(E->getType());
2250 return this->emitZero(T, E);
2251}
2252
2253template <class Emitter>
2255 if (DiscardResult)
2256 return true;
2257 return this->emitThis(E);
2258}
2259
2260template <class Emitter>
2262 const Expr *SubExpr = E->getSubExpr();
2263 std::optional<PrimType> T = classify(SubExpr->getType());
2264
2265 switch (E->getOpcode()) {
2266 case UO_PostInc: { // x++
2267 if (!this->visit(SubExpr))
2268 return false;
2269
2270 if (T == PT_Ptr) {
2271 if (!this->emitIncPtr(E))
2272 return false;
2273
2274 return DiscardResult ? this->emitPopPtr(E) : true;
2275 }
2276
2277 if (T == PT_Float) {
2278 return DiscardResult ? this->emitIncfPop(getRoundingMode(E), E)
2279 : this->emitIncf(getRoundingMode(E), E);
2280 }
2281
2282 return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E);
2283 }
2284 case UO_PostDec: { // x--
2285 if (!this->visit(SubExpr))
2286 return false;
2287
2288 if (T == PT_Ptr) {
2289 if (!this->emitDecPtr(E))
2290 return false;
2291
2292 return DiscardResult ? this->emitPopPtr(E) : true;
2293 }
2294
2295 if (T == PT_Float) {
2296 return DiscardResult ? this->emitDecfPop(getRoundingMode(E), E)
2297 : this->emitDecf(getRoundingMode(E), E);
2298 }
2299
2300 return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E);
2301 }
2302 case UO_PreInc: { // ++x
2303 if (!this->visit(SubExpr))
2304 return false;
2305
2306 if (T == PT_Ptr) {
2307 if (!this->emitLoadPtr(E))
2308 return false;
2309 if (!this->emitConstUint8(1, E))
2310 return false;
2311 if (!this->emitAddOffsetUint8(E))
2312 return false;
2313 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
2314 }
2315
2316 // Post-inc and pre-inc are the same if the value is to be discarded.
2317 if (DiscardResult) {
2318 if (T == PT_Float)
2319 return this->emitIncfPop(getRoundingMode(E), E);
2320 return this->emitIncPop(*T, E);
2321 }
2322
2323 if (T == PT_Float) {
2324 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
2325 if (!this->emitLoadFloat(E))
2326 return false;
2327 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
2328 return false;
2329 if (!this->emitAddf(getRoundingMode(E), E))
2330 return false;
2331 return this->emitStoreFloat(E);
2332 }
2333 if (!this->emitLoad(*T, E))
2334 return false;
2335 if (!this->emitConst(1, E))
2336 return false;
2337 if (!this->emitAdd(*T, E))
2338 return false;
2339 return this->emitStore(*T, E);
2340 }
2341 case UO_PreDec: { // --x
2342 if (!this->visit(SubExpr))
2343 return false;
2344
2345 if (T == PT_Ptr) {
2346 if (!this->emitLoadPtr(E))
2347 return false;
2348 if (!this->emitConstUint8(1, E))
2349 return false;
2350 if (!this->emitSubOffsetUint8(E))
2351 return false;
2352 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
2353 }
2354
2355 // Post-dec and pre-dec are the same if the value is to be discarded.
2356 if (DiscardResult) {
2357 if (T == PT_Float)
2358 return this->emitDecfPop(getRoundingMode(E), E);
2359 return this->emitDecPop(*T, E);
2360 }
2361
2362 if (T == PT_Float) {
2363 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
2364 if (!this->emitLoadFloat(E))
2365 return false;
2366 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
2367 return false;
2368 if (!this->emitSubf(getRoundingMode(E), E))
2369 return false;
2370 return this->emitStoreFloat(E);
2371 }
2372 if (!this->emitLoad(*T, E))
2373 return false;
2374 if (!this->emitConst(1, E))
2375 return false;
2376 if (!this->emitSub(*T, E))
2377 return false;
2378 return this->emitStore(*T, E);
2379 }
2380 case UO_LNot: // !x
2381 if (DiscardResult)
2382 return this->discard(SubExpr);
2383
2384 if (!this->visitBool(SubExpr))
2385 return false;
2386
2387 if (!this->emitInvBool(E))
2388 return false;
2389
2390 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
2391 return this->emitCast(PT_Bool, ET, E);
2392 return true;
2393 case UO_Minus: // -x
2394 if (!this->visit(SubExpr))
2395 return false;
2396 return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
2397 case UO_Plus: // +x
2398 if (!this->visit(SubExpr)) // noop
2399 return false;
2400 return DiscardResult ? this->emitPop(*T, E) : true;
2401 case UO_AddrOf: // &x
2402 // We should already have a pointer when we get here.
2403 if (!this->visit(SubExpr))
2404 return false;
2405 return DiscardResult ? this->emitPop(*T, E) : true;
2406 case UO_Deref: // *x
2407 return dereference(
2408 SubExpr, DerefKind::Read,
2409 [](PrimType) {
2410 llvm_unreachable("Dereferencing requires a pointer");
2411 return false;
2412 },
2413 [this, E](PrimType T) {
2414 return DiscardResult ? this->emitPop(T, E) : true;
2415 });
2416 case UO_Not: // ~x
2417 if (!this->visit(SubExpr))
2418 return false;
2419 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
2420 case UO_Real: // __real x
2421 case UO_Imag: // __imag x
2422 case UO_Extension:
2423 return this->delegate(SubExpr);
2424 case UO_Coawait:
2425 assert(false && "Unhandled opcode");
2426 }
2427
2428 return false;
2429}
2430
2431template <class Emitter>
2433 if (DiscardResult)
2434 return true;
2435
2436 const auto *D = E->getDecl();
2437
2438 if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
2439 return this->emitConst(ECD->getInitVal(), E);
2440 } else if (const auto *BD = dyn_cast<BindingDecl>(D)) {
2441 return this->visit(BD->getBinding());
2442 } else if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
2443 const Function *F = getFunction(FuncDecl);
2444 return F && this->emitGetFnPtr(F, E);
2445 }
2446
2447 // References are implemented via pointers, so when we see a DeclRefExpr
2448 // pointing to a reference, we need to get its value directly (i.e. the
2449 // pointer to the actual value) instead of a pointer to the pointer to the
2450 // value.
2451 bool IsReference = D->getType()->isReferenceType();
2452
2453 // Check for local/global variables and parameters.
2454 if (auto It = Locals.find(D); It != Locals.end()) {
2455 const unsigned Offset = It->second.Offset;
2456
2457 if (IsReference)
2458 return this->emitGetLocal(PT_Ptr, Offset, E);
2459 return this->emitGetPtrLocal(Offset, E);
2460 } else if (auto GlobalIndex = P.getGlobal(D)) {
2461 if (IsReference)
2462 return this->emitGetGlobalPtr(*GlobalIndex, E);
2463
2464 return this->emitGetPtrGlobal(*GlobalIndex, E);
2465 } else if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
2466 if (auto It = this->Params.find(PVD); It != this->Params.end()) {
2467 if (IsReference || !It->second.IsPtr)
2468 return this->emitGetParamPtr(It->second.Offset, E);
2469
2470 return this->emitGetPtrParam(It->second.Offset, E);
2471 }
2472 }
2473
2474 // Handle lambda captures.
2475 if (auto It = this->LambdaCaptures.find(D);
2476 It != this->LambdaCaptures.end()) {
2477 auto [Offset, IsPtr] = It->second;
2478
2479 if (IsPtr)
2480 return this->emitGetThisFieldPtr(Offset, E);
2481 return this->emitGetPtrThisField(Offset, E);
2482 }
2483
2484 // Lazily visit global declarations we haven't seen yet.
2485 // This happens in C.
2486 if (!Ctx.getLangOpts().CPlusPlus) {
2487 if (const auto *VD = dyn_cast<VarDecl>(D);
2488 VD && VD->hasGlobalStorage() && VD->getAnyInitializer()) {
2489 if (!this->visitVarDecl(VD))
2490 return false;
2491 // Retry.
2492 return this->VisitDeclRefExpr(E);
2493 }
2494 }
2495
2496 return this->emitInvalidDeclRef(E, E);
2497}
2498
2499template <class Emitter>
2501 for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent())
2502 C->emitDestruction();
2503}
2504
2505template <class Emitter>
2506unsigned
2508 const RecordType *DerivedType) {
2509 const auto *FinalDecl = cast<CXXRecordDecl>(BaseType->getDecl());
2510 const RecordDecl *CurDecl = DerivedType->getDecl();
2511 const Record *CurRecord = getRecord(CurDecl);
2512 assert(CurDecl && FinalDecl);
2513
2514 unsigned OffsetSum = 0;
2515 for (;;) {
2516 assert(CurRecord->getNumBases() > 0);
2517 // One level up
2518 for (const Record::Base &B : CurRecord->bases()) {
2519 const auto *BaseDecl = cast<CXXRecordDecl>(B.Decl);
2520
2521 if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) {
2522 OffsetSum += B.Offset;
2523 CurRecord = B.R;
2524 CurDecl = BaseDecl;
2525 break;
2526 }
2527 }
2528 if (CurDecl == FinalDecl)
2529 break;
2530 }
2531
2532 assert(OffsetSum > 0);
2533 return OffsetSum;
2534}
2535
2536/// Emit casts from a PrimType to another PrimType.
2537template <class Emitter>
2539 QualType ToQT, const Expr *E) {
2540
2541 if (FromT == PT_Float) {
2542 // Floating to floating.
2543 if (ToT == PT_Float) {
2544 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
2545 return this->emitCastFP(ToSem, getRoundingMode(E), E);
2546 }
2547
2548 // Float to integral.
2549 if (isIntegralType(ToT) || ToT == PT_Bool)
2550 return this->emitCastFloatingIntegral(ToT, E);
2551 }
2552
2553 if (isIntegralType(FromT) || FromT == PT_Bool) {
2554 // Integral to integral.
2555 if (isIntegralType(ToT) || ToT == PT_Bool)
2556 return FromT != ToT ? this->emitCast(FromT, ToT, E) : true;
2557
2558 if (ToT == PT_Float) {
2559 // Integral to floating.
2560 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
2561 return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(E),
2562 E);
2563 }
2564 }
2565
2566 return false;
2567}
2568
2569/// When calling this, we have a pointer of the local-to-destroy
2570/// on the stack.
2571/// Emit destruction of record types (or arrays of record types).
2572/// FIXME: Handle virtual destructors.
2573template <class Emitter>
2575 assert(Desc);
2576 assert(!Desc->isPrimitive());
2577 assert(!Desc->isPrimitiveArray());
2578
2579 // Arrays.
2580 if (Desc->isArray()) {
2581 const Descriptor *ElemDesc = Desc->ElemDesc;
2582 const Record *ElemRecord = ElemDesc->ElemRecord;
2583 assert(ElemRecord); // This is not a primitive array.
2584
2585 if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
2586 Dtor && !Dtor->isTrivial()) {
2587 for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) {
2588 if (!this->emitConstUint64(I, SourceInfo{}))
2589 return false;
2590 if (!this->emitArrayElemPtrUint64(SourceInfo{}))
2591 return false;
2592 if (!this->emitRecordDestruction(Desc->ElemDesc))
2593 return false;
2594 }
2595 }
2596 return this->emitPopPtr(SourceInfo{});
2597 }
2598
2599 const Record *R = Desc->ElemRecord;
2600 assert(R);
2601 // First, destroy all fields.
2602 for (const Record::Field &Field : llvm::reverse(R->fields())) {
2603 const Descriptor *D = Field.Desc;
2604 if (!D->isPrimitive() && !D->isPrimitiveArray()) {
2605 if (!this->emitDupPtr(SourceInfo{}))
2606 return false;
2607 if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
2608 return false;
2609 if (!this->emitRecordDestruction(D))
2610 return false;
2611 }
2612 }
2613
2614 // FIXME: Unions need to be handled differently here. We don't want to
2615 // call the destructor of its members.
2616
2617 // Now emit the destructor and recurse into base classes.
2618 if (const CXXDestructorDecl *Dtor = R->getDestructor();
2619 Dtor && !Dtor->isTrivial()) {
2620 if (const Function *DtorFunc = getFunction(Dtor)) {
2621 assert(DtorFunc->hasThisPointer());
2622 assert(DtorFunc->getNumParams() == 1);
2623 if (!this->emitDupPtr(SourceInfo{}))
2624 return false;
2625 if (!this->emitCall(DtorFunc, SourceInfo{}))
2626 return false;
2627 }
2628 }
2629
2630 for (const Record::Base &Base : llvm::reverse(R->bases())) {
2631 if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
2632 return false;
2633 if (!this->emitRecordDestruction(Base.Desc))
2634 return false;
2635 }
2636 // FIXME: Virtual bases.
2637
2638 // Remove the instance pointer.
2639 return this->emitPopPtr(SourceInfo{});
2640}
2641
2642namespace clang {
2643namespace interp {
2644
2646template class ByteCodeExprGen<EvalEmitter>;
2647
2648} // namespace interp
2649} // namespace clang
#define V(N, I)
Definition: ASTContext.h:3233
ASTImporterLookupTable & LT
DynTypedNode Node
StringRef P
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
llvm::APSInt APSInt
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
const LValueBase getLValueBase() const
Definition: APValue.cpp:966
ArrayRef< LValuePathEntry > getLValuePath() const
Definition: APValue.cpp:986
APSInt & getInt()
Definition: APValue.h:423
bool isLValue() const
Definition: APValue.h:406
bool isInt() const
Definition: APValue.h:401
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
Definition: ASTContext.h:2390
const LangOptions & getLangOpts() const
Definition: ASTContext.h:761
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Definition: Expr.h:4148
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Definition: Expr.h:4326
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Definition: Expr.h:4332
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Definition: Expr.h:4338
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition: Expr.h:5559
Represents a loop initializing the elements of an array.
Definition: Expr.h:5506
llvm::APInt getArraySize() const
Definition: Expr.h:5528
Expr * getSubExpr() const
Get the initializer to use for each array element.
Definition: Expr.h:5526
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2676
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3083
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3847
static bool isLogicalOp(Opcode Opc)
Definition: Expr.h:3979
Expr * getLHS() const
Definition: Expr.h:3896
static bool isCommaOp(Opcode Opc)
Definition: Expr.h:3949
Expr * getRHS() const
Definition: Expr.h:3898
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
Definition: Expr.h:3923
Opcode getOpcode() const
Definition: Expr.h:3891
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1475
const Expr * getSubExpr() const
Definition: ExprCXX.h:1497
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition: ExprCXX.h:720
bool getValue() const
Definition: ExprCXX.h:737
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1523
arg_range arguments()
Definition: ExprCXX.h:1655
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
Definition: ExprCXX.h:1634
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition: ExprCXX.h:1595
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2491
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
Expr * getExpr()
Get the initialization expression that will be used.
Definition: ExprCXX.cpp:1034
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2755
Represents a call to a member function that may be written either with member call syntax (e....
Definition: ExprCXX.h:176
Expr * getImplicitObjectArgument() const
Retrieve the implicit object argument for the member call.
Definition: ExprCXX.cpp:653
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition: ExprCXX.h:4085
bool getValue() const
Definition: ExprCXX.h:4108
The null pointer literal (C++11 [lex.nullptr])
Definition: ExprCXX.h:765
Represents a list-initialization with parenthesis.
Definition: ExprCXX.h:4811
ArrayRef< Expr * > getInitExprs()
Definition: ExprCXX.h:4851
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
Definition: ExprCXX.h:523
Represents the this expression in C++.
Definition: ExprCXX.h:1148
A C++ throw-expression (C++ [except.throw]).
Definition: ExprCXX.h:1192
const Expr * getSubExpr() const
Definition: ExprCXX.h:1212
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2832
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
Definition: Expr.cpp:1603
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition: Expr.h:3002
Expr * getCallee()
Definition: Expr.h:2982
arg_range arguments()
Definition: Expr.h:3071
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition: Expr.cpp:1614
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3502
CastKind getCastKind() const
Definition: Expr.h:3546
Expr * getSubExpr()
Definition: Expr.h:3552
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
static CharUnits One()
One - Construct a CharUnits quantity of one.
Definition: CharUnits.h:58
unsigned getValue() const
Definition: Expr.h:1641
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4095
QualType getComputationLHSType() const
Definition: Expr.h:4129
QualType getComputationResultType() const
Definition: Expr.h:4132
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3432
bool isFileScope() const
Definition: Expr.h:3459
const Expr * getInitializer() const
Definition: Expr.h:3455
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3131
const llvm::APInt & getSize() const
Definition: Type.h:3152
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition: Expr.h:1049
APValue getAPValueResult() const
Definition: Expr.cpp:465
bool hasAPValueResult() const
Definition: Expr.h:1128
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1951
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1242
ValueDecl * getDecl()
Definition: Expr.h:1310
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
bool isInvalidDecl() const
Definition: DeclBase.h:571
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3433
unsigned getNumObjects() const
Definition: ExprCXX.h:3461
This represents one expression.
Definition: Expr.h:110
bool isGLValue() const
Definition: Expr.h:274
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
Definition: Expr.h:239
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3077
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
Definition: Expr.h:463
QualType getType() const
Definition: Expr.h:142
llvm::APFloat getValue() const
Definition: Expr.h:1676
const Expr * getSubExpr() const
Definition: Expr.h:1032
Represents a function declaration or definition.
Definition: Decl.h:1919
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition: Decl.h:2274
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition: Expr.h:4640
Represents an implicitly-generated value initialization of an object of a given type.
Definition: Expr.h:5595
Describes an C or C++ initializer list.
Definition: Expr.h:4843
unsigned getNumInits() const
Definition: Expr.h:4873
ArrayRef< Expr * > inits()
Definition: Expr.h:4883
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1937
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
Definition: ExprCXX.h:2063
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Definition: ExprCXX.cpp:1331
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
Definition: DeclCXX.h:3183
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition: ExprCXX.h:4577
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Definition: ExprCXX.h:4602
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition: ExprCXX.h:4594
LifetimeExtendedTemporaryDecl * getLifetimeExtendedTemporaryDecl()
Definition: ExprCXX.h:4617
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3195
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition: Expr.h:3274
Expr * getBase() const
Definition: Expr.h:3268
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition: Expr.h:2477
Expr * getIndexExpr(unsigned Idx)
Definition: Expr.h:2538
const OffsetOfNode & getComponent(unsigned Idx) const
Definition: Expr.h:2524
unsigned getNumComponents() const
Definition: Expr.h:2534
Helper class for OffsetOfExpr.
Definition: Expr.h:2371
@ Array
An index into an array.
Definition: Expr.h:2376
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1150
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition: Expr.h:1200
ParenExpr - This represents a parethesized expression, e.g.
Definition: Expr.h:2142
const Expr * getSubExpr() const
Definition: Expr.h:2157
Represents a parameter to a function.
Definition: Decl.h:1724
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2840
[C99 6.4.2.2] - A predefined identifier such as func.
Definition: Expr.h:1985
StringLiteral * getFunctionName()
Definition: Expr.h:2044
A (possibly-)qualified type.
Definition: Type.h:736
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:803
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6747
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:6819
Represents a struct/union/class.
Definition: Decl.h:4036
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4933
RecordDecl * getDecl() const
Definition: Type.h:4943
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2951
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition: Expr.h:4724
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Definition: Expr.cpp:2295
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1793
unsigned getLength() const
Definition: Expr.h:1902
uint32_t getCodeUnit(size_t i) const
Definition: Expr.h:1888
unsigned getCharByteWidth() const
Definition: Expr.h:1903
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4333
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition: ExprCXX.h:2755
bool getValue() const
Definition: ExprCXX.h:2796
bool isVoidType() const
Definition: Type.h:7317
bool isBooleanType() const
Definition: Type.h:7433
bool isFundamentalType() const
Tests whether the type is categorized as a fundamental type.
Definition: Type.h:6962
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
Definition: Type.cpp:2293
bool isArrayType() const
Definition: Type.h:7065
bool isPointerType() const
Definition: Type.h:6999
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:7349
bool isReferenceType() const
Definition: Type.h:7011
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:655
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2365
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition: Type.h:7576
bool isFunctionType() const
Definition: Type.h:6995
bool isFloatingType() const
Definition: Type.cpp:2190
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7523
bool isRecordType() const
Definition: Type.h:7089
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2580
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
Definition: Expr.h:2649
bool isArgumentType() const
Definition: Expr.h:2622
UnaryExprOrTypeTrait getKind() const
Definition: Expr.h:2612
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2195
Expr * getSubExpr() const
Definition: Expr.h:2240
Opcode getOpcode() const
Definition: Expr.h:2235
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:703
QualType getType() const
Definition: Decl.h:714
Represents a variable declaration or definition.
Definition: Decl.h:915
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition: Decl.h:1521
bool hasInit() const
Definition: Decl.cpp:2378
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:1185
const Expr * getInit() const
Definition: Decl.h:1327
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Definition: Decl.h:1143
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Definition: Decl.h:1317
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 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 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)
bool VisitBuiltinCallExpr(const CallExpr *E)
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E)
bool VisitCXXMemberCallExpr(const CXXMemberCallExpr *E)
void emitCleanup()
Emits scope cleanup instructions.
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitPredefinedExpr(const PredefinedExpr *E)
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)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
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 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)
bool VisitGNUNullExpr(const GNUNullExpr *E)
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
bool VisitSourceLocExpr(const SourceLocExpr *E)
bool VisitOpaqueValueExpr(const OpaqueValueExpr *E)
bool VisitCXXThisExpr(const CXXThisExpr *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)
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Definition: Context.h:80
Scope used to handle temporaries in toplevel variable declarations.
void addExtended(const Scope::Local &Local) override
DeclScope(ByteCodeExprGen< Emitter > *Ctx, const ValueDecl *VD)
Expression scope which tracks potentially lifetime extended temporaries which are hoisted to the pare...
Bytecode function.
Definition: Function.h:75
bool isFullyCompiled() const
Checks if the function is fully done compiling.
Definition: Function.h:165
bool hasThisPointer() const
Definition: Function.h:167
bool isConstexpr() const
Checks if the function is valid to call in constexpr.
Definition: Function.h:131
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Definition: Function.h:108
Generic scope for local variables.
Scope used to handle initialization methods.
OptionScope(ByteCodeExprGen< Emitter > *Ctx, bool NewDiscardResult, bool NewInitializing)
Root constructor, compiling or discarding primitives.
Context to manage declaration lifetimes.
Definition: Program.h:132
Structure/Class descriptor.
Definition: Record.h:25
unsigned getNumBases() const
Definition: Record.h:89
const CXXDestructorDecl * getDestructor() const
Returns the destructor of the record, if any.
Definition: Record.h:69
const Field * getField(const FieldDecl *FD) const
Returns a field.
Definition: Record.cpp:30
llvm::iterator_range< const_base_iter > bases() const
Definition: Record.h:85
unsigned getNumFields() const
Definition: Record.h:80
llvm::iterator_range< const_field_iter > fields() const
Definition: Record.h:76
const Base * getBase(const RecordDecl *FD) const
Returns a base descriptor.
Definition: Record.cpp:36
Describes a scope block.
Definition: Function.h:33
Describes the statement/declaration an opcode was generated from.
Definition: Source.h:68
Scope chain managing the variable lifetimes.
virtual void addLocal(const Scope::Local &Local)
ByteCodeExprGen< Emitter > * Ctx
ByteCodeExprGen instance.
bool LE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:799
PrimType
Enumeration of the primitive types of the VM.
Definition: PrimType.h:31
llvm::APSInt APSInt
Definition: Floating.h:24
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
Definition: Descriptor.h:26
constexpr bool isIntegralType(PrimType T)
Definition: PrimType.h:59
BinaryOperatorKind
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
Definition: TypeTraits.h:51
@ C
Languages that the frontend can parse and compile.
@ SD_Static
Static storage duration.
Definition: Specifiers.h:318
#define true
Definition: stdbool.h:21
Describes a memory block created by an allocation site.
Definition: Descriptor.h:77
unsigned getNumElems() const
Returns the number of elements stored in the block.
Definition: Descriptor.h:173
bool isPrimitive() const
Checks if the descriptor is of a primitive.
Definition: Descriptor.h:187
QualType getElemQualType() const
Definition: Descriptor.cpp:288
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
Definition: Descriptor.h:180
QualType getType() const
Definition: Descriptor.cpp:278
static constexpr MetadataSize InlineDescMD
Definition: Descriptor.h:98
Descriptor *const ElemDesc
Descriptor of the array element.
Definition: Descriptor.h:103
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
Definition: Descriptor.h:178
bool isRecord() const
Checks if the descriptor is of a record.
Definition: Descriptor.h:192
Record *const ElemRecord
Pointer to the record, if block contains records.
Definition: Descriptor.h:101
bool isArray() const
Checks if the descriptor is of an array.
Definition: Descriptor.h:190
Describes a base class.
Definition: Record.h:35
Describes a record field.
Definition: Record.h:28
const FieldDecl * Decl
Definition: Record.h:29
Information about a local's storage.
Definition: Function.h:36