clang 19.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 "ByteCodeStmtGen.h"
12#include "Context.h"
13#include "Floating.h"
14#include "Function.h"
15#include "InterpShared.h"
16#include "PrimType.h"
17#include "Program.h"
18#include "clang/AST/Attr.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, nullptr), Scope(Ctx->P, VD),
33 OldGlobalDecl(Ctx->GlobalDecl) {
34 Ctx->GlobalDecl = Context::shouldBeGloballyIndexed(VD);
35 }
36
37 ~DeclScope() { this->Ctx->GlobalDecl = OldGlobalDecl; }
38
39private:
41 bool OldGlobalDecl;
42};
43
44/// Scope used to handle initialization methods.
45template <class Emitter> class OptionScope final {
46public:
47 /// Root constructor, compiling or discarding primitives.
48 OptionScope(ByteCodeExprGen<Emitter> *Ctx, bool NewDiscardResult,
49 bool NewInitializing)
50 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
51 OldInitializing(Ctx->Initializing) {
52 Ctx->DiscardResult = NewDiscardResult;
53 Ctx->Initializing = NewInitializing;
54 }
55
57 Ctx->DiscardResult = OldDiscardResult;
58 Ctx->Initializing = OldInitializing;
59 }
60
61private:
62 /// Parent context.
64 /// Old discard flag to restore.
65 bool OldDiscardResult;
66 bool OldInitializing;
67};
68
69} // namespace interp
70} // namespace clang
71
72template <class Emitter>
74 const Expr *SubExpr = CE->getSubExpr();
75 switch (CE->getCastKind()) {
76
77 case CK_LValueToRValue: {
78 if (DiscardResult)
79 return this->discard(SubExpr);
80
81 std::optional<PrimType> SubExprT = classify(SubExpr->getType());
82 // Prepare storage for the result.
83 if (!Initializing && !SubExprT) {
84 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
85 if (!LocalIndex)
86 return false;
87 if (!this->emitGetPtrLocal(*LocalIndex, CE))
88 return false;
89 }
90
91 if (!this->visit(SubExpr))
92 return false;
93
94 if (SubExprT)
95 return this->emitLoadPop(*SubExprT, CE);
96
97 // If the subexpr type is not primitive, we need to perform a copy here.
98 // This happens for example in C when dereferencing a pointer of struct
99 // type.
100 return this->emitMemcpy(CE);
101 }
102
103 case CK_UncheckedDerivedToBase:
104 case CK_DerivedToBase: {
105 if (!this->visit(SubExpr))
106 return false;
107
108 const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
109 if (const auto *PT = dyn_cast<PointerType>(Ty))
110 return PT->getPointeeType()->getAsCXXRecordDecl();
111 return Ty->getAsCXXRecordDecl();
112 };
113
114 // FIXME: We can express a series of non-virtual casts as a single
115 // GetPtrBasePop op.
116 QualType CurType = SubExpr->getType();
117 for (const CXXBaseSpecifier *B : CE->path()) {
118 if (B->isVirtual()) {
119 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))
120 return false;
121 CurType = B->getType();
122 } else {
123 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
124 if (!this->emitGetPtrBasePop(DerivedOffset, CE))
125 return false;
126 CurType = B->getType();
127 }
128 }
129
130 return true;
131 }
132
133 case CK_BaseToDerived: {
134 if (!this->visit(SubExpr))
135 return false;
136
137 unsigned DerivedOffset =
138 collectBaseOffset(SubExpr->getType(), CE->getType());
139
140 return this->emitGetPtrDerivedPop(DerivedOffset, CE);
141 }
142
143 case CK_FloatingCast: {
144 if (DiscardResult)
145 return this->discard(SubExpr);
146 if (!this->visit(SubExpr))
147 return false;
148 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
149 return this->emitCastFP(TargetSemantics, getRoundingMode(CE), CE);
150 }
151
152 case CK_IntegralToFloating: {
153 if (DiscardResult)
154 return this->discard(SubExpr);
155 std::optional<PrimType> FromT = classify(SubExpr->getType());
156 if (!FromT)
157 return false;
158
159 if (!this->visit(SubExpr))
160 return false;
161
162 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
163 llvm::RoundingMode RM = getRoundingMode(CE);
164 return this->emitCastIntegralFloating(*FromT, TargetSemantics, RM, CE);
165 }
166
167 case CK_FloatingToBoolean:
168 case CK_FloatingToIntegral: {
169 if (DiscardResult)
170 return this->discard(SubExpr);
171
172 std::optional<PrimType> ToT = classify(CE->getType());
173
174 if (!ToT)
175 return false;
176
177 if (!this->visit(SubExpr))
178 return false;
179
180 if (ToT == PT_IntAP)
181 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->getType()),
182 CE);
183 if (ToT == PT_IntAPS)
184 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->getType()),
185 CE);
186
187 return this->emitCastFloatingIntegral(*ToT, CE);
188 }
189
190 case CK_NullToPointer: {
191 if (DiscardResult)
192 return true;
193
194 const Descriptor *Desc = nullptr;
195 const QualType PointeeType = CE->getType()->getPointeeType();
196 if (!PointeeType.isNull()) {
197 if (std::optional<PrimType> T = classify(PointeeType))
198 Desc = P.createDescriptor(SubExpr, *T);
199 }
200 return this->emitNull(classifyPrim(CE->getType()), Desc, CE);
201 }
202
203 case CK_PointerToIntegral: {
204 if (DiscardResult)
205 return this->discard(SubExpr);
206
207 if (!this->visit(SubExpr))
208 return false;
209
210 // If SubExpr doesn't result in a pointer, make it one.
211 if (PrimType FromT = classifyPrim(SubExpr->getType()); FromT != PT_Ptr) {
212 assert(isPtrType(FromT));
213 if (!this->emitDecayPtr(FromT, PT_Ptr, CE))
214 return false;
215 }
216
217 PrimType T = classifyPrim(CE->getType());
218 if (T == PT_IntAP)
219 return this->emitCastPointerIntegralAP(Ctx.getBitWidth(CE->getType()),
220 CE);
221 if (T == PT_IntAPS)
222 return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(CE->getType()),
223 CE);
224 return this->emitCastPointerIntegral(T, CE);
225 }
226
227 case CK_ArrayToPointerDecay: {
228 if (!this->visit(SubExpr))
229 return false;
230 if (!this->emitArrayDecay(CE))
231 return false;
232 if (DiscardResult)
233 return this->emitPopPtr(CE);
234 return true;
235 }
236
237 case CK_IntegralToPointer: {
238 QualType IntType = SubExpr->getType();
239 assert(IntType->isIntegralOrEnumerationType());
240 if (!this->visit(SubExpr))
241 return false;
242 // FIXME: I think the discard is wrong since the int->ptr cast might cause a
243 // diagnostic.
244 PrimType T = classifyPrim(IntType);
245 if (DiscardResult)
246 return this->emitPop(T, CE);
247
248 QualType PtrType = CE->getType();
249 assert(PtrType->isPointerType());
250
251 const Descriptor *Desc;
252 if (std::optional<PrimType> T = classify(PtrType->getPointeeType()))
253 Desc = P.createDescriptor(SubExpr, *T);
254 else if (PtrType->getPointeeType()->isVoidType())
255 Desc = nullptr;
256 else
257 Desc = P.createDescriptor(CE, PtrType->getPointeeType().getTypePtr(),
258 Descriptor::InlineDescMD, true, false,
259 /*IsMutable=*/false, nullptr);
260
261 if (!this->emitGetIntPtr(T, Desc, CE))
262 return false;
263
264 PrimType DestPtrT = classifyPrim(PtrType);
265 if (DestPtrT == PT_Ptr)
266 return true;
267
268 // In case we're converting the integer to a non-Pointer.
269 return this->emitDecayPtr(PT_Ptr, DestPtrT, CE);
270 }
271
272 case CK_AtomicToNonAtomic:
273 case CK_ConstructorConversion:
274 case CK_FunctionToPointerDecay:
275 case CK_NonAtomicToAtomic:
276 case CK_NoOp:
277 case CK_UserDefinedConversion:
278 return this->delegate(SubExpr);
279
280 case CK_BitCast: {
281 // Reject bitcasts to atomic types.
282 if (CE->getType()->isAtomicType()) {
283 if (!this->discard(SubExpr))
284 return false;
285 return this->emitInvalidCast(CastKind::Reinterpret, CE);
286 }
287
288 if (DiscardResult)
289 return this->discard(SubExpr);
290
291 std::optional<PrimType> FromT = classify(SubExpr->getType());
292 std::optional<PrimType> ToT = classify(CE->getType());
293 if (!FromT || !ToT)
294 return false;
295
296 assert(isPtrType(*FromT));
297 assert(isPtrType(*ToT));
298 if (FromT == ToT)
299 return this->delegate(SubExpr);
300
301 if (!this->visit(SubExpr))
302 return false;
303 return this->emitDecayPtr(*FromT, *ToT, CE);
304 }
305
306 case CK_IntegralToBoolean:
307 case CK_IntegralCast: {
308 if (DiscardResult)
309 return this->discard(SubExpr);
310 std::optional<PrimType> FromT = classify(SubExpr->getType());
311 std::optional<PrimType> ToT = classify(CE->getType());
312
313 if (!FromT || !ToT)
314 return false;
315
316 if (!this->visit(SubExpr))
317 return false;
318
319 if (ToT == PT_IntAP)
320 return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->getType()), CE);
321 if (ToT == PT_IntAPS)
322 return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->getType()), CE);
323
324 if (FromT == ToT)
325 return true;
326 return this->emitCast(*FromT, *ToT, CE);
327 }
328
329 case CK_PointerToBoolean: {
330 PrimType PtrT = classifyPrim(SubExpr->getType());
331
332 // Just emit p != nullptr for this.
333 if (!this->visit(SubExpr))
334 return false;
335
336 if (!this->emitNull(PtrT, nullptr, CE))
337 return false;
338
339 return this->emitNE(PtrT, CE);
340 }
341
342 case CK_IntegralComplexToBoolean:
343 case CK_FloatingComplexToBoolean: {
344 if (DiscardResult)
345 return this->discard(SubExpr);
346 if (!this->visit(SubExpr))
347 return false;
348 return this->emitComplexBoolCast(SubExpr);
349 }
350
351 case CK_IntegralComplexToReal:
352 case CK_FloatingComplexToReal:
353 return this->emitComplexReal(SubExpr);
354
355 case CK_IntegralRealToComplex:
356 case CK_FloatingRealToComplex: {
357 // We're creating a complex value here, so we need to
358 // allocate storage for it.
359 if (!Initializing) {
360 std::optional<unsigned> LocalIndex = allocateLocal(CE);
361 if (!LocalIndex)
362 return false;
363 if (!this->emitGetPtrLocal(*LocalIndex, CE))
364 return false;
365 }
366
367 // Init the complex value to {SubExpr, 0}.
368 if (!this->visitArrayElemInit(0, SubExpr))
369 return false;
370 // Zero-init the second element.
371 PrimType T = classifyPrim(SubExpr->getType());
372 if (!this->visitZeroInitializer(T, SubExpr->getType(), SubExpr))
373 return false;
374 return this->emitInitElem(T, 1, SubExpr);
375 }
376
377 case CK_IntegralComplexCast:
378 case CK_FloatingComplexCast:
379 case CK_IntegralComplexToFloatingComplex:
380 case CK_FloatingComplexToIntegralComplex: {
381 assert(CE->getType()->isAnyComplexType());
382 assert(SubExpr->getType()->isAnyComplexType());
383 if (DiscardResult)
384 return this->discard(SubExpr);
385
386 if (!Initializing) {
387 std::optional<unsigned> LocalIndex = allocateLocal(CE);
388 if (!LocalIndex)
389 return false;
390 if (!this->emitGetPtrLocal(*LocalIndex, CE))
391 return false;
392 }
393
394 // Location for the SubExpr.
395 // Since SubExpr is of complex type, visiting it results in a pointer
396 // anyway, so we just create a temporary pointer variable.
397 unsigned SubExprOffset = allocateLocalPrimitive(
398 SubExpr, PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false);
399 if (!this->visit(SubExpr))
400 return false;
401 if (!this->emitSetLocal(PT_Ptr, SubExprOffset, CE))
402 return false;
403
404 PrimType SourceElemT = classifyComplexElementType(SubExpr->getType());
405 QualType DestElemType =
406 CE->getType()->getAs<ComplexType>()->getElementType();
407 PrimType DestElemT = classifyPrim(DestElemType);
408 // Cast both elements individually.
409 for (unsigned I = 0; I != 2; ++I) {
410 if (!this->emitGetLocal(PT_Ptr, SubExprOffset, CE))
411 return false;
412 if (!this->emitArrayElemPop(SourceElemT, I, CE))
413 return false;
414
415 // Do the cast.
416 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
417 return false;
418
419 // Save the value.
420 if (!this->emitInitElem(DestElemT, I, CE))
421 return false;
422 }
423 return true;
424 }
425
426 case CK_VectorSplat: {
427 assert(!classify(CE->getType()));
428 assert(classify(SubExpr->getType()));
429 assert(CE->getType()->isVectorType());
430
431 if (DiscardResult)
432 return this->discard(SubExpr);
433
434 assert(Initializing); // FIXME: Not always correct.
435 const auto *VT = CE->getType()->getAs<VectorType>();
436 PrimType ElemT = classifyPrim(SubExpr);
437 unsigned ElemOffset = allocateLocalPrimitive(
438 SubExpr, ElemT, /*IsConst=*/true, /*IsExtended=*/false);
439
440 if (!this->visit(SubExpr))
441 return false;
442 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
443 return false;
444
445 for (unsigned I = 0; I != VT->getNumElements(); ++I) {
446 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
447 return false;
448 if (!this->emitInitElem(ElemT, I, CE))
449 return false;
450 }
451
452 return true;
453 }
454
455 case CK_ToVoid:
456 return discard(SubExpr);
457
458 default:
459 return this->emitInvalid(CE);
460 }
461 llvm_unreachable("Unhandled clang::CastKind enum");
462}
463
464template <class Emitter>
466 if (DiscardResult)
467 return true;
468
469 return this->emitConst(LE->getValue(), LE);
470}
471
472template <class Emitter>
474 if (DiscardResult)
475 return true;
476
477 return this->emitConstFloat(E->getValue(), E);
478}
479
480template <class Emitter>
482 const ImaginaryLiteral *E) {
483 assert(E->getType()->isAnyComplexType());
484 if (DiscardResult)
485 return true;
486
487 if (!Initializing) {
488 std::optional<unsigned> LocalIndex = allocateLocal(E);
489 if (!LocalIndex)
490 return false;
491 if (!this->emitGetPtrLocal(*LocalIndex, E))
492 return false;
493 }
494
495 const Expr *SubExpr = E->getSubExpr();
496 PrimType SubExprT = classifyPrim(SubExpr->getType());
497
498 if (!this->visitZeroInitializer(SubExprT, SubExpr->getType(), SubExpr))
499 return false;
500 if (!this->emitInitElem(SubExprT, 0, SubExpr))
501 return false;
502 return this->visitArrayElemInit(1, SubExpr);
503}
504
505template <class Emitter>
507 return this->delegate(E->getSubExpr());
508}
509
510template <class Emitter>
512 // Need short-circuiting for these.
513 if (BO->isLogicalOp())
514 return this->VisitLogicalBinOp(BO);
515
516 const Expr *LHS = BO->getLHS();
517 const Expr *RHS = BO->getRHS();
518
519 // Handle comma operators. Just discard the LHS
520 // and delegate to RHS.
521 if (BO->isCommaOp()) {
522 if (!this->discard(LHS))
523 return false;
524 if (RHS->getType()->isVoidType())
525 return this->discard(RHS);
526
527 return this->delegate(RHS);
528 }
529
530 if (BO->getType()->isAnyComplexType())
531 return this->VisitComplexBinOp(BO);
532 if ((LHS->getType()->isAnyComplexType() ||
533 RHS->getType()->isAnyComplexType()) &&
534 BO->isComparisonOp())
535 return this->emitComplexComparison(LHS, RHS, BO);
536
537 if (BO->isPtrMemOp())
538 return this->visit(RHS);
539
540 // Typecheck the args.
541 std::optional<PrimType> LT = classify(LHS->getType());
542 std::optional<PrimType> RT = classify(RHS->getType());
543 std::optional<PrimType> T = classify(BO->getType());
544
545 // Special case for C++'s three-way/spaceship operator <=>, which
546 // returns a std::{strong,weak,partial}_ordering (which is a class, so doesn't
547 // have a PrimType).
548 if (!T && BO->getOpcode() == BO_Cmp) {
549 if (DiscardResult)
550 return true;
551 const ComparisonCategoryInfo *CmpInfo =
552 Ctx.getASTContext().CompCategories.lookupInfoForType(BO->getType());
553 assert(CmpInfo);
554
555 // We need a temporary variable holding our return value.
556 if (!Initializing) {
557 std::optional<unsigned> ResultIndex = this->allocateLocal(BO);
558 if (!this->emitGetPtrLocal(*ResultIndex, BO))
559 return false;
560 }
561
562 if (!visit(LHS) || !visit(RHS))
563 return false;
564
565 return this->emitCMP3(*LT, CmpInfo, BO);
566 }
567
568 if (!LT || !RT || !T)
569 return false;
570
571 // Pointer arithmetic special case.
572 if (BO->getOpcode() == BO_Add || BO->getOpcode() == BO_Sub) {
573 if (isPtrType(*T) || (isPtrType(*LT) && isPtrType(*RT)))
574 return this->VisitPointerArithBinOp(BO);
575 }
576
577 if (!visit(LHS) || !visit(RHS))
578 return false;
579
580 // For languages such as C, cast the result of one
581 // of our comparision opcodes to T (which is usually int).
582 auto MaybeCastToBool = [this, T, BO](bool Result) {
583 if (!Result)
584 return false;
585 if (DiscardResult)
586 return this->emitPop(*T, BO);
587 if (T != PT_Bool)
588 return this->emitCast(PT_Bool, *T, BO);
589 return true;
590 };
591
592 auto Discard = [this, T, BO](bool Result) {
593 if (!Result)
594 return false;
595 return DiscardResult ? this->emitPop(*T, BO) : true;
596 };
597
598 switch (BO->getOpcode()) {
599 case BO_EQ:
600 return MaybeCastToBool(this->emitEQ(*LT, BO));
601 case BO_NE:
602 return MaybeCastToBool(this->emitNE(*LT, BO));
603 case BO_LT:
604 return MaybeCastToBool(this->emitLT(*LT, BO));
605 case BO_LE:
606 return MaybeCastToBool(this->emitLE(*LT, BO));
607 case BO_GT:
608 return MaybeCastToBool(this->emitGT(*LT, BO));
609 case BO_GE:
610 return MaybeCastToBool(this->emitGE(*LT, BO));
611 case BO_Sub:
612 if (BO->getType()->isFloatingType())
613 return Discard(this->emitSubf(getRoundingMode(BO), BO));
614 return Discard(this->emitSub(*T, BO));
615 case BO_Add:
616 if (BO->getType()->isFloatingType())
617 return Discard(this->emitAddf(getRoundingMode(BO), BO));
618 return Discard(this->emitAdd(*T, BO));
619 case BO_Mul:
620 if (BO->getType()->isFloatingType())
621 return Discard(this->emitMulf(getRoundingMode(BO), BO));
622 return Discard(this->emitMul(*T, BO));
623 case BO_Rem:
624 return Discard(this->emitRem(*T, BO));
625 case BO_Div:
626 if (BO->getType()->isFloatingType())
627 return Discard(this->emitDivf(getRoundingMode(BO), BO));
628 return Discard(this->emitDiv(*T, BO));
629 case BO_Assign:
630 if (DiscardResult)
631 return LHS->refersToBitField() ? this->emitStoreBitFieldPop(*T, BO)
632 : this->emitStorePop(*T, BO);
633 if (LHS->refersToBitField()) {
634 if (!this->emitStoreBitField(*T, BO))
635 return false;
636 } else {
637 if (!this->emitStore(*T, BO))
638 return false;
639 }
640 // Assignments aren't necessarily lvalues in C.
641 // Load from them in that case.
642 if (!BO->isLValue())
643 return this->emitLoadPop(*T, BO);
644 return true;
645 case BO_And:
646 return Discard(this->emitBitAnd(*T, BO));
647 case BO_Or:
648 return Discard(this->emitBitOr(*T, BO));
649 case BO_Shl:
650 return Discard(this->emitShl(*LT, *RT, BO));
651 case BO_Shr:
652 return Discard(this->emitShr(*LT, *RT, BO));
653 case BO_Xor:
654 return Discard(this->emitBitXor(*T, BO));
655 case BO_LOr:
656 case BO_LAnd:
657 llvm_unreachable("Already handled earlier");
658 default:
659 return false;
660 }
661
662 llvm_unreachable("Unhandled binary op");
663}
664
665/// Perform addition/subtraction of a pointer and an integer or
666/// subtraction of two pointers.
667template <class Emitter>
670 const Expr *LHS = E->getLHS();
671 const Expr *RHS = E->getRHS();
672
673 if ((Op != BO_Add && Op != BO_Sub) ||
674 (!LHS->getType()->isPointerType() && !RHS->getType()->isPointerType()))
675 return false;
676
677 std::optional<PrimType> LT = classify(LHS);
678 std::optional<PrimType> RT = classify(RHS);
679
680 if (!LT || !RT)
681 return false;
682
683 if (LHS->getType()->isPointerType() && RHS->getType()->isPointerType()) {
684 if (Op != BO_Sub)
685 return false;
686
687 assert(E->getType()->isIntegerType());
688 if (!visit(RHS) || !visit(LHS))
689 return false;
690
691 return this->emitSubPtr(classifyPrim(E->getType()), E);
692 }
693
694 PrimType OffsetType;
695 if (LHS->getType()->isIntegerType()) {
696 if (!visit(RHS) || !visit(LHS))
697 return false;
698 OffsetType = *LT;
699 } else if (RHS->getType()->isIntegerType()) {
700 if (!visit(LHS) || !visit(RHS))
701 return false;
702 OffsetType = *RT;
703 } else {
704 return false;
705 }
706
707 if (Op == BO_Add)
708 return this->emitAddOffset(OffsetType, E);
709 else if (Op == BO_Sub)
710 return this->emitSubOffset(OffsetType, E);
711
712 return false;
713}
714
715template <class Emitter>
717 assert(E->isLogicalOp());
719 const Expr *LHS = E->getLHS();
720 const Expr *RHS = E->getRHS();
721 std::optional<PrimType> T = classify(E->getType());
722
723 if (Op == BO_LOr) {
724 // Logical OR. Visit LHS and only evaluate RHS if LHS was FALSE.
725 LabelTy LabelTrue = this->getLabel();
726 LabelTy LabelEnd = this->getLabel();
727
728 if (!this->visitBool(LHS))
729 return false;
730 if (!this->jumpTrue(LabelTrue))
731 return false;
732
733 if (!this->visitBool(RHS))
734 return false;
735 if (!this->jump(LabelEnd))
736 return false;
737
738 this->emitLabel(LabelTrue);
739 this->emitConstBool(true, E);
740 this->fallthrough(LabelEnd);
741 this->emitLabel(LabelEnd);
742
743 } else {
744 assert(Op == BO_LAnd);
745 // Logical AND.
746 // Visit LHS. Only visit RHS if LHS was TRUE.
747 LabelTy LabelFalse = this->getLabel();
748 LabelTy LabelEnd = this->getLabel();
749
750 if (!this->visitBool(LHS))
751 return false;
752 if (!this->jumpFalse(LabelFalse))
753 return false;
754
755 if (!this->visitBool(RHS))
756 return false;
757 if (!this->jump(LabelEnd))
758 return false;
759
760 this->emitLabel(LabelFalse);
761 this->emitConstBool(false, E);
762 this->fallthrough(LabelEnd);
763 this->emitLabel(LabelEnd);
764 }
765
766 if (DiscardResult)
767 return this->emitPopBool(E);
768
769 // For C, cast back to integer type.
770 assert(T);
771 if (T != PT_Bool)
772 return this->emitCast(PT_Bool, *T, E);
773 return true;
774}
775
776template <class Emitter>
778 // Prepare storage for result.
779 if (!Initializing) {
780 std::optional<unsigned> LocalIndex = allocateLocal(E);
781 if (!LocalIndex)
782 return false;
783 if (!this->emitGetPtrLocal(*LocalIndex, E))
784 return false;
785 }
786
787 // Both LHS and RHS might _not_ be of complex type, but one of them
788 // needs to be.
789 const Expr *LHS = E->getLHS();
790 const Expr *RHS = E->getRHS();
791
792 PrimType ResultElemT = this->classifyComplexElementType(E->getType());
793 unsigned ResultOffset = ~0u;
794 if (!DiscardResult)
795 ResultOffset = this->allocateLocalPrimitive(E, PT_Ptr, true, false);
796
797 // Save result pointer in ResultOffset
798 if (!this->DiscardResult) {
799 if (!this->emitDupPtr(E))
800 return false;
801 if (!this->emitSetLocal(PT_Ptr, ResultOffset, E))
802 return false;
803 }
804 QualType LHSType = LHS->getType();
805 if (const auto *AT = LHSType->getAs<AtomicType>())
806 LHSType = AT->getValueType();
807 QualType RHSType = RHS->getType();
808 if (const auto *AT = RHSType->getAs<AtomicType>())
809 RHSType = AT->getValueType();
810
811 // Evaluate LHS and save value to LHSOffset.
812 bool LHSIsComplex;
813 unsigned LHSOffset;
814 if (LHSType->isAnyComplexType()) {
815 LHSIsComplex = true;
816 LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false);
817 if (!this->visit(LHS))
818 return false;
819 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
820 return false;
821 } else {
822 LHSIsComplex = false;
823 PrimType LHST = classifyPrim(LHSType);
824 LHSOffset = this->allocateLocalPrimitive(LHS, LHST, true, false);
825 if (!this->visit(LHS))
826 return false;
827 if (!this->emitSetLocal(LHST, LHSOffset, E))
828 return false;
829 }
830
831 // Same with RHS.
832 bool RHSIsComplex;
833 unsigned RHSOffset;
834 if (RHSType->isAnyComplexType()) {
835 RHSIsComplex = true;
836 RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false);
837 if (!this->visit(RHS))
838 return false;
839 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
840 return false;
841 } else {
842 RHSIsComplex = false;
843 PrimType RHST = classifyPrim(RHSType);
844 RHSOffset = this->allocateLocalPrimitive(RHS, RHST, true, false);
845 if (!this->visit(RHS))
846 return false;
847 if (!this->emitSetLocal(RHST, RHSOffset, E))
848 return false;
849 }
850
851 // For both LHS and RHS, either load the value from the complex pointer, or
852 // directly from the local variable. For index 1 (i.e. the imaginary part),
853 // just load 0 and do the operation anyway.
854 auto loadComplexValue = [this](bool IsComplex, unsigned ElemIndex,
855 unsigned Offset, const Expr *E) -> bool {
856 if (IsComplex) {
857 if (!this->emitGetLocal(PT_Ptr, Offset, E))
858 return false;
859 return this->emitArrayElemPop(classifyComplexElementType(E->getType()),
860 ElemIndex, E);
861 }
862 if (ElemIndex == 0)
863 return this->emitGetLocal(classifyPrim(E->getType()), Offset, E);
864 return this->visitZeroInitializer(classifyPrim(E->getType()), E->getType(),
865 E);
866 };
867
868 // Now we can get pointers to the LHS and RHS from the offsets above.
870 for (unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
871 // Result pointer for the store later.
872 if (!this->DiscardResult) {
873 if (!this->emitGetLocal(PT_Ptr, ResultOffset, E))
874 return false;
875 }
876
877 if (!loadComplexValue(LHSIsComplex, ElemIndex, LHSOffset, LHS))
878 return false;
879
880 if (!loadComplexValue(RHSIsComplex, ElemIndex, RHSOffset, RHS))
881 return false;
882
883 // The actual operation.
884 switch (Op) {
885 case BO_Add:
886 if (ResultElemT == PT_Float) {
887 if (!this->emitAddf(getRoundingMode(E), E))
888 return false;
889 } else {
890 if (!this->emitAdd(ResultElemT, E))
891 return false;
892 }
893 break;
894 case BO_Sub:
895 if (ResultElemT == PT_Float) {
896 if (!this->emitSubf(getRoundingMode(E), E))
897 return false;
898 } else {
899 if (!this->emitSub(ResultElemT, E))
900 return false;
901 }
902 break;
903
904 default:
905 return false;
906 }
907
908 if (!this->DiscardResult) {
909 // Initialize array element with the value we just computed.
910 if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))
911 return false;
912 } else {
913 if (!this->emitPop(ResultElemT, E))
914 return false;
915 }
916 }
917 return true;
918}
919
920template <class Emitter>
922 QualType QT = E->getType();
923
924 if (std::optional<PrimType> T = classify(QT))
925 return this->visitZeroInitializer(*T, QT, E);
926
927 if (QT->isRecordType()) {
928 const RecordDecl *RD = QT->getAsRecordDecl();
929 assert(RD);
930 if (RD->isInvalidDecl())
931 return false;
932 if (RD->isUnion()) {
933 // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the
934 // object's first non-static named data member is zero-initialized
935 // FIXME
936 return false;
937 }
938
939 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
940 CXXRD && CXXRD->getNumVBases() > 0) {
941 // TODO: Diagnose.
942 return false;
943 }
944
945 const Record *R = getRecord(QT);
946 if (!R)
947 return false;
948
949 assert(Initializing);
950 return this->visitZeroRecordInitializer(R, E);
951 }
952
953 if (QT->isIncompleteArrayType())
954 return true;
955
956 if (QT->isArrayType()) {
957 const ArrayType *AT = QT->getAsArrayTypeUnsafe();
958 assert(AT);
959 const auto *CAT = cast<ConstantArrayType>(AT);
960 size_t NumElems = CAT->getZExtSize();
961 PrimType ElemT = classifyPrim(CAT->getElementType());
962
963 for (size_t I = 0; I != NumElems; ++I) {
964 if (!this->visitZeroInitializer(ElemT, CAT->getElementType(), E))
965 return false;
966 if (!this->emitInitElem(ElemT, I, E))
967 return false;
968 }
969
970 return true;
971 }
972
973 if (const auto *ComplexTy = E->getType()->getAs<ComplexType>()) {
974 assert(Initializing);
975 QualType ElemQT = ComplexTy->getElementType();
976 PrimType ElemT = classifyPrim(ElemQT);
977 for (unsigned I = 0; I < 2; ++I) {
978 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
979 return false;
980 if (!this->emitInitElem(ElemT, I, E))
981 return false;
982 }
983 return true;
984 }
985
986 if (const auto *VecT = E->getType()->getAs<VectorType>()) {
987 unsigned NumVecElements = VecT->getNumElements();
988 QualType ElemQT = VecT->getElementType();
989 PrimType ElemT = classifyPrim(ElemQT);
990
991 for (unsigned I = 0; I < NumVecElements; ++I) {
992 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
993 return false;
994 if (!this->emitInitElem(ElemT, I, E))
995 return false;
996 }
997 return true;
998 }
999
1000 return false;
1001}
1002
1003template <class Emitter>
1005 const ArraySubscriptExpr *E) {
1006 const Expr *Base = E->getBase();
1007 const Expr *Index = E->getIdx();
1008
1009 if (DiscardResult)
1010 return this->discard(Base) && this->discard(Index);
1011
1012 // Take pointer of LHS, add offset from RHS.
1013 // What's left on the stack after this is a pointer.
1014 if (!this->visit(Base))
1015 return false;
1016
1017 if (!this->visit(Index))
1018 return false;
1019
1020 PrimType IndexT = classifyPrim(Index->getType());
1021 return this->emitArrayElemPtrPop(IndexT, E);
1022}
1023
1024template <class Emitter>
1026 const Expr *ArrayFiller,
1027 const Expr *E) {
1028 if (E->getType()->isVoidType())
1029 return this->emitInvalid(E);
1030
1031 // Handle discarding first.
1032 if (DiscardResult) {
1033 for (const Expr *Init : Inits) {
1034 if (!this->discard(Init))
1035 return false;
1036 }
1037 return true;
1038 }
1039
1040 // Primitive values.
1041 if (std::optional<PrimType> T = classify(E->getType())) {
1042 assert(!DiscardResult);
1043 if (Inits.size() == 0)
1044 return this->visitZeroInitializer(*T, E->getType(), E);
1045 assert(Inits.size() == 1);
1046 return this->delegate(Inits[0]);
1047 }
1048
1049 QualType T = E->getType();
1050 if (T->isRecordType()) {
1051 const Record *R = getRecord(E->getType());
1052
1053 if (Inits.size() == 1 && E->getType() == Inits[0]->getType()) {
1054 return this->visitInitializer(Inits[0]);
1055 }
1056
1057 unsigned InitIndex = 0;
1058 for (const Expr *Init : Inits) {
1059 // Skip unnamed bitfields.
1060 while (InitIndex < R->getNumFields() &&
1061 R->getField(InitIndex)->Decl->isUnnamedBitField())
1062 ++InitIndex;
1063
1064 if (!this->emitDupPtr(E))
1065 return false;
1066
1067 if (std::optional<PrimType> T = classify(Init)) {
1068 const Record::Field *FieldToInit = R->getField(InitIndex);
1069 if (!this->visit(Init))
1070 return false;
1071
1072 if (FieldToInit->isBitField()) {
1073 if (!this->emitInitBitField(*T, FieldToInit, E))
1074 return false;
1075 } else {
1076 if (!this->emitInitField(*T, FieldToInit->Offset, E))
1077 return false;
1078 }
1079
1080 if (!this->emitPopPtr(E))
1081 return false;
1082 ++InitIndex;
1083 } else {
1084 // Initializer for a direct base class.
1085 if (const Record::Base *B = R->getBase(Init->getType())) {
1086 if (!this->emitGetPtrBasePop(B->Offset, Init))
1087 return false;
1088
1089 if (!this->visitInitializer(Init))
1090 return false;
1091
1092 if (!this->emitFinishInitPop(E))
1093 return false;
1094 // Base initializers don't increase InitIndex, since they don't count
1095 // into the Record's fields.
1096 } else {
1097 const Record::Field *FieldToInit = R->getField(InitIndex);
1098 // Non-primitive case. Get a pointer to the field-to-initialize
1099 // on the stack and recurse into visitInitializer().
1100 if (!this->emitGetPtrField(FieldToInit->Offset, Init))
1101 return false;
1102
1103 if (!this->visitInitializer(Init))
1104 return false;
1105
1106 if (!this->emitPopPtr(E))
1107 return false;
1108 ++InitIndex;
1109 }
1110 }
1111 }
1112 return true;
1113 }
1114
1115 if (T->isArrayType()) {
1116 unsigned ElementIndex = 0;
1117 for (const Expr *Init : Inits) {
1118 if (!this->visitArrayElemInit(ElementIndex, Init))
1119 return false;
1120 ++ElementIndex;
1121 }
1122
1123 // Expand the filler expression.
1124 // FIXME: This should go away.
1125 if (ArrayFiller) {
1126 const ConstantArrayType *CAT =
1127 Ctx.getASTContext().getAsConstantArrayType(E->getType());
1128 uint64_t NumElems = CAT->getZExtSize();
1129
1130 for (; ElementIndex != NumElems; ++ElementIndex) {
1131 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller))
1132 return false;
1133 }
1134 }
1135
1136 return true;
1137 }
1138
1139 if (const auto *ComplexTy = E->getType()->getAs<ComplexType>()) {
1140 unsigned NumInits = Inits.size();
1141
1142 if (NumInits == 1)
1143 return this->delegate(Inits[0]);
1144
1145 QualType ElemQT = ComplexTy->getElementType();
1146 PrimType ElemT = classifyPrim(ElemQT);
1147 if (NumInits == 0) {
1148 // Zero-initialize both elements.
1149 for (unsigned I = 0; I < 2; ++I) {
1150 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1151 return false;
1152 if (!this->emitInitElem(ElemT, I, E))
1153 return false;
1154 }
1155 } else if (NumInits == 2) {
1156 unsigned InitIndex = 0;
1157 for (const Expr *Init : Inits) {
1158 if (!this->visit(Init))
1159 return false;
1160
1161 if (!this->emitInitElem(ElemT, InitIndex, E))
1162 return false;
1163 ++InitIndex;
1164 }
1165 }
1166 return true;
1167 }
1168
1169 if (const auto *VecT = E->getType()->getAs<VectorType>()) {
1170 unsigned NumVecElements = VecT->getNumElements();
1171 assert(NumVecElements >= Inits.size());
1172
1173 QualType ElemQT = VecT->getElementType();
1174 PrimType ElemT = classifyPrim(ElemQT);
1175
1176 // All initializer elements.
1177 unsigned InitIndex = 0;
1178 for (const Expr *Init : Inits) {
1179 if (!this->visit(Init))
1180 return false;
1181
1182 // If the initializer is of vector type itself, we have to deconstruct
1183 // that and initialize all the target fields from the initializer fields.
1184 if (const auto *InitVecT = Init->getType()->getAs<VectorType>()) {
1185 if (!this->emitCopyArray(ElemT, 0, InitIndex, InitVecT->getNumElements(), E))
1186 return false;
1187 InitIndex += InitVecT->getNumElements();
1188 } else {
1189 if (!this->emitInitElem(ElemT, InitIndex, E))
1190 return false;
1191 ++InitIndex;
1192 }
1193 }
1194
1195 assert(InitIndex <= NumVecElements);
1196
1197 // Fill the rest with zeroes.
1198 for (; InitIndex != NumVecElements; ++InitIndex) {
1199 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1200 return false;
1201 if (!this->emitInitElem(ElemT, InitIndex, E))
1202 return false;
1203 }
1204 return true;
1205 }
1206
1207 return false;
1208}
1209
1210/// Pointer to the array(not the element!) must be on the stack when calling
1211/// this.
1212template <class Emitter>
1214 const Expr *Init) {
1215 if (std::optional<PrimType> T = classify(Init->getType())) {
1216 // Visit the primitive element like normal.
1217 if (!this->visit(Init))
1218 return false;
1219 return this->emitInitElem(*T, ElemIndex, Init);
1220 }
1221
1222 // Advance the pointer currently on the stack to the given
1223 // dimension.
1224 if (!this->emitConstUint32(ElemIndex, Init))
1225 return false;
1226 if (!this->emitArrayElemPtrUint32(Init))
1227 return false;
1228 if (!this->visitInitializer(Init))
1229 return false;
1230 return this->emitFinishInitPop(Init);
1231}
1232
1233template <class Emitter>
1235 return this->visitInitList(E->inits(), E->getArrayFiller(), E);
1236}
1237
1238template <class Emitter>
1240 const CXXParenListInitExpr *E) {
1241 return this->visitInitList(E->getInitExprs(), E->getArrayFiller(), E);
1242}
1243
1244template <class Emitter>
1247 return this->delegate(E->getReplacement());
1248}
1249
1250template <class Emitter>
1252 std::optional<PrimType> T = classify(E->getType());
1253 if (T && E->hasAPValueResult()) {
1254 // Try to emit the APValue directly, without visiting the subexpr.
1255 // This will only fail if we can't emit the APValue, so won't emit any
1256 // diagnostics or any double values.
1257 if (DiscardResult)
1258 return true;
1259
1260 if (this->visitAPValue(E->getAPValueResult(), *T, E))
1261 return true;
1262 }
1263 return this->delegate(E->getSubExpr());
1264}
1265
1267 UnaryExprOrTypeTrait Kind) {
1268 bool AlignOfReturnsPreferred =
1269 ASTCtx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
1270
1271 // C++ [expr.alignof]p3:
1272 // When alignof is applied to a reference type, the result is the
1273 // alignment of the referenced type.
1274 if (const auto *Ref = T->getAs<ReferenceType>())
1275 T = Ref->getPointeeType();
1276
1277 if (T.getQualifiers().hasUnaligned())
1278 return CharUnits::One();
1279
1280 // __alignof is defined to return the preferred alignment.
1281 // Before 8, clang returned the preferred alignment for alignof and
1282 // _Alignof as well.
1283 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
1284 return ASTCtx.toCharUnitsFromBits(ASTCtx.getPreferredTypeAlign(T));
1285
1286 return ASTCtx.getTypeAlignInChars(T);
1287}
1288
1289template <class Emitter>
1291 const UnaryExprOrTypeTraitExpr *E) {
1292 UnaryExprOrTypeTrait Kind = E->getKind();
1293 const ASTContext &ASTCtx = Ctx.getASTContext();
1294
1295 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
1296 QualType ArgType = E->getTypeOfArgument();
1297
1298 // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
1299 // the result is the size of the referenced type."
1300 if (const auto *Ref = ArgType->getAs<ReferenceType>())
1301 ArgType = Ref->getPointeeType();
1302
1303 CharUnits Size;
1304 if (ArgType->isVoidType() || ArgType->isFunctionType())
1305 Size = CharUnits::One();
1306 else {
1307 if (ArgType->isDependentType() || !ArgType->isConstantSizeType())
1308 return false;
1309
1310 if (Kind == UETT_SizeOf)
1311 Size = ASTCtx.getTypeSizeInChars(ArgType);
1312 else
1313 Size = ASTCtx.getTypeInfoDataSizeInChars(ArgType).Width;
1314 }
1315
1316 if (DiscardResult)
1317 return true;
1318
1319 return this->emitConst(Size.getQuantity(), E);
1320 }
1321
1322 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
1323 CharUnits Size;
1324
1325 if (E->isArgumentType()) {
1326 QualType ArgType = E->getTypeOfArgument();
1327
1328 Size = AlignOfType(ArgType, ASTCtx, Kind);
1329 } else {
1330 // Argument is an expression, not a type.
1331 const Expr *Arg = E->getArgumentExpr()->IgnoreParens();
1332
1333 // The kinds of expressions that we have special-case logic here for
1334 // should be kept up to date with the special checks for those
1335 // expressions in Sema.
1336
1337 // alignof decl is always accepted, even if it doesn't make sense: we
1338 // default to 1 in those cases.
1339 if (const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
1340 Size = ASTCtx.getDeclAlign(DRE->getDecl(),
1341 /*RefAsPointee*/ true);
1342 else if (const auto *ME = dyn_cast<MemberExpr>(Arg))
1343 Size = ASTCtx.getDeclAlign(ME->getMemberDecl(),
1344 /*RefAsPointee*/ true);
1345 else
1346 Size = AlignOfType(Arg->getType(), ASTCtx, Kind);
1347 }
1348
1349 if (DiscardResult)
1350 return true;
1351
1352 return this->emitConst(Size.getQuantity(), E);
1353 }
1354
1355 if (Kind == UETT_VectorElements) {
1356 if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>())
1357 return this->emitConst(VT->getNumElements(), E);
1358
1359 // FIXME: Apparently we need to catch the fact that a sizeless vector type
1360 // has been passed and diagnose that (at run time).
1362 }
1363
1364 if (Kind == UETT_VecStep) {
1365 if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>()) {
1366 unsigned N = VT->getNumElements();
1367
1368 // The vec_step built-in functions that take a 3-component
1369 // vector return 4. (OpenCL 1.1 spec 6.11.12)
1370 if (N == 3)
1371 N = 4;
1372
1373 return this->emitConst(N, E);
1374 }
1375 return this->emitConst(1, E);
1376 }
1377
1378 return false;
1379}
1380
1381template <class Emitter>
1383 // 'Base.Member'
1384 const Expr *Base = E->getBase();
1385 const ValueDecl *Member = E->getMemberDecl();
1386
1387 if (DiscardResult)
1388 return this->discard(Base);
1389
1390 // MemberExprs are almost always lvalues, in which case we don't need to
1391 // do the load. But sometimes they aren't.
1392 const auto maybeLoadValue = [&]() -> bool {
1393 if (E->isGLValue())
1394 return true;
1395 if (std::optional<PrimType> T = classify(E))
1396 return this->emitLoadPop(*T, E);
1397 return false;
1398 };
1399
1400 if (const auto *VD = dyn_cast<VarDecl>(Member)) {
1401 // I am almost confident in saying that a var decl must be static
1402 // and therefore registered as a global variable. But this will probably
1403 // turn out to be wrong some time in the future, as always.
1404 if (auto GlobalIndex = P.getGlobal(VD))
1405 return this->emitGetPtrGlobal(*GlobalIndex, E) && maybeLoadValue();
1406 return false;
1407 }
1408
1409 if (Initializing) {
1410 if (!this->delegate(Base))
1411 return false;
1412 } else {
1413 if (!this->visit(Base))
1414 return false;
1415 }
1416
1417 // Base above gives us a pointer on the stack.
1418 if (const auto *FD = dyn_cast<FieldDecl>(Member)) {
1419 const RecordDecl *RD = FD->getParent();
1420 const Record *R = getRecord(RD);
1421 if (!R)
1422 return false;
1423 const Record::Field *F = R->getField(FD);
1424 // Leave a pointer to the field on the stack.
1425 if (F->Decl->getType()->isReferenceType())
1426 return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue();
1427 return this->emitGetPtrField(F->Offset, E) && maybeLoadValue();
1428 }
1429
1430 return false;
1431}
1432
1433template <class Emitter>
1435 const ArrayInitIndexExpr *E) {
1436 // ArrayIndex might not be set if a ArrayInitIndexExpr is being evaluated
1437 // stand-alone, e.g. via EvaluateAsInt().
1438 if (!ArrayIndex)
1439 return false;
1440 return this->emitConst(*ArrayIndex, E);
1441}
1442
1443template <class Emitter>
1445 const ArrayInitLoopExpr *E) {
1446 assert(Initializing);
1447 assert(!DiscardResult);
1448
1449 // We visit the common opaque expression here once so we have its value
1450 // cached.
1451 if (!this->discard(E->getCommonExpr()))
1452 return false;
1453
1454 // TODO: This compiles to quite a lot of bytecode if the array is larger.
1455 // Investigate compiling this to a loop.
1456 const Expr *SubExpr = E->getSubExpr();
1457 size_t Size = E->getArraySize().getZExtValue();
1458
1459 // So, every iteration, we execute an assignment here
1460 // where the LHS is on the stack (the target array)
1461 // and the RHS is our SubExpr.
1462 for (size_t I = 0; I != Size; ++I) {
1463 ArrayIndexScope<Emitter> IndexScope(this, I);
1464 BlockScope<Emitter> BS(this);
1465
1466 if (!this->visitArrayElemInit(I, SubExpr))
1467 return false;
1468 }
1469 return true;
1470}
1471
1472template <class Emitter>
1474 const Expr *SourceExpr = E->getSourceExpr();
1475 if (!SourceExpr)
1476 return false;
1477
1478 if (Initializing)
1479 return this->visitInitializer(SourceExpr);
1480
1481 PrimType SubExprT = classify(SourceExpr).value_or(PT_Ptr);
1482 if (auto It = OpaqueExprs.find(E); It != OpaqueExprs.end())
1483 return this->emitGetLocal(SubExprT, It->second, E);
1484
1485 if (!this->visit(SourceExpr))
1486 return false;
1487
1488 // At this point we either have the evaluated source expression or a pointer
1489 // to an object on the stack. We want to create a local variable that stores
1490 // this value.
1491 unsigned LocalIndex = allocateLocalPrimitive(E, SubExprT, /*IsConst=*/true);
1492 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
1493 return false;
1494
1495 // Here the local variable is created but the value is removed from the stack,
1496 // so we put it back if the caller needs it.
1497 if (!DiscardResult) {
1498 if (!this->emitGetLocal(SubExprT, LocalIndex, E))
1499 return false;
1500 }
1501
1502 // This is cleaned up when the local variable is destroyed.
1503 OpaqueExprs.insert({E, LocalIndex});
1504
1505 return true;
1506}
1507
1508template <class Emitter>
1510 const AbstractConditionalOperator *E) {
1511 const Expr *Condition = E->getCond();
1512 const Expr *TrueExpr = E->getTrueExpr();
1513 const Expr *FalseExpr = E->getFalseExpr();
1514
1515 LabelTy LabelEnd = this->getLabel(); // Label after the operator.
1516 LabelTy LabelFalse = this->getLabel(); // Label for the false expr.
1517
1518 if (!this->visitBool(Condition))
1519 return false;
1520
1521 if (!this->jumpFalse(LabelFalse))
1522 return false;
1523
1524 if (!this->delegate(TrueExpr))
1525 return false;
1526 if (!this->jump(LabelEnd))
1527 return false;
1528
1529 this->emitLabel(LabelFalse);
1530
1531 if (!this->delegate(FalseExpr))
1532 return false;
1533
1534 this->fallthrough(LabelEnd);
1535 this->emitLabel(LabelEnd);
1536
1537 return true;
1538}
1539
1540template <class Emitter>
1542 if (DiscardResult)
1543 return true;
1544
1545 if (!Initializing) {
1546 unsigned StringIndex = P.createGlobalString(E);
1547 return this->emitGetPtrGlobal(StringIndex, E);
1548 }
1549
1550 // We are initializing an array on the stack.
1551 const ConstantArrayType *CAT =
1552 Ctx.getASTContext().getAsConstantArrayType(E->getType());
1553 assert(CAT && "a string literal that's not a constant array?");
1554
1555 // If the initializer string is too long, a diagnostic has already been
1556 // emitted. Read only the array length from the string literal.
1557 unsigned ArraySize = CAT->getZExtSize();
1558 unsigned N = std::min(ArraySize, E->getLength());
1559 size_t CharWidth = E->getCharByteWidth();
1560
1561 for (unsigned I = 0; I != N; ++I) {
1562 uint32_t CodeUnit = E->getCodeUnit(I);
1563
1564 if (CharWidth == 1) {
1565 this->emitConstSint8(CodeUnit, E);
1566 this->emitInitElemSint8(I, E);
1567 } else if (CharWidth == 2) {
1568 this->emitConstUint16(CodeUnit, E);
1569 this->emitInitElemUint16(I, E);
1570 } else if (CharWidth == 4) {
1571 this->emitConstUint32(CodeUnit, E);
1572 this->emitInitElemUint32(I, E);
1573 } else {
1574 llvm_unreachable("unsupported character width");
1575 }
1576 }
1577
1578 // Fill up the rest of the char array with NUL bytes.
1579 for (unsigned I = N; I != ArraySize; ++I) {
1580 if (CharWidth == 1) {
1581 this->emitConstSint8(0, E);
1582 this->emitInitElemSint8(I, E);
1583 } else if (CharWidth == 2) {
1584 this->emitConstUint16(0, E);
1585 this->emitInitElemUint16(I, E);
1586 } else if (CharWidth == 4) {
1587 this->emitConstUint32(0, E);
1588 this->emitInitElemUint32(I, E);
1589 } else {
1590 llvm_unreachable("unsupported character width");
1591 }
1592 }
1593
1594 return true;
1595}
1596
1597template <class Emitter>
1599 const CharacterLiteral *E) {
1600 if (DiscardResult)
1601 return true;
1602 return this->emitConst(E->getValue(), E);
1603}
1604
1605template <class Emitter>
1607 const CompoundAssignOperator *E) {
1608
1609 const Expr *LHS = E->getLHS();
1610 const Expr *RHS = E->getRHS();
1611 QualType LHSType = LHS->getType();
1612 QualType LHSComputationType = E->getComputationLHSType();
1613 QualType ResultType = E->getComputationResultType();
1614 std::optional<PrimType> LT = classify(LHSComputationType);
1615 std::optional<PrimType> RT = classify(ResultType);
1616
1617 assert(ResultType->isFloatingType());
1618
1619 if (!LT || !RT)
1620 return false;
1621
1622 PrimType LHST = classifyPrim(LHSType);
1623
1624 // C++17 onwards require that we evaluate the RHS first.
1625 // Compute RHS and save it in a temporary variable so we can
1626 // load it again later.
1627 if (!visit(RHS))
1628 return false;
1629
1630 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
1631 if (!this->emitSetLocal(*RT, TempOffset, E))
1632 return false;
1633
1634 // First, visit LHS.
1635 if (!visit(LHS))
1636 return false;
1637 if (!this->emitLoad(LHST, E))
1638 return false;
1639
1640 // If necessary, convert LHS to its computation type.
1641 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
1642 LHSComputationType, E))
1643 return false;
1644
1645 // Now load RHS.
1646 if (!this->emitGetLocal(*RT, TempOffset, E))
1647 return false;
1648
1649 llvm::RoundingMode RM = getRoundingMode(E);
1650 switch (E->getOpcode()) {
1651 case BO_AddAssign:
1652 if (!this->emitAddf(RM, E))
1653 return false;
1654 break;
1655 case BO_SubAssign:
1656 if (!this->emitSubf(RM, E))
1657 return false;
1658 break;
1659 case BO_MulAssign:
1660 if (!this->emitMulf(RM, E))
1661 return false;
1662 break;
1663 case BO_DivAssign:
1664 if (!this->emitDivf(RM, E))
1665 return false;
1666 break;
1667 default:
1668 return false;
1669 }
1670
1671 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->getType(), E))
1672 return false;
1673
1674 if (DiscardResult)
1675 return this->emitStorePop(LHST, E);
1676 return this->emitStore(LHST, E);
1677}
1678
1679template <class Emitter>
1681 const CompoundAssignOperator *E) {
1682 BinaryOperatorKind Op = E->getOpcode();
1683 const Expr *LHS = E->getLHS();
1684 const Expr *RHS = E->getRHS();
1685 std::optional<PrimType> LT = classify(LHS->getType());
1686 std::optional<PrimType> RT = classify(RHS->getType());
1687
1688 if (Op != BO_AddAssign && Op != BO_SubAssign)
1689 return false;
1690
1691 if (!LT || !RT)
1692 return false;
1693
1694 if (!visit(LHS))
1695 return false;
1696
1697 if (!this->emitLoad(*LT, LHS))
1698 return false;
1699
1700 if (!visit(RHS))
1701 return false;
1702
1703 if (Op == BO_AddAssign) {
1704 if (!this->emitAddOffset(*RT, E))
1705 return false;
1706 } else {
1707 if (!this->emitSubOffset(*RT, E))
1708 return false;
1709 }
1710
1711 if (DiscardResult)
1712 return this->emitStorePopPtr(E);
1713 return this->emitStorePtr(E);
1714}
1715
1716template <class Emitter>
1718 const CompoundAssignOperator *E) {
1719
1720 const Expr *LHS = E->getLHS();
1721 const Expr *RHS = E->getRHS();
1722 std::optional<PrimType> LHSComputationT =
1723 classify(E->getComputationLHSType());
1724 std::optional<PrimType> LT = classify(LHS->getType());
1725 std::optional<PrimType> RT = classify(RHS->getType());
1726 std::optional<PrimType> ResultT = classify(E->getType());
1727
1728 if (!LT || !RT || !ResultT || !LHSComputationT)
1729 return false;
1730
1731 // Handle floating point operations separately here, since they
1732 // require special care.
1733
1734 if (ResultT == PT_Float || RT == PT_Float)
1735 return VisitFloatCompoundAssignOperator(E);
1736
1737 if (E->getType()->isPointerType())
1738 return VisitPointerCompoundAssignOperator(E);
1739
1740 assert(!E->getType()->isPointerType() && "Handled above");
1741 assert(!E->getType()->isFloatingType() && "Handled above");
1742
1743 // C++17 onwards require that we evaluate the RHS first.
1744 // Compute RHS and save it in a temporary variable so we can
1745 // load it again later.
1746 // FIXME: Compound assignments are unsequenced in C, so we might
1747 // have to figure out how to reject them.
1748 if (!visit(RHS))
1749 return false;
1750
1751 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
1752
1753 if (!this->emitSetLocal(*RT, TempOffset, E))
1754 return false;
1755
1756 // Get LHS pointer, load its value and cast it to the
1757 // computation type if necessary.
1758 if (!visit(LHS))
1759 return false;
1760 if (!this->emitLoad(*LT, E))
1761 return false;
1762 if (LT != LHSComputationT) {
1763 if (!this->emitCast(*LT, *LHSComputationT, E))
1764 return false;
1765 }
1766
1767 // Get the RHS value on the stack.
1768 if (!this->emitGetLocal(*RT, TempOffset, E))
1769 return false;
1770
1771 // Perform operation.
1772 switch (E->getOpcode()) {
1773 case BO_AddAssign:
1774 if (!this->emitAdd(*LHSComputationT, E))
1775 return false;
1776 break;
1777 case BO_SubAssign:
1778 if (!this->emitSub(*LHSComputationT, E))
1779 return false;
1780 break;
1781 case BO_MulAssign:
1782 if (!this->emitMul(*LHSComputationT, E))
1783 return false;
1784 break;
1785 case BO_DivAssign:
1786 if (!this->emitDiv(*LHSComputationT, E))
1787 return false;
1788 break;
1789 case BO_RemAssign:
1790 if (!this->emitRem(*LHSComputationT, E))
1791 return false;
1792 break;
1793 case BO_ShlAssign:
1794 if (!this->emitShl(*LHSComputationT, *RT, E))
1795 return false;
1796 break;
1797 case BO_ShrAssign:
1798 if (!this->emitShr(*LHSComputationT, *RT, E))
1799 return false;
1800 break;
1801 case BO_AndAssign:
1802 if (!this->emitBitAnd(*LHSComputationT, E))
1803 return false;
1804 break;
1805 case BO_XorAssign:
1806 if (!this->emitBitXor(*LHSComputationT, E))
1807 return false;
1808 break;
1809 case BO_OrAssign:
1810 if (!this->emitBitOr(*LHSComputationT, E))
1811 return false;
1812 break;
1813 default:
1814 llvm_unreachable("Unimplemented compound assign operator");
1815 }
1816
1817 // And now cast from LHSComputationT to ResultT.
1818 if (ResultT != LHSComputationT) {
1819 if (!this->emitCast(*LHSComputationT, *ResultT, E))
1820 return false;
1821 }
1822
1823 // And store the result in LHS.
1824 if (DiscardResult) {
1825 if (LHS->refersToBitField())
1826 return this->emitStoreBitFieldPop(*ResultT, E);
1827 return this->emitStorePop(*ResultT, E);
1828 }
1829 if (LHS->refersToBitField())
1830 return this->emitStoreBitField(*ResultT, E);
1831 return this->emitStore(*ResultT, E);
1832}
1833
1834template <class Emitter>
1836 const ExprWithCleanups *E) {
1837 ExprScope<Emitter> ES(this);
1838 const Expr *SubExpr = E->getSubExpr();
1839
1840 assert(E->getNumObjects() == 0 && "TODO: Implement cleanups");
1841
1842 return this->delegate(SubExpr) && ES.destroyLocals();
1843}
1844
1845template <class Emitter>
1847 const MaterializeTemporaryExpr *E) {
1848 const Expr *SubExpr = E->getSubExpr();
1849
1850 if (Initializing) {
1851 // We already have a value, just initialize that.
1852 return this->visitInitializer(SubExpr);
1853 }
1854 // If we don't end up using the materialized temporary anyway, don't
1855 // bother creating it.
1856 if (DiscardResult)
1857 return this->discard(SubExpr);
1858
1859 // When we're initializing a global variable *or* the storage duration of
1860 // the temporary is explicitly static, create a global variable.
1861 std::optional<PrimType> SubExprT = classify(SubExpr);
1862 bool IsStatic = E->getStorageDuration() == SD_Static;
1863 if (GlobalDecl || IsStatic) {
1864 std::optional<unsigned> GlobalIndex = P.createGlobal(E);
1865 if (!GlobalIndex)
1866 return false;
1867
1868 const LifetimeExtendedTemporaryDecl *TempDecl =
1870 if (IsStatic)
1871 assert(TempDecl);
1872
1873 if (SubExprT) {
1874 if (!this->visit(SubExpr))
1875 return false;
1876 if (IsStatic) {
1877 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl, E))
1878 return false;
1879 } else {
1880 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex, E))
1881 return false;
1882 }
1883 return this->emitGetPtrGlobal(*GlobalIndex, E);
1884 }
1885
1886 // Non-primitive values.
1887 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1888 return false;
1889 if (!this->visitInitializer(SubExpr))
1890 return false;
1891 if (IsStatic)
1892 return this->emitInitGlobalTempComp(TempDecl, E);
1893 return true;
1894 }
1895
1896 // For everyhing else, use local variables.
1897 if (SubExprT) {
1898 unsigned LocalIndex = allocateLocalPrimitive(
1899 SubExpr, *SubExprT, /*IsConst=*/true, /*IsExtended=*/true);
1900 if (!this->visit(SubExpr))
1901 return false;
1902 if (!this->emitSetLocal(*SubExprT, LocalIndex, E))
1903 return false;
1904 return this->emitGetPtrLocal(LocalIndex, E);
1905 } else {
1906 const Expr *Inner = E->getSubExpr()->skipRValueSubobjectAdjustments();
1907 if (std::optional<unsigned> LocalIndex =
1908 allocateLocal(Inner, E->getExtendingDecl())) {
1909 if (!this->emitGetPtrLocal(*LocalIndex, E))
1910 return false;
1911 return this->visitInitializer(SubExpr);
1912 }
1913 }
1914 return false;
1915}
1916
1917template <class Emitter>
1919 const CXXBindTemporaryExpr *E) {
1920 return this->delegate(E->getSubExpr());
1921}
1922
1923template <class Emitter>
1925 const CompoundLiteralExpr *E) {
1926 const Expr *Init = E->getInitializer();
1927 if (Initializing) {
1928 // We already have a value, just initialize that.
1929 return this->visitInitializer(Init) && this->emitFinishInit(E);
1930 }
1931
1932 std::optional<PrimType> T = classify(E->getType());
1933 if (E->isFileScope()) {
1934 // Avoid creating a variable if this is a primitive RValue anyway.
1935 if (T && !E->isLValue())
1936 return this->delegate(Init);
1937
1938 if (std::optional<unsigned> GlobalIndex = P.createGlobal(E)) {
1939 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1940 return false;
1941
1942 if (T) {
1943 if (!this->visit(Init))
1944 return false;
1945 return this->emitInitGlobal(*T, *GlobalIndex, E);
1946 }
1947
1948 return this->visitInitializer(Init) && this->emitFinishInit(E);
1949 }
1950
1951 return false;
1952 }
1953
1954 // Otherwise, use a local variable.
1955 if (T && !E->isLValue()) {
1956 // For primitive types, we just visit the initializer.
1957 return this->delegate(Init);
1958 } else {
1959 unsigned LocalIndex;
1960
1961 if (T)
1962 LocalIndex = this->allocateLocalPrimitive(Init, *T, false, false);
1963 else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(Init))
1964 LocalIndex = *MaybeIndex;
1965 else
1966 return false;
1967
1968 if (!this->emitGetPtrLocal(LocalIndex, E))
1969 return false;
1970
1971 if (T) {
1972 if (!this->visit(Init)) {
1973 return false;
1974 }
1975 return this->emitInit(*T, E);
1976 } else {
1977 if (!this->visitInitializer(Init) || !this->emitFinishInit(E))
1978 return false;
1979 }
1980
1981 if (DiscardResult)
1982 return this->emitPopPtr(E);
1983 return true;
1984 }
1985
1986 return false;
1987}
1988
1989template <class Emitter>
1991 if (DiscardResult)
1992 return true;
1993 if (E->getType()->isBooleanType())
1994 return this->emitConstBool(E->getValue(), E);
1995 return this->emitConst(E->getValue(), E);
1996}
1997
1998template <class Emitter>
2000 const ArrayTypeTraitExpr *E) {
2001 if (DiscardResult)
2002 return true;
2003 return this->emitConst(E->getValue(), E);
2004}
2005
2006template <class Emitter>
2008 if (DiscardResult)
2009 return true;
2010
2011 assert(Initializing);
2012 const Record *R = P.getOrCreateRecord(E->getLambdaClass());
2013
2014 auto *CaptureInitIt = E->capture_init_begin();
2015 // Initialize all fields (which represent lambda captures) of the
2016 // record with their initializers.
2017 for (const Record::Field &F : R->fields()) {
2018 const Expr *Init = *CaptureInitIt;
2019 ++CaptureInitIt;
2020
2021 if (!Init)
2022 continue;
2023
2024 if (std::optional<PrimType> T = classify(Init)) {
2025 if (!this->visit(Init))
2026 return false;
2027
2028 if (!this->emitInitField(*T, F.Offset, E))
2029 return false;
2030 } else {
2031 if (!this->emitDupPtr(E))
2032 return false;
2033
2034 if (!this->emitGetPtrField(F.Offset, E))
2035 return false;
2036
2037 if (!this->visitInitializer(Init))
2038 return false;
2039
2040 if (!this->emitPopPtr(E))
2041 return false;
2042 }
2043 }
2044
2045 return true;
2046}
2047
2048template <class Emitter>
2050 if (DiscardResult)
2051 return true;
2052
2053 return this->delegate(E->getFunctionName());
2054}
2055
2056template <class Emitter>
2058 if (E->getSubExpr() && !this->discard(E->getSubExpr()))
2059 return false;
2060
2061 return this->emitInvalid(E);
2062}
2063
2064template <class Emitter>
2066 const CXXReinterpretCastExpr *E) {
2067 if (!this->discard(E->getSubExpr()))
2068 return false;
2069
2070 return this->emitInvalidCast(CastKind::Reinterpret, E);
2071}
2072
2073template <class Emitter>
2075 assert(E->getType()->isBooleanType());
2076
2077 if (DiscardResult)
2078 return true;
2079 return this->emitConstBool(E->getValue(), E);
2080}
2081
2082template <class Emitter>
2084 const CXXConstructExpr *E) {
2085 QualType T = E->getType();
2086 assert(!classify(T));
2087
2088 if (T->isRecordType()) {
2089 const CXXConstructorDecl *Ctor = E->getConstructor();
2090
2091 // Zero initialization.
2092 if (E->requiresZeroInitialization()) {
2093 const Record *R = getRecord(E->getType());
2094
2095 if (!this->visitZeroRecordInitializer(R, E))
2096 return false;
2097
2098 // If the constructor is trivial anyway, we're done.
2099 if (Ctor->isTrivial())
2100 return true;
2101 }
2102
2103 const Function *Func = getFunction(Ctor);
2104
2105 if (!Func)
2106 return false;
2107
2108 assert(Func->hasThisPointer());
2109 assert(!Func->hasRVO());
2110
2111 // If we're discarding a construct expression, we still need
2112 // to allocate a variable and call the constructor and destructor.
2113 if (DiscardResult) {
2114 assert(!Initializing);
2115 std::optional<unsigned> LocalIndex = allocateLocal(E);
2116
2117 if (!LocalIndex)
2118 return false;
2119
2120 if (!this->emitGetPtrLocal(*LocalIndex, E))
2121 return false;
2122 }
2123
2124 // The This pointer is already on the stack because this is an initializer,
2125 // but we need to dup() so the call() below has its own copy.
2126 if (!this->emitDupPtr(E))
2127 return false;
2128
2129 // Constructor arguments.
2130 for (const auto *Arg : E->arguments()) {
2131 if (!this->visit(Arg))
2132 return false;
2133 }
2134
2135 if (Func->isVariadic()) {
2136 uint32_t VarArgSize = 0;
2137 unsigned NumParams = Func->getNumWrittenParams();
2138 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I) {
2139 VarArgSize +=
2140 align(primSize(classify(E->getArg(I)->getType()).value_or(PT_Ptr)));
2141 }
2142 if (!this->emitCallVar(Func, VarArgSize, E))
2143 return false;
2144 } else {
2145 if (!this->emitCall(Func, 0, E))
2146 return false;
2147 }
2148
2149 // Immediately call the destructor if we have to.
2150 if (DiscardResult) {
2151 if (!this->emitRecordDestruction(getRecord(E->getType())))
2152 return false;
2153 if (!this->emitPopPtr(E))
2154 return false;
2155 }
2156 return true;
2157 }
2158
2159 if (T->isArrayType()) {
2160 const ConstantArrayType *CAT =
2161 Ctx.getASTContext().getAsConstantArrayType(E->getType());
2162 if (!CAT)
2163 return false;
2164
2165 size_t NumElems = CAT->getZExtSize();
2166 const Function *Func = getFunction(E->getConstructor());
2167 if (!Func || !Func->isConstexpr())
2168 return false;
2169
2170 // FIXME(perf): We're calling the constructor once per array element here,
2171 // in the old intepreter we had a special-case for trivial constructors.
2172 for (size_t I = 0; I != NumElems; ++I) {
2173 if (!this->emitConstUint64(I, E))
2174 return false;
2175 if (!this->emitArrayElemPtrUint64(E))
2176 return false;
2177
2178 // Constructor arguments.
2179 for (const auto *Arg : E->arguments()) {
2180 if (!this->visit(Arg))
2181 return false;
2182 }
2183
2184 if (!this->emitCall(Func, 0, E))
2185 return false;
2186 }
2187 return true;
2188 }
2189
2190 return false;
2191}
2192
2193template <class Emitter>
2195 if (DiscardResult)
2196 return true;
2197
2198 const APValue Val =
2199 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
2200
2201 // Things like __builtin_LINE().
2202 if (E->getType()->isIntegerType()) {
2203 assert(Val.isInt());
2204 const APSInt &I = Val.getInt();
2205 return this->emitConst(I, E);
2206 }
2207 // Otherwise, the APValue is an LValue, with only one element.
2208 // Theoretically, we don't need the APValue at all of course.
2209 assert(E->getType()->isPointerType());
2210 assert(Val.isLValue());
2211 const APValue::LValueBase &Base = Val.getLValueBase();
2212 if (const Expr *LValueExpr = Base.dyn_cast<const Expr *>())
2213 return this->visit(LValueExpr);
2214
2215 // Otherwise, we have a decl (which is the case for
2216 // __builtin_source_location).
2217 assert(Base.is<const ValueDecl *>());
2218 assert(Val.getLValuePath().size() == 0);
2219 const auto *BaseDecl = Base.dyn_cast<const ValueDecl *>();
2220 assert(BaseDecl);
2221
2222 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
2223
2224 std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(UGCD);
2225 if (!GlobalIndex)
2226 return false;
2227
2228 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2229 return false;
2230
2231 const Record *R = getRecord(E->getType());
2232 const APValue &V = UGCD->getValue();
2233 for (unsigned I = 0, N = R->getNumFields(); I != N; ++I) {
2234 const Record::Field *F = R->getField(I);
2235 const APValue &FieldValue = V.getStructField(I);
2236
2237 PrimType FieldT = classifyPrim(F->Decl->getType());
2238
2239 if (!this->visitAPValue(FieldValue, FieldT, E))
2240 return false;
2241 if (!this->emitInitField(FieldT, F->Offset, E))
2242 return false;
2243 }
2244
2245 // Leave the pointer to the global on the stack.
2246 return true;
2247}
2248
2249template <class Emitter>
2251 unsigned N = E->getNumComponents();
2252 if (N == 0)
2253 return false;
2254
2255 for (unsigned I = 0; I != N; ++I) {
2256 const OffsetOfNode &Node = E->getComponent(I);
2257 if (Node.getKind() == OffsetOfNode::Array) {
2258 const Expr *ArrayIndexExpr = E->getIndexExpr(Node.getArrayExprIndex());
2259 PrimType IndexT = classifyPrim(ArrayIndexExpr->getType());
2260
2261 if (DiscardResult) {
2262 if (!this->discard(ArrayIndexExpr))
2263 return false;
2264 continue;
2265 }
2266
2267 if (!this->visit(ArrayIndexExpr))
2268 return false;
2269 // Cast to Sint64.
2270 if (IndexT != PT_Sint64) {
2271 if (!this->emitCast(IndexT, PT_Sint64, E))
2272 return false;
2273 }
2274 }
2275 }
2276
2277 if (DiscardResult)
2278 return true;
2279
2280 PrimType T = classifyPrim(E->getType());
2281 return this->emitOffsetOf(T, E, E);
2282}
2283
2284template <class Emitter>
2286 const CXXScalarValueInitExpr *E) {
2287 QualType Ty = E->getType();
2288
2289 if (DiscardResult || Ty->isVoidType())
2290 return true;
2291
2292 if (std::optional<PrimType> T = classify(Ty))
2293 return this->visitZeroInitializer(*T, Ty, E);
2294
2295 if (const auto *CT = Ty->getAs<ComplexType>()) {
2296 if (!Initializing) {
2297 std::optional<unsigned> LocalIndex = allocateLocal(E);
2298 if (!LocalIndex)
2299 return false;
2300 if (!this->emitGetPtrLocal(*LocalIndex, E))
2301 return false;
2302 }
2303
2304 // Initialize both fields to 0.
2305 QualType ElemQT = CT->getElementType();
2306 PrimType ElemT = classifyPrim(ElemQT);
2307
2308 for (unsigned I = 0; I != 2; ++I) {
2309 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2310 return false;
2311 if (!this->emitInitElem(ElemT, I, E))
2312 return false;
2313 }
2314 return true;
2315 }
2316
2317 if (const auto *VT = Ty->getAs<VectorType>()) {
2318 // FIXME: Code duplication with the _Complex case above.
2319 if (!Initializing) {
2320 std::optional<unsigned> LocalIndex = allocateLocal(E);
2321 if (!LocalIndex)
2322 return false;
2323 if (!this->emitGetPtrLocal(*LocalIndex, E))
2324 return false;
2325 }
2326
2327 // Initialize all fields to 0.
2328 QualType ElemQT = VT->getElementType();
2329 PrimType ElemT = classifyPrim(ElemQT);
2330
2331 for (unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
2332 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2333 return false;
2334 if (!this->emitInitElem(ElemT, I, E))
2335 return false;
2336 }
2337 return true;
2338 }
2339
2340 return false;
2341}
2342
2343template <class Emitter>
2345 return this->emitConst(E->getPackLength(), E);
2346}
2347
2348template <class Emitter>
2350 const GenericSelectionExpr *E) {
2351 return this->delegate(E->getResultExpr());
2352}
2353
2354template <class Emitter>
2356 return this->delegate(E->getChosenSubExpr());
2357}
2358
2359template <class Emitter>
2361 const ObjCBoolLiteralExpr *E) {
2362 if (DiscardResult)
2363 return true;
2364
2365 return this->emitConst(E->getValue(), E);
2366}
2367
2368template <class Emitter>
2370 const CXXInheritedCtorInitExpr *E) {
2371 const CXXConstructorDecl *Ctor = E->getConstructor();
2372 assert(!Ctor->isTrivial() &&
2373 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
2374 const Function *F = this->getFunction(Ctor);
2375 assert(F);
2376 assert(!F->hasRVO());
2377 assert(F->hasThisPointer());
2378
2379 if (!this->emitDupPtr(SourceInfo{}))
2380 return false;
2381
2382 // Forward all arguments of the current function (which should be a
2383 // constructor itself) to the inherited ctor.
2384 // This is necessary because the calling code has pushed the pointer
2385 // of the correct base for us already, but the arguments need
2386 // to come after.
2387 unsigned Offset = align(primSize(PT_Ptr)); // instance pointer.
2388 for (const ParmVarDecl *PD : Ctor->parameters()) {
2389 PrimType PT = this->classify(PD->getType()).value_or(PT_Ptr);
2390
2391 if (!this->emitGetParam(PT, Offset, E))
2392 return false;
2393 Offset += align(primSize(PT));
2394 }
2395
2396 return this->emitCall(F, 0, E);
2397}
2398
2399template <class Emitter>
2401 const ExpressionTraitExpr *E) {
2402 assert(Ctx.getLangOpts().CPlusPlus);
2403 return this->emitConstBool(E->getValue(), E);
2404}
2405
2406template <class Emitter>
2408 if (DiscardResult)
2409 return true;
2410 assert(!Initializing);
2411
2412 std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(E->getGuidDecl());
2413 if (!GlobalIndex)
2414 return false;
2415 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2416 return false;
2417
2418 assert(this->getRecord(E->getType()));
2419
2420 const APValue &V = E->getGuidDecl()->getAsAPValue();
2421 if (V.getKind() == APValue::None)
2422 return true;
2423
2424 assert(V.isStruct());
2425 assert(V.getStructNumBases() == 0);
2426 if (!this->visitAPValueInitializer(V, E))
2427 return false;
2428
2429 return this->emitFinishInit(E);
2430}
2431
2432template <class Emitter>
2434 assert(classifyPrim(E->getType()) == PT_Bool);
2435 if (DiscardResult)
2436 return true;
2437 return this->emitConstBool(E->isSatisfied(), E);
2438}
2439
2440template <class Emitter>
2442 const ConceptSpecializationExpr *E) {
2443 assert(classifyPrim(E->getType()) == PT_Bool);
2444 if (DiscardResult)
2445 return true;
2446 return this->emitConstBool(E->isSatisfied(), E);
2447}
2448
2449template <class Emitter>
2451 const CXXRewrittenBinaryOperator *E) {
2452 return this->delegate(E->getSemanticForm());
2453}
2454
2455template <class Emitter>
2457 const PseudoObjectExpr *E) {
2458
2459 for (const Expr *SemE : E->semantics()) {
2460 if (auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
2461 if (SemE == E->getResultExpr())
2462 return false;
2463
2464 if (OVE->isUnique())
2465 continue;
2466
2467 if (!this->discard(OVE))
2468 return false;
2469 } else if (SemE == E->getResultExpr()) {
2470 if (!this->delegate(SemE))
2471 return false;
2472 } else {
2473 if (!this->discard(SemE))
2474 return false;
2475 }
2476 }
2477 return true;
2478}
2479
2480template <class Emitter>
2482 const PackIndexingExpr *E) {
2483 return this->delegate(E->getSelectedExpr());
2484}
2485
2486template <class Emitter>
2488 return this->emitError(E);
2489}
2490
2491template <class Emitter>
2493 assert(E->getType()->isVoidPointerType());
2494
2495 unsigned Offset = allocateLocalPrimitive(
2496 E->getLabel(), PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false);
2497
2498 return this->emitGetLocal(PT_Ptr, Offset, E);
2499}
2500
2501template <class Emitter>
2503 const ConvertVectorExpr *E) {
2504 assert(Initializing);
2505 const auto *VT = E->getType()->castAs<VectorType>();
2506 QualType ElemType = VT->getElementType();
2507 PrimType ElemT = classifyPrim(ElemType);
2508 const Expr *Src = E->getSrcExpr();
2509 PrimType SrcElemT =
2510 classifyPrim(Src->getType()->castAs<VectorType>()->getElementType());
2511
2512 unsigned SrcOffset = this->allocateLocalPrimitive(Src, PT_Ptr, true, false);
2513 if (!this->visit(Src))
2514 return false;
2515 if (!this->emitSetLocal(PT_Ptr, SrcOffset, E))
2516 return false;
2517
2518 for (unsigned I = 0; I != VT->getNumElements(); ++I) {
2519 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
2520 return false;
2521 if (!this->emitArrayElemPop(SrcElemT, I, E))
2522 return false;
2523 if (SrcElemT != ElemT) {
2524 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
2525 return false;
2526 }
2527 if (!this->emitInitElem(ElemT, I, E))
2528 return false;
2529 }
2530
2531 return true;
2532}
2533
2534template <class Emitter>
2536 const ShuffleVectorExpr *E) {
2537 assert(Initializing);
2538 assert(E->getNumSubExprs() > 2);
2539
2540 const Expr *Vecs[] = {E->getExpr(0), E->getExpr(1)};
2541 assert(Vecs[0]->getType() == Vecs[1]->getType());
2542
2543 const VectorType *VT = Vecs[0]->getType()->castAs<VectorType>();
2544 PrimType ElemT = classifyPrim(VT->getElementType());
2545 unsigned NumInputElems = VT->getNumElements();
2546 unsigned NumOutputElems = E->getNumSubExprs() - 2;
2547 assert(NumOutputElems > 0);
2548
2549 // Save both input vectors to a local variable.
2550 unsigned VectorOffsets[2];
2551 for (unsigned I = 0; I != 2; ++I) {
2552 VectorOffsets[I] = this->allocateLocalPrimitive(
2553 Vecs[I], PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false);
2554 if (!this->visit(Vecs[I]))
2555 return false;
2556 if (!this->emitSetLocal(PT_Ptr, VectorOffsets[I], E))
2557 return false;
2558 }
2559 for (unsigned I = 0; I != NumOutputElems; ++I) {
2560 APSInt ShuffleIndex = E->getShuffleMaskIdx(Ctx.getASTContext(), I);
2561 if (ShuffleIndex == -1)
2562 return this->emitInvalid(E); // FIXME: Better diagnostic.
2563
2564 assert(ShuffleIndex < (NumInputElems * 2));
2565 if (!this->emitGetLocal(PT_Ptr,
2566 VectorOffsets[ShuffleIndex >= NumInputElems], E))
2567 return false;
2568 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
2569 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
2570 return false;
2571
2572 if (!this->emitInitElem(ElemT, I, E))
2573 return false;
2574 }
2575
2576 return true;
2577}
2578
2579template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) {
2580 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
2581 /*NewInitializing=*/false);
2582 return this->Visit(E);
2583}
2584
2585template <class Emitter>
2587 // We're basically doing:
2588 // OptionScope<Emitter> Scope(this, DicardResult, Initializing);
2589 // but that's unnecessary of course.
2590 return this->Visit(E);
2591}
2592
2593template <class Emitter> bool ByteCodeExprGen<Emitter>::visit(const Expr *E) {
2594 if (E->getType()->isVoidType())
2595 return this->discard(E);
2596
2597 // Create local variable to hold the return value.
2598 if (!E->isGLValue() && !E->getType()->isAnyComplexType() &&
2599 !classify(E->getType())) {
2600 std::optional<unsigned> LocalIndex = allocateLocal(E);
2601 if (!LocalIndex)
2602 return false;
2603
2604 if (!this->emitGetPtrLocal(*LocalIndex, E))
2605 return false;
2606 return this->visitInitializer(E);
2607 }
2608
2609 // Otherwise,we have a primitive return value, produce the value directly
2610 // and push it on the stack.
2611 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
2612 /*NewInitializing=*/false);
2613 return this->Visit(E);
2614}
2615
2616template <class Emitter>
2618 assert(!classify(E->getType()));
2619
2620 if (E->containsErrors())
2621 return this->emitError(E);
2622
2623 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
2624 /*NewInitializing=*/true);
2625 return this->Visit(E);
2626}
2627
2628template <class Emitter>
2630 std::optional<PrimType> T = classify(E->getType());
2631 if (!T) {
2632 // Convert complex values to bool.
2633 if (E->getType()->isAnyComplexType()) {
2634 if (!this->visit(E))
2635 return false;
2636 return this->emitComplexBoolCast(E);
2637 }
2638 return false;
2639 }
2640
2641 if (!this->visit(E))
2642 return false;
2643
2644 if (T == PT_Bool)
2645 return true;
2646
2647 // Convert pointers to bool.
2648 if (T == PT_Ptr || T == PT_FnPtr) {
2649 if (!this->emitNull(*T, nullptr, E))
2650 return false;
2651 return this->emitNE(*T, E);
2652 }
2653
2654 // Or Floats.
2655 if (T == PT_Float)
2656 return this->emitCastFloatingIntegralBool(E);
2657
2658 // Or anything else we can.
2659 return this->emitCast(*T, PT_Bool, E);
2660}
2661
2662template <class Emitter>
2664 const Expr *E) {
2665 switch (T) {
2666 case PT_Bool:
2667 return this->emitZeroBool(E);
2668 case PT_Sint8:
2669 return this->emitZeroSint8(E);
2670 case PT_Uint8:
2671 return this->emitZeroUint8(E);
2672 case PT_Sint16:
2673 return this->emitZeroSint16(E);
2674 case PT_Uint16:
2675 return this->emitZeroUint16(E);
2676 case PT_Sint32:
2677 return this->emitZeroSint32(E);
2678 case PT_Uint32:
2679 return this->emitZeroUint32(E);
2680 case PT_Sint64:
2681 return this->emitZeroSint64(E);
2682 case PT_Uint64:
2683 return this->emitZeroUint64(E);
2684 case PT_IntAP:
2685 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
2686 case PT_IntAPS:
2687 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
2688 case PT_Ptr:
2689 return this->emitNullPtr(nullptr, E);
2690 case PT_FnPtr:
2691 return this->emitNullFnPtr(nullptr, E);
2692 case PT_Float: {
2693 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E);
2694 }
2695 }
2696 llvm_unreachable("unknown primitive type");
2697}
2698
2699template <class Emitter>
2701 const Expr *E) {
2702 assert(E);
2703 assert(R);
2704 // Fields
2705 for (const Record::Field &Field : R->fields()) {
2706 const Descriptor *D = Field.Desc;
2707 if (D->isPrimitive()) {
2708 QualType QT = D->getType();
2709 PrimType T = classifyPrim(D->getType());
2710 if (!this->visitZeroInitializer(T, QT, E))
2711 return false;
2712 if (!this->emitInitField(T, Field.Offset, E))
2713 return false;
2714 continue;
2715 }
2716
2717 // TODO: Add GetPtrFieldPop and get rid of this dup.
2718 if (!this->emitDupPtr(E))
2719 return false;
2720 if (!this->emitGetPtrField(Field.Offset, E))
2721 return false;
2722
2723 if (D->isPrimitiveArray()) {
2724 QualType ET = D->getElemQualType();
2725 PrimType T = classifyPrim(ET);
2726 for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
2727 if (!this->visitZeroInitializer(T, ET, E))
2728 return false;
2729 if (!this->emitInitElem(T, I, E))
2730 return false;
2731 }
2732 } else if (D->isCompositeArray()) {
2733 const Record *ElemRecord = D->ElemDesc->ElemRecord;
2734 assert(D->ElemDesc->ElemRecord);
2735 for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
2736 if (!this->emitConstUint32(I, E))
2737 return false;
2738 if (!this->emitArrayElemPtr(PT_Uint32, E))
2739 return false;
2740 if (!this->visitZeroRecordInitializer(ElemRecord, E))
2741 return false;
2742 if (!this->emitPopPtr(E))
2743 return false;
2744 }
2745 } else if (D->isRecord()) {
2746 if (!this->visitZeroRecordInitializer(D->ElemRecord, E))
2747 return false;
2748 } else {
2749 assert(false);
2750 }
2751
2752 if (!this->emitPopPtr(E))
2753 return false;
2754 }
2755
2756 for (const Record::Base &B : R->bases()) {
2757 if (!this->emitGetPtrBase(B.Offset, E))
2758 return false;
2759 if (!this->visitZeroRecordInitializer(B.R, E))
2760 return false;
2761 if (!this->emitFinishInitPop(E))
2762 return false;
2763 }
2764
2765 // FIXME: Virtual bases.
2766
2767 return true;
2768}
2769
2770template <class Emitter>
2771template <typename T>
2773 switch (Ty) {
2774 case PT_Sint8:
2775 return this->emitConstSint8(Value, E);
2776 case PT_Uint8:
2777 return this->emitConstUint8(Value, E);
2778 case PT_Sint16:
2779 return this->emitConstSint16(Value, E);
2780 case PT_Uint16:
2781 return this->emitConstUint16(Value, E);
2782 case PT_Sint32:
2783 return this->emitConstSint32(Value, E);
2784 case PT_Uint32:
2785 return this->emitConstUint32(Value, E);
2786 case PT_Sint64:
2787 return this->emitConstSint64(Value, E);
2788 case PT_Uint64:
2789 return this->emitConstUint64(Value, E);
2790 case PT_Bool:
2791 return this->emitConstBool(Value, E);
2792 case PT_Ptr:
2793 case PT_FnPtr:
2794 case PT_Float:
2795 case PT_IntAP:
2796 case PT_IntAPS:
2797 llvm_unreachable("Invalid integral type");
2798 break;
2799 }
2800 llvm_unreachable("unknown primitive type");
2801}
2802
2803template <class Emitter>
2804template <typename T>
2806 return this->emitConst(Value, classifyPrim(E->getType()), E);
2807}
2808
2809template <class Emitter>
2811 const Expr *E) {
2812 if (Ty == PT_IntAPS)
2813 return this->emitConstIntAPS(Value, E);
2814 if (Ty == PT_IntAP)
2815 return this->emitConstIntAP(Value, E);
2816
2817 if (Value.isSigned())
2818 return this->emitConst(Value.getSExtValue(), Ty, E);
2819 return this->emitConst(Value.getZExtValue(), Ty, E);
2820}
2821
2822template <class Emitter>
2824 return this->emitConst(Value, classifyPrim(E->getType()), E);
2825}
2826
2827template <class Emitter>
2829 PrimType Ty,
2830 bool IsConst,
2831 bool IsExtended) {
2832 // Make sure we don't accidentally register the same decl twice.
2833 if (const auto *VD =
2834 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
2835 assert(!P.getGlobal(VD));
2836 assert(!Locals.contains(VD));
2837 (void)VD;
2838 }
2839
2840 // FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
2841 // (int){12} in C. Consider using Expr::isTemporaryObject() instead
2842 // or isa<MaterializeTemporaryExpr>().
2843 Descriptor *D = P.createDescriptor(Src, Ty, Descriptor::InlineDescMD, IsConst,
2844 Src.is<const Expr *>());
2845 Scope::Local Local = this->createLocal(D);
2846 if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>()))
2847 Locals.insert({VD, Local});
2848 VarScope->add(Local, IsExtended);
2849 return Local.Offset;
2850}
2851
2852template <class Emitter>
2853std::optional<unsigned>
2855 const ValueDecl *ExtendingDecl) {
2856 // Make sure we don't accidentally register the same decl twice.
2857 if ([[maybe_unused]] const auto *VD =
2858 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
2859 assert(!P.getGlobal(VD));
2860 assert(!Locals.contains(VD));
2861 }
2862
2863 QualType Ty;
2864 const ValueDecl *Key = nullptr;
2865 const Expr *Init = nullptr;
2866 bool IsTemporary = false;
2867 if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
2868 Key = VD;
2869 Ty = VD->getType();
2870
2871 if (const auto *VarD = dyn_cast<VarDecl>(VD))
2872 Init = VarD->getInit();
2873 }
2874 if (auto *E = Src.dyn_cast<const Expr *>()) {
2875 IsTemporary = true;
2876 Ty = E->getType();
2877 }
2878
2879 Descriptor *D = P.createDescriptor(
2881 IsTemporary, /*IsMutable=*/false, Init);
2882 if (!D)
2883 return std::nullopt;
2884
2885 Scope::Local Local = this->createLocal(D);
2886 if (Key)
2887 Locals.insert({Key, Local});
2888 if (ExtendingDecl)
2889 VarScope->addExtended(Local, ExtendingDecl);
2890 else
2891 VarScope->add(Local, false);
2892 return Local.Offset;
2893}
2894
2895template <class Emitter>
2897 if (const PointerType *PT = dyn_cast<PointerType>(Ty))
2898 return PT->getPointeeType()->getAs<RecordType>();
2899 return Ty->getAs<RecordType>();
2900}
2901
2902template <class Emitter>
2904 if (const auto *RecordTy = getRecordTy(Ty))
2905 return getRecord(RecordTy->getDecl());
2906 return nullptr;
2907}
2908
2909template <class Emitter>
2911 return P.getOrCreateRecord(RD);
2912}
2913
2914template <class Emitter>
2916 return Ctx.getOrCreateFunction(FD);
2917}
2918
2919template <class Emitter>
2921 ExprScope<Emitter> RootScope(this);
2922 // Void expressions.
2923 if (E->getType()->isVoidType()) {
2924 if (!visit(E))
2925 return false;
2926 return this->emitRetVoid(E) && RootScope.destroyLocals();
2927 }
2928
2929 // Expressions with a primitive return type.
2930 if (std::optional<PrimType> T = classify(E)) {
2931 if (!visit(E))
2932 return false;
2933 return this->emitRet(*T, E) && RootScope.destroyLocals();
2934 }
2935
2936 // Expressions with a composite return type.
2937 // For us, that means everything we don't
2938 // have a PrimType for.
2939 if (std::optional<unsigned> LocalOffset = this->allocateLocal(E)) {
2940 if (!this->emitGetPtrLocal(*LocalOffset, E))
2941 return false;
2942
2943 if (!visitInitializer(E))
2944 return false;
2945
2946 if (!this->emitFinishInit(E))
2947 return false;
2948 // We are destroying the locals AFTER the Ret op.
2949 // The Ret op needs to copy the (alive) values, but the
2950 // destructors may still turn the entire expression invalid.
2951 return this->emitRetValue(E) && RootScope.destroyLocals();
2952 }
2953
2954 RootScope.destroyLocals();
2955 return false;
2956}
2957
2958/// Toplevel visitDecl().
2959/// We get here from evaluateAsInitializer().
2960/// We need to evaluate the initializer and return its value.
2961template <class Emitter>
2963 assert(!VD->isInvalidDecl() && "Trying to constant evaluate an invalid decl");
2964
2965 // Global variable we've already seen but that's uninitialized means
2966 // evaluating the initializer failed. Just return failure.
2967 if (std::optional<unsigned> Index = P.getGlobal(VD);
2968 Index && !P.getPtrGlobal(*Index).isInitialized())
2969 return false;
2970
2971 // Create and initialize the variable.
2972 if (!this->visitVarDecl(VD))
2973 return false;
2974
2975 std::optional<PrimType> VarT = classify(VD->getType());
2976 // Get a pointer to the variable
2978 auto GlobalIndex = P.getGlobal(VD);
2979 assert(GlobalIndex); // visitVarDecl() didn't return false.
2980 if (VarT) {
2981 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
2982 return false;
2983 } else {
2984 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
2985 return false;
2986 }
2987 } else {
2988 auto Local = Locals.find(VD);
2989 assert(Local != Locals.end()); // Same here.
2990 if (VarT) {
2991 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
2992 return false;
2993 } else {
2994 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
2995 return false;
2996 }
2997 }
2998
2999 // Return the value
3000 if (VarT)
3001 return this->emitRet(*VarT, VD);
3002
3003 // Return non-primitive values as pointers here.
3004 return this->emitRet(PT_Ptr, VD);
3005}
3006
3007template <class Emitter>
3009 // We don't know what to do with these, so just return false.
3010 if (VD->getType().isNull())
3011 return false;
3012
3013 const Expr *Init = VD->getInit();
3014 std::optional<PrimType> VarT = classify(VD->getType());
3015
3017 auto initGlobal = [&](unsigned GlobalIndex) -> bool {
3018 assert(Init);
3020
3021 if (VarT) {
3022 if (!this->visit(Init))
3023 return false;
3024 return this->emitInitGlobal(*VarT, GlobalIndex, VD);
3025 }
3026 return this->visitGlobalInitializer(Init, GlobalIndex);
3027 };
3028
3029 // We've already seen and initialized this global.
3030 if (std::optional<unsigned> GlobalIndex = P.getGlobal(VD)) {
3031 if (P.getPtrGlobal(*GlobalIndex).isInitialized())
3032 return true;
3033
3034 // The previous attempt at initialization might've been unsuccessful,
3035 // so let's try this one.
3036 return Init && initGlobal(*GlobalIndex);
3037 }
3038
3039 std::optional<unsigned> GlobalIndex = P.createGlobal(VD, Init);
3040
3041 if (!GlobalIndex)
3042 return false;
3043
3044 return !Init || initGlobal(*GlobalIndex);
3045 } else {
3047 if (VarT) {
3048 unsigned Offset = this->allocateLocalPrimitive(
3049 VD, *VarT, VD->getType().isConstQualified());
3050 if (Init) {
3051 // Compile the initializer in its own scope.
3053 if (!this->visit(Init))
3054 return false;
3055
3056 return this->emitSetLocal(*VarT, Offset, VD);
3057 }
3058 } else {
3059 if (std::optional<unsigned> Offset = this->allocateLocal(VD))
3060 return !Init || this->visitLocalInitializer(Init, *Offset);
3061 return false;
3062 }
3063
3064 return true;
3065 }
3066
3067 return false;
3068}
3069
3070template <class Emitter>
3072 PrimType ValType, const Expr *E) {
3073 assert(!DiscardResult);
3074 if (Val.isInt())
3075 return this->emitConst(Val.getInt(), ValType, E);
3076
3077 if (Val.isLValue()) {
3079 if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>())
3080 return this->visit(BaseExpr);
3081 }
3082
3083 return false;
3084}
3085
3086template <class Emitter>
3088 const Expr *E) {
3089 if (Val.isStruct()) {
3090 const Record *R = this->getRecord(E->getType());
3091 assert(R);
3092
3093 for (unsigned I = 0, N = Val.getStructNumFields(); I != N; ++I) {
3094 const APValue &F = Val.getStructField(I);
3095 const Record::Field *RF = R->getField(I);
3096
3097 if (F.isInt()) {
3098 PrimType T = classifyPrim(RF->Decl->getType());
3099 if (!this->visitAPValue(F, T, E))
3100 return false;
3101 if (!this->emitInitField(T, RF->Offset, E))
3102 return false;
3103 } else if (F.isArray()) {
3104 assert(RF->Desc->isPrimitiveArray());
3105 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
3106 PrimType ElemT = classifyPrim(ArrType->getElementType());
3107 assert(ArrType);
3108
3109 if (!this->emitDupPtr(E))
3110 return false;
3111 if (!this->emitGetPtrField(RF->Offset, E))
3112 return false;
3113
3114 for (unsigned A = 0, AN = F.getArraySize(); A != AN; ++A) {
3115 if (!this->visitAPValue(F.getArrayInitializedElt(A), ElemT, E))
3116 return false;
3117 if (!this->emitInitElem(ElemT, A, E))
3118 return false;
3119 }
3120
3121 if (!this->emitPopPtr(E))
3122 return false;
3123 } else {
3124 assert(false && "I don't think this should be possible");
3125 }
3126 }
3127 return true;
3128 }
3129 // TODO: Other types.
3130
3131 return false;
3132}
3133
3134template <class Emitter>
3136 const Function *Func = getFunction(E->getDirectCallee());
3137 if (!Func)
3138 return false;
3139
3140 QualType ReturnType = E->getType();
3141 std::optional<PrimType> ReturnT = classify(E);
3142
3143 // Non-primitive return type. Prepare storage.
3144 if (!Initializing && !ReturnT && !ReturnType->isVoidType()) {
3145 std::optional<unsigned> LocalIndex = allocateLocal(E);
3146 if (!LocalIndex)
3147 return false;
3148 if (!this->emitGetPtrLocal(*LocalIndex, E))
3149 return false;
3150 }
3151
3152 if (!Func->isUnevaluatedBuiltin()) {
3153 // Put arguments on the stack.
3154 for (const auto *Arg : E->arguments()) {
3155 if (!this->visit(Arg))
3156 return false;
3157 }
3158 }
3159
3160 if (!this->emitCallBI(Func, E, E))
3161 return false;
3162
3163 if (DiscardResult && !ReturnType->isVoidType()) {
3164 assert(ReturnT);
3165 return this->emitPop(*ReturnT, E);
3166 }
3167
3168 return true;
3169}
3170
3171template <class Emitter>
3173 if (E->getBuiltinCallee())
3174 return VisitBuiltinCallExpr(E);
3175
3176 QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
3177 std::optional<PrimType> T = classify(ReturnType);
3178 bool HasRVO = !ReturnType->isVoidType() && !T;
3179 const FunctionDecl *FuncDecl = E->getDirectCallee();
3180
3181 if (HasRVO) {
3182 if (DiscardResult) {
3183 // If we need to discard the return value but the function returns its
3184 // value via an RVO pointer, we need to create one such pointer just
3185 // for this call.
3186 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
3187 if (!this->emitGetPtrLocal(*LocalIndex, E))
3188 return false;
3189 }
3190 } else {
3191 // We need the result. Prepare a pointer to return or
3192 // dup the current one.
3193 if (!Initializing) {
3194 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
3195 if (!this->emitGetPtrLocal(*LocalIndex, E))
3196 return false;
3197 }
3198 }
3199 if (!this->emitDupPtr(E))
3200 return false;
3201 }
3202 }
3203
3204 auto Args = llvm::ArrayRef(E->getArgs(), E->getNumArgs());
3205 // Calling a static operator will still
3206 // pass the instance, but we don't need it.
3207 // Discard it here.
3208 if (isa<CXXOperatorCallExpr>(E)) {
3209 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
3210 MD && MD->isStatic()) {
3211 if (!this->discard(E->getArg(0)))
3212 return false;
3213 Args = Args.drop_front();
3214 }
3215 }
3216
3217 // Add the (optional, implicit) This pointer.
3218 if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
3219 if (!this->visit(MC->getImplicitObjectArgument()))
3220 return false;
3221 }
3222
3223 llvm::BitVector NonNullArgs = collectNonNullArgs(FuncDecl, Args);
3224 // Put arguments on the stack.
3225 unsigned ArgIndex = 0;
3226 for (const auto *Arg : Args) {
3227 if (!this->visit(Arg))
3228 return false;
3229
3230 // If we know the callee already, check the known parametrs for nullability.
3231 if (FuncDecl && NonNullArgs[ArgIndex]) {
3232 PrimType ArgT = classify(Arg).value_or(PT_Ptr);
3233 if (ArgT == PT_Ptr || ArgT == PT_FnPtr) {
3234 if (!this->emitCheckNonNullArg(ArgT, Arg))
3235 return false;
3236 }
3237 }
3238 ++ArgIndex;
3239 }
3240
3241 if (FuncDecl) {
3242 const Function *Func = getFunction(FuncDecl);
3243 if (!Func)
3244 return false;
3245 assert(HasRVO == Func->hasRVO());
3246
3247 bool HasQualifier = false;
3248 if (const auto *ME = dyn_cast<MemberExpr>(E->getCallee()))
3249 HasQualifier = ME->hasQualifier();
3250
3251 bool IsVirtual = false;
3252 if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
3253 IsVirtual = MD->isVirtual();
3254
3255 // In any case call the function. The return value will end up on the stack
3256 // and if the function has RVO, we already have the pointer on the stack to
3257 // write the result into.
3258 if (IsVirtual && !HasQualifier) {
3259 uint32_t VarArgSize = 0;
3260 unsigned NumParams = Func->getNumWrittenParams();
3261 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
3262 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
3263
3264 if (!this->emitCallVirt(Func, VarArgSize, E))
3265 return false;
3266 } else if (Func->isVariadic()) {
3267 uint32_t VarArgSize = 0;
3268 unsigned NumParams =
3269 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(E);
3270 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
3271 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
3272 if (!this->emitCallVar(Func, VarArgSize, E))
3273 return false;
3274 } else {
3275 if (!this->emitCall(Func, 0, E))
3276 return false;
3277 }
3278 } else {
3279 // Indirect call. Visit the callee, which will leave a FunctionPointer on
3280 // the stack. Cleanup of the returned value if necessary will be done after
3281 // the function call completed.
3282
3283 // Sum the size of all args from the call expr.
3284 uint32_t ArgSize = 0;
3285 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
3286 ArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
3287
3288 if (!this->visit(E->getCallee()))
3289 return false;
3290
3291 if (!this->emitCallPtr(ArgSize, E, E))
3292 return false;
3293 }
3294
3295 // Cleanup for discarded return values.
3296 if (DiscardResult && !ReturnType->isVoidType() && T)
3297 return this->emitPop(*T, E);
3298
3299 return true;
3300}
3301
3302template <class Emitter>
3304 const CXXDefaultInitExpr *E) {
3305 SourceLocScope<Emitter> SLS(this, E);
3306 return this->delegate(E->getExpr());
3307}
3308
3309template <class Emitter>
3311 const CXXDefaultArgExpr *E) {
3312 SourceLocScope<Emitter> SLS(this, E);
3313
3314 const Expr *SubExpr = E->getExpr();
3315 if (std::optional<PrimType> T = classify(E->getExpr()))
3316 return this->visit(SubExpr);
3317
3318 assert(Initializing);
3319 return this->visitInitializer(SubExpr);
3320}
3321
3322template <class Emitter>
3324 const CXXBoolLiteralExpr *E) {
3325 if (DiscardResult)
3326 return true;
3327
3328 return this->emitConstBool(E->getValue(), E);
3329}
3330
3331template <class Emitter>
3333 const CXXNullPtrLiteralExpr *E) {
3334 if (DiscardResult)
3335 return true;
3336
3337 return this->emitNullPtr(nullptr, E);
3338}
3339
3340template <class Emitter>
3342 if (DiscardResult)
3343 return true;
3344
3345 assert(E->getType()->isIntegerType());
3346
3347 PrimType T = classifyPrim(E->getType());
3348 return this->emitZero(T, E);
3349}
3350
3351template <class Emitter>
3353 if (DiscardResult)
3354 return true;
3355
3356 if (this->LambdaThisCapture.Offset > 0) {
3357 if (this->LambdaThisCapture.IsPtr)
3358 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
3359 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
3360 }
3361
3362 return this->emitThis(E);
3363}
3364
3365template <class Emitter>
3367 const Expr *SubExpr = E->getSubExpr();
3368 if (SubExpr->getType()->isAnyComplexType())
3369 return this->VisitComplexUnaryOperator(E);
3370 std::optional<PrimType> T = classify(SubExpr->getType());
3371
3372 switch (E->getOpcode()) {
3373 case UO_PostInc: { // x++
3374 if (!this->visit(SubExpr))
3375 return false;
3376
3377 if (T == PT_Ptr || T == PT_FnPtr) {
3378 if (!this->emitIncPtr(E))
3379 return false;
3380
3381 return DiscardResult ? this->emitPopPtr(E) : true;
3382 }
3383
3384 if (T == PT_Float) {
3385 return DiscardResult ? this->emitIncfPop(getRoundingMode(E), E)
3386 : this->emitIncf(getRoundingMode(E), E);
3387 }
3388
3389 return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E);
3390 }
3391 case UO_PostDec: { // x--
3392 if (!this->visit(SubExpr))
3393 return false;
3394
3395 if (T == PT_Ptr || T == PT_FnPtr) {
3396 if (!this->emitDecPtr(E))
3397 return false;
3398
3399 return DiscardResult ? this->emitPopPtr(E) : true;
3400 }
3401
3402 if (T == PT_Float) {
3403 return DiscardResult ? this->emitDecfPop(getRoundingMode(E), E)
3404 : this->emitDecf(getRoundingMode(E), E);
3405 }
3406
3407 return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E);
3408 }
3409 case UO_PreInc: { // ++x
3410 if (!this->visit(SubExpr))
3411 return false;
3412
3413 if (T == PT_Ptr || T == PT_FnPtr) {
3414 if (!this->emitLoadPtr(E))
3415 return false;
3416 if (!this->emitConstUint8(1, E))
3417 return false;
3418 if (!this->emitAddOffsetUint8(E))
3419 return false;
3420 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
3421 }
3422
3423 // Post-inc and pre-inc are the same if the value is to be discarded.
3424 if (DiscardResult) {
3425 if (T == PT_Float)
3426 return this->emitIncfPop(getRoundingMode(E), E);
3427 return this->emitIncPop(*T, E);
3428 }
3429
3430 if (T == PT_Float) {
3431 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
3432 if (!this->emitLoadFloat(E))
3433 return false;
3434 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
3435 return false;
3436 if (!this->emitAddf(getRoundingMode(E), E))
3437 return false;
3438 if (!this->emitStoreFloat(E))
3439 return false;
3440 } else {
3441 assert(isIntegralType(*T));
3442 if (!this->emitLoad(*T, E))
3443 return false;
3444 if (!this->emitConst(1, E))
3445 return false;
3446 if (!this->emitAdd(*T, E))
3447 return false;
3448 if (!this->emitStore(*T, E))
3449 return false;
3450 }
3451 return E->isGLValue() || this->emitLoadPop(*T, E);
3452 }
3453 case UO_PreDec: { // --x
3454 if (!this->visit(SubExpr))
3455 return false;
3456
3457 if (T == PT_Ptr || T == PT_FnPtr) {
3458 if (!this->emitLoadPtr(E))
3459 return false;
3460 if (!this->emitConstUint8(1, E))
3461 return false;
3462 if (!this->emitSubOffsetUint8(E))
3463 return false;
3464 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
3465 }
3466
3467 // Post-dec and pre-dec are the same if the value is to be discarded.
3468 if (DiscardResult) {
3469 if (T == PT_Float)
3470 return this->emitDecfPop(getRoundingMode(E), E);
3471 return this->emitDecPop(*T, E);
3472 }
3473
3474 if (T == PT_Float) {
3475 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
3476 if (!this->emitLoadFloat(E))
3477 return false;
3478 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
3479 return false;
3480 if (!this->emitSubf(getRoundingMode(E), E))
3481 return false;
3482 if (!this->emitStoreFloat(E))
3483 return false;
3484 } else {
3485 assert(isIntegralType(*T));
3486 if (!this->emitLoad(*T, E))
3487 return false;
3488 if (!this->emitConst(1, E))
3489 return false;
3490 if (!this->emitSub(*T, E))
3491 return false;
3492 if (!this->emitStore(*T, E))
3493 return false;
3494 }
3495 return E->isGLValue() || this->emitLoadPop(*T, E);
3496 }
3497 case UO_LNot: // !x
3498 if (DiscardResult)
3499 return this->discard(SubExpr);
3500
3501 if (!this->visitBool(SubExpr))
3502 return false;
3503
3504 if (!this->emitInvBool(E))
3505 return false;
3506
3507 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
3508 return this->emitCast(PT_Bool, ET, E);
3509 return true;
3510 case UO_Minus: // -x
3511 if (!this->visit(SubExpr))
3512 return false;
3513 return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
3514 case UO_Plus: // +x
3515 if (!this->visit(SubExpr)) // noop
3516 return false;
3517 return DiscardResult ? this->emitPop(*T, E) : true;
3518 case UO_AddrOf: // &x
3519 // We should already have a pointer when we get here.
3520 return this->delegate(SubExpr);
3521 case UO_Deref: // *x
3522 if (DiscardResult)
3523 return this->discard(SubExpr);
3524 return this->visit(SubExpr);
3525 case UO_Not: // ~x
3526 if (!this->visit(SubExpr))
3527 return false;
3528 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
3529 case UO_Real: // __real x
3530 assert(T);
3531 return this->delegate(SubExpr);
3532 case UO_Imag: { // __imag x
3533 assert(T);
3534 if (!this->discard(SubExpr))
3535 return false;
3536 return this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);
3537 }
3538 case UO_Extension:
3539 return this->delegate(SubExpr);
3540 case UO_Coawait:
3541 assert(false && "Unhandled opcode");
3542 }
3543
3544 return false;
3545}
3546
3547template <class Emitter>
3549 const UnaryOperator *E) {
3550 const Expr *SubExpr = E->getSubExpr();
3551 assert(SubExpr->getType()->isAnyComplexType());
3552
3553 if (DiscardResult)
3554 return this->discard(SubExpr);
3555
3556 std::optional<PrimType> ResT = classify(E);
3557 auto prepareResult = [=]() -> bool {
3558 if (!ResT && !Initializing) {
3559 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
3560 if (!LocalIndex)
3561 return false;
3562 return this->emitGetPtrLocal(*LocalIndex, E);
3563 }
3564
3565 return true;
3566 };
3567
3568 // The offset of the temporary, if we created one.
3569 unsigned SubExprOffset = ~0u;
3570 auto createTemp = [=, &SubExprOffset]() -> bool {
3571 SubExprOffset = this->allocateLocalPrimitive(SubExpr, PT_Ptr, true, false);
3572 if (!this->visit(SubExpr))
3573 return false;
3574 return this->emitSetLocal(PT_Ptr, SubExprOffset, E);
3575 };
3576
3577 PrimType ElemT = classifyComplexElementType(SubExpr->getType());
3578 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
3579 if (!this->emitGetLocal(PT_Ptr, Offset, E))
3580 return false;
3581 return this->emitArrayElemPop(ElemT, Index, E);
3582 };
3583
3584 switch (E->getOpcode()) {
3585 case UO_Minus:
3586 if (!prepareResult())
3587 return false;
3588 if (!createTemp())
3589 return false;
3590 for (unsigned I = 0; I != 2; ++I) {
3591 if (!getElem(SubExprOffset, I))
3592 return false;
3593 if (!this->emitNeg(ElemT, E))
3594 return false;
3595 if (!this->emitInitElem(ElemT, I, E))
3596 return false;
3597 }
3598 break;
3599
3600 case UO_Plus: // +x
3601 case UO_AddrOf: // &x
3602 case UO_Deref: // *x
3603 return this->delegate(SubExpr);
3604
3605 case UO_LNot:
3606 if (!this->visit(SubExpr))
3607 return false;
3608 if (!this->emitComplexBoolCast(SubExpr))
3609 return false;
3610 if (!this->emitInvBool(E))
3611 return false;
3612 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
3613 return this->emitCast(PT_Bool, ET, E);
3614 return true;
3615
3616 case UO_Real:
3617 return this->emitComplexReal(SubExpr);
3618
3619 case UO_Imag:
3620 if (!this->visit(SubExpr))
3621 return false;
3622
3623 if (SubExpr->isLValue()) {
3624 if (!this->emitConstUint8(1, E))
3625 return false;
3626 return this->emitArrayElemPtrPopUint8(E);
3627 }
3628
3629 // Since our _Complex implementation does not map to a primitive type,
3630 // we sometimes have to do the lvalue-to-rvalue conversion here manually.
3631 return this->emitArrayElemPop(classifyPrim(E->getType()), 1, E);
3632
3633 default:
3634 return this->emitInvalid(E);
3635 }
3636
3637 return true;
3638}
3639
3640template <class Emitter>
3642 if (DiscardResult)
3643 return true;
3644
3645 const auto *D = E->getDecl();
3646
3647 if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
3648 return this->emitConst(ECD->getInitVal(), E);
3649 } else if (const auto *BD = dyn_cast<BindingDecl>(D)) {
3650 return this->visit(BD->getBinding());
3651 } else if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
3652 const Function *F = getFunction(FuncDecl);
3653 return F && this->emitGetFnPtr(F, E);
3654 } else if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
3655 if (std::optional<unsigned> Index = P.getOrCreateGlobal(D)) {
3656 if (!this->emitGetPtrGlobal(*Index, E))
3657 return false;
3658 if (std::optional<PrimType> T = classify(E->getType())) {
3659 if (!this->visitAPValue(TPOD->getValue(), *T, E))
3660 return false;
3661 return this->emitInitGlobal(*T, *Index, E);
3662 }
3663 return this->visitAPValueInitializer(TPOD->getValue(), E);
3664 }
3665 return false;
3666 }
3667
3668 // References are implemented via pointers, so when we see a DeclRefExpr
3669 // pointing to a reference, we need to get its value directly (i.e. the
3670 // pointer to the actual value) instead of a pointer to the pointer to the
3671 // value.
3672 bool IsReference = D->getType()->isReferenceType();
3673
3674 // Check for local/global variables and parameters.
3675 if (auto It = Locals.find(D); It != Locals.end()) {
3676 const unsigned Offset = It->second.Offset;
3677 if (IsReference)
3678 return this->emitGetLocal(PT_Ptr, Offset, E);
3679 return this->emitGetPtrLocal(Offset, E);
3680 } else if (auto GlobalIndex = P.getGlobal(D)) {
3681 if (IsReference)
3682 return this->emitGetGlobalPtr(*GlobalIndex, E);
3683
3684 return this->emitGetPtrGlobal(*GlobalIndex, E);
3685 } else if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
3686 if (auto It = this->Params.find(PVD); It != this->Params.end()) {
3687 if (IsReference || !It->second.IsPtr)
3688 return this->emitGetParamPtr(It->second.Offset, E);
3689
3690 return this->emitGetPtrParam(It->second.Offset, E);
3691 }
3692 }
3693
3694 // Handle lambda captures.
3695 if (auto It = this->LambdaCaptures.find(D);
3696 It != this->LambdaCaptures.end()) {
3697 auto [Offset, IsPtr] = It->second;
3698
3699 if (IsPtr)
3700 return this->emitGetThisFieldPtr(Offset, E);
3701 return this->emitGetPtrThisField(Offset, E);
3702 }
3703
3704 // Try to lazily visit (or emit dummy pointers for) declarations
3705 // we haven't seen yet.
3706 if (Ctx.getLangOpts().CPlusPlus) {
3707 if (const auto *VD = dyn_cast<VarDecl>(D)) {
3708 // Visit local const variables like normal.
3709 if ((VD->isLocalVarDecl() || VD->isStaticDataMember()) &&
3710 VD->getType().isConstQualified()) {
3711 if (!this->visitVarDecl(VD))
3712 return false;
3713 // Retry.
3714 return this->VisitDeclRefExpr(E);
3715 }
3716 }
3717 } else {
3718 if (const auto *VD = dyn_cast<VarDecl>(D);
3719 VD && VD->getAnyInitializer() && VD->getType().isConstQualified()) {
3720 if (!this->visitVarDecl(VD))
3721 return false;
3722 // Retry.
3723 return this->VisitDeclRefExpr(E);
3724 }
3725 }
3726
3727 if (std::optional<unsigned> I = P.getOrCreateDummy(D))
3728 return this->emitGetPtrGlobal(*I, E);
3729
3730 return this->emitInvalidDeclRef(E, E);
3731}
3732
3733template <class Emitter>
3735 for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent())
3736 C->emitDestruction();
3737}
3738
3739template <class Emitter>
3740unsigned
3742 const QualType DerivedType) {
3743 const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
3744 if (const auto *PT = dyn_cast<PointerType>(Ty))
3745 return PT->getPointeeType()->getAsCXXRecordDecl();
3746 return Ty->getAsCXXRecordDecl();
3747 };
3748 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
3749 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
3750
3751 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
3752}
3753
3754/// Emit casts from a PrimType to another PrimType.
3755template <class Emitter>
3757 QualType ToQT, const Expr *E) {
3758
3759 if (FromT == PT_Float) {
3760 // Floating to floating.
3761 if (ToT == PT_Float) {
3762 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
3763 return this->emitCastFP(ToSem, getRoundingMode(E), E);
3764 }
3765
3766 if (ToT == PT_IntAP)
3767 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT), E);
3768 if (ToT == PT_IntAPS)
3769 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT), E);
3770
3771 // Float to integral.
3772 if (isIntegralType(ToT) || ToT == PT_Bool)
3773 return this->emitCastFloatingIntegral(ToT, E);
3774 }
3775
3776 if (isIntegralType(FromT) || FromT == PT_Bool) {
3777 if (ToT == PT_IntAP)
3778 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
3779 if (ToT == PT_IntAPS)
3780 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
3781
3782 // Integral to integral.
3783 if (isIntegralType(ToT) || ToT == PT_Bool)
3784 return FromT != ToT ? this->emitCast(FromT, ToT, E) : true;
3785
3786 if (ToT == PT_Float) {
3787 // Integral to floating.
3788 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
3789 return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(E),
3790 E);
3791 }
3792 }
3793
3794 return false;
3795}
3796
3797/// Emits __real(SubExpr)
3798template <class Emitter>
3800 assert(SubExpr->getType()->isAnyComplexType());
3801
3802 if (DiscardResult)
3803 return this->discard(SubExpr);
3804
3805 if (!this->visit(SubExpr))
3806 return false;
3807 if (SubExpr->isLValue()) {
3808 if (!this->emitConstUint8(0, SubExpr))
3809 return false;
3810 return this->emitArrayElemPtrPopUint8(SubExpr);
3811 }
3812
3813 // Rvalue, load the actual element.
3814 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->getType()),
3815 0, SubExpr);
3816}
3817
3818template <class Emitter>
3820 assert(!DiscardResult);
3821 PrimType ElemT = classifyComplexElementType(E->getType());
3822 // We emit the expression (__real(E) != 0 || __imag(E) != 0)
3823 // for us, that means (bool)E[0] || (bool)E[1]
3824 if (!this->emitArrayElem(ElemT, 0, E))
3825 return false;
3826 if (ElemT == PT_Float) {
3827 if (!this->emitCastFloatingIntegral(PT_Bool, E))
3828 return false;
3829 } else {
3830 if (!this->emitCast(ElemT, PT_Bool, E))
3831 return false;
3832 }
3833
3834 // We now have the bool value of E[0] on the stack.
3835 LabelTy LabelTrue = this->getLabel();
3836 if (!this->jumpTrue(LabelTrue))
3837 return false;
3838
3839 if (!this->emitArrayElemPop(ElemT, 1, E))
3840 return false;
3841 if (ElemT == PT_Float) {
3842 if (!this->emitCastFloatingIntegral(PT_Bool, E))
3843 return false;
3844 } else {
3845 if (!this->emitCast(ElemT, PT_Bool, E))
3846 return false;
3847 }
3848 // Leave the boolean value of E[1] on the stack.
3849 LabelTy EndLabel = this->getLabel();
3850 this->jump(EndLabel);
3851
3852 this->emitLabel(LabelTrue);
3853 if (!this->emitPopPtr(E))
3854 return false;
3855 if (!this->emitConstBool(true, E))
3856 return false;
3857
3858 this->fallthrough(EndLabel);
3859 this->emitLabel(EndLabel);
3860
3861 return true;
3862}
3863
3864template <class Emitter>
3866 const Expr *RHS,
3867 const BinaryOperator *E) {
3868 assert(E->isComparisonOp());
3869 assert(!Initializing);
3870 assert(!DiscardResult);
3871
3872 PrimType ElemT;
3873 bool LHSIsComplex;
3874 unsigned LHSOffset;
3875 if (LHS->getType()->isAnyComplexType()) {
3876 LHSIsComplex = true;
3877 ElemT = classifyComplexElementType(LHS->getType());
3878 LHSOffset = allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true,
3879 /*IsExtended=*/false);
3880 if (!this->visit(LHS))
3881 return false;
3882 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
3883 return false;
3884 } else {
3885 LHSIsComplex = false;
3886 PrimType LHST = classifyPrim(LHS->getType());
3887 LHSOffset = this->allocateLocalPrimitive(LHS, LHST, true, false);
3888 if (!this->visit(LHS))
3889 return false;
3890 if (!this->emitSetLocal(LHST, LHSOffset, E))
3891 return false;
3892 }
3893
3894 bool RHSIsComplex;
3895 unsigned RHSOffset;
3896 if (RHS->getType()->isAnyComplexType()) {
3897 RHSIsComplex = true;
3898 ElemT = classifyComplexElementType(RHS->getType());
3899 RHSOffset = allocateLocalPrimitive(RHS, PT_Ptr, /*IsConst=*/true,
3900 /*IsExtended=*/false);
3901 if (!this->visit(RHS))
3902 return false;
3903 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
3904 return false;
3905 } else {
3906 RHSIsComplex = false;
3907 PrimType RHST = classifyPrim(RHS->getType());
3908 RHSOffset = this->allocateLocalPrimitive(RHS, RHST, true, false);
3909 if (!this->visit(RHS))
3910 return false;
3911 if (!this->emitSetLocal(RHST, RHSOffset, E))
3912 return false;
3913 }
3914
3915 auto getElem = [&](unsigned LocalOffset, unsigned Index,
3916 bool IsComplex) -> bool {
3917 if (IsComplex) {
3918 if (!this->emitGetLocal(PT_Ptr, LocalOffset, E))
3919 return false;
3920 return this->emitArrayElemPop(ElemT, Index, E);
3921 }
3922 return this->emitGetLocal(ElemT, LocalOffset, E);
3923 };
3924
3925 for (unsigned I = 0; I != 2; ++I) {
3926 // Get both values.
3927 if (!getElem(LHSOffset, I, LHSIsComplex))
3928 return false;
3929 if (!getElem(RHSOffset, I, RHSIsComplex))
3930 return false;
3931 // And compare them.
3932 if (!this->emitEQ(ElemT, E))
3933 return false;
3934
3935 if (!this->emitCastBoolUint8(E))
3936 return false;
3937 }
3938
3939 // We now have two bool values on the stack. Compare those.
3940 if (!this->emitAddUint8(E))
3941 return false;
3942 if (!this->emitConstUint8(2, E))
3943 return false;
3944
3945 if (E->getOpcode() == BO_EQ) {
3946 if (!this->emitEQUint8(E))
3947 return false;
3948 } else if (E->getOpcode() == BO_NE) {
3949 if (!this->emitNEUint8(E))
3950 return false;
3951 } else
3952 return false;
3953
3954 // In C, this returns an int.
3955 if (PrimType ResT = classifyPrim(E->getType()); ResT != PT_Bool)
3956 return this->emitCast(PT_Bool, ResT, E);
3957 return true;
3958}
3959
3960/// When calling this, we have a pointer of the local-to-destroy
3961/// on the stack.
3962/// Emit destruction of record types (or arrays of record types).
3963template <class Emitter>
3965 assert(R);
3966 // First, destroy all fields.
3967 for (const Record::Field &Field : llvm::reverse(R->fields())) {
3968 const Descriptor *D = Field.Desc;
3969 if (!D->isPrimitive() && !D->isPrimitiveArray()) {
3970 if (!this->emitDupPtr(SourceInfo{}))
3971 return false;
3972 if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
3973 return false;
3974 if (!this->emitDestruction(D))
3975 return false;
3976 if (!this->emitPopPtr(SourceInfo{}))
3977 return false;
3978 }
3979 }
3980
3981 // FIXME: Unions need to be handled differently here. We don't want to
3982 // call the destructor of its members.
3983
3984 // Now emit the destructor and recurse into base classes.
3985 if (const CXXDestructorDecl *Dtor = R->getDestructor();
3986 Dtor && !Dtor->isTrivial()) {
3987 const Function *DtorFunc = getFunction(Dtor);
3988 if (!DtorFunc)
3989 return false;
3990 assert(DtorFunc->hasThisPointer());
3991 assert(DtorFunc->getNumParams() == 1);
3992 if (!this->emitDupPtr(SourceInfo{}))
3993 return false;
3994 if (!this->emitCall(DtorFunc, 0, SourceInfo{}))
3995 return false;
3996 }
3997
3998 for (const Record::Base &Base : llvm::reverse(R->bases())) {
3999 if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
4000 return false;
4001 if (!this->emitRecordDestruction(Base.R))
4002 return false;
4003 if (!this->emitPopPtr(SourceInfo{}))
4004 return false;
4005 }
4006
4007 // FIXME: Virtual bases.
4008 return true;
4009}
4010/// When calling this, we have a pointer of the local-to-destroy
4011/// on the stack.
4012/// Emit destruction of record types (or arrays of record types).
4013template <class Emitter>
4015 assert(Desc);
4016 assert(!Desc->isPrimitive());
4017 assert(!Desc->isPrimitiveArray());
4018
4019 // Arrays.
4020 if (Desc->isArray()) {
4021 const Descriptor *ElemDesc = Desc->ElemDesc;
4022 assert(ElemDesc);
4023
4024 // Don't need to do anything for these.
4025 if (ElemDesc->isPrimitiveArray())
4026 return true;
4027
4028 // If this is an array of record types, check if we need
4029 // to call the element destructors at all. If not, try
4030 // to save the work.
4031 if (const Record *ElemRecord = ElemDesc->ElemRecord) {
4032 if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
4033 !Dtor || Dtor->isTrivial())
4034 return true;
4035 }
4036
4037 for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) {
4038 if (!this->emitConstUint64(I, SourceInfo{}))
4039 return false;
4040 if (!this->emitArrayElemPtrUint64(SourceInfo{}))
4041 return false;
4042 if (!this->emitDestruction(ElemDesc))
4043 return false;
4044 if (!this->emitPopPtr(SourceInfo{}))
4045 return false;
4046 }
4047 return true;
4048 }
4049
4050 assert(Desc->ElemRecord);
4051 return this->emitRecordDestruction(Desc->ElemRecord);
4052}
4053
4054namespace clang {
4055namespace interp {
4056
4058template class ByteCodeExprGen<EvalEmitter>;
4059
4060} // namespace interp
4061} // namespace clang
#define V(N, I)
Definition: ASTContext.h:3285
ASTImporterLookupTable & LT
DynTypedNode Node
StringRef P
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
llvm::APSInt APSInt
bool IsStatic
Definition: Format.cpp:2987
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
const LValueBase getLValueBase() const
Definition: APValue.cpp:974
APValue & getArrayInitializedElt(unsigned I)
Definition: APValue.h:510
ArrayRef< LValuePathEntry > getLValuePath() const
Definition: APValue.cpp:994
APSInt & getInt()
Definition: APValue.h:423
APValue & getStructField(unsigned i)
Definition: APValue.h:551
unsigned getStructNumFields() const
Definition: APValue.h:542
bool isArray() const
Definition: APValue.h:408
bool isLValue() const
Definition: APValue.h:406
bool isInt() const
Definition: APValue.h:401
unsigned getArraySize() const
Definition: APValue.h:533
@ None
There is no such object (it's outside its lifetime).
Definition: APValue.h:129
bool isStruct() const
Definition: APValue.h:409
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:2432
const LangOptions & getLangOpts() const
Definition: ASTContext.h:775
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const
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:4141
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Definition: Expr.h:4319
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Definition: Expr.h:4325
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Definition: Expr.h:4331
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition: Expr.h:4338
LabelDecl * getLabel() const
Definition: Expr.h:4361
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition: Expr.h:5564
Represents a loop initializing the elements of an array.
Definition: Expr.h:5511
llvm::APInt getArraySize() const
Definition: Expr.h:5533
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Definition: Expr.h:5526
Expr * getSubExpr() const
Get the initializer to use for each array element.
Definition: Expr.h:5531
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2664
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition: ExprCXX.h:2848
uint64_t getValue() const
Definition: ExprCXX.h:2894
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3518
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3840
static bool isLogicalOp(Opcode Opc)
Definition: Expr.h:3972
Expr * getLHS() const
Definition: Expr.h:3889
static bool isComparisonOp(Opcode Opc)
Definition: Expr.h:3939
static bool isCommaOp(Opcode Opc)
Definition: Expr.h:3942
Expr * getRHS() const
Definition: Expr.h:3891
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
Definition: Expr.h:3916
Opcode getOpcode() const
Definition: Expr.h:3884
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1487
const Expr * getSubExpr() const
Definition: ExprCXX.h:1509
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:1542
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition: ExprCXX.h:1685
arg_range arguments()
Definition: ExprCXX.h:1666
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
Definition: ExprCXX.h:1644
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition: ExprCXX.h:1605
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Definition: ExprCXX.h:1682
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2535
A default argument (C++ [dcl.fct.default]).
Definition: ExprCXX.h:1264
A use of a default initializer in a constructor or in aggregate initialization.
Definition: ExprCXX.h:1371
Expr * getExpr()
Get the initialization expression that will be used.
Definition: ExprCXX.cpp:1035
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2799
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition: ExprCXX.h:1733
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Definition: ExprCXX.h:1770
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition: ExprCXX.h:4119
bool getValue() const
Definition: ExprCXX.h:4142
The null pointer literal (C++11 [lex.nullptr])
Definition: ExprCXX.h:765
Represents a list-initialization with parenthesis.
Definition: ExprCXX.h:4944
ArrayRef< Expr * > getInitExprs()
Definition: ExprCXX.h:4984
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
Definition: ExprCXX.h:523
A rewritten comparison expression that was originally written using operator syntax.
Definition: ExprCXX.h:283
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
Definition: ExprCXX.h:301
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type.
Definition: ExprCXX.h:2177
Represents the this expression in C++.
Definition: ExprCXX.h:1148
A C++ throw-expression (C++ [except.throw]).
Definition: ExprCXX.h:1202
const Expr * getSubExpr() const
Definition: ExprCXX.h:1222
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Definition: ExprCXX.h:1062
MSGuidDecl * getGuidDecl() const
Definition: ExprCXX.h:1108
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2820
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: Expr.h:3011
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
Definition: Expr.cpp:1579
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition: Expr.h:2990
Expr * getCallee()
Definition: Expr.h:2970
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition: Expr.h:2998
Expr ** getArgs()
Retrieve the call arguments.
Definition: Expr.h:3001
arg_range arguments()
Definition: Expr.h:3059
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition: Expr.cpp:1590
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3483
CastKind getCastKind() const
Definition: Expr.h:3527
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
Definition: Expr.h:3570
Expr * getSubExpr()
Definition: Expr.h:3533
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:1610
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition: Expr.h:4558
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Definition: Expr.h:4594
Complex values, per C99 6.2.5p11.
Definition: Type.h:3086
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4088
QualType getComputationLHSType() const
Definition: Expr.h:4122
QualType getComputationResultType() const
Definition: Expr.h:4125
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3413
bool isFileScope() const
Definition: Expr.h:3440
const Expr * getInitializer() const
Definition: Expr.h:3436
Represents the specialization of a concept - evaluates to a prvalue of type bool.
Definition: ExprConcepts.h:42
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
Definition: ExprConcepts.h:124
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3556
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
Definition: Type.h:3632
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition: Expr.h:1072
APValue getAPValueResult() const
Definition: Expr.cpp:413
bool hasAPValueResult() const
Definition: Expr.h:1147
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition: Expr.h:4499
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Definition: Expr.h:4519
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2066
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1260
ValueDecl * getDecl()
Definition: Expr.h:1328
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
bool isInvalidDecl() const
Definition: DeclBase.h:594
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3467
unsigned getNumObjects() const
Definition: ExprCXX.h:3495
This represents one expression.
Definition: Expr.h:110
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
Definition: Expr.cpp:82
bool isGLValue() const
Definition: Expr.h:280
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
Definition: Expr.h:245
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3055
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
Definition: Expr.h:277
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
Definition: Expr.h:469
QualType getType() const
Definition: Expr.h:142
An expression trait intrinsic.
Definition: ExprCXX.h:2919
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
Definition: Decl.h:3151
llvm::APFloat getValue() const
Definition: Expr.h:1647
const Expr * getSubExpr() const
Definition: Expr.h:1052
Represents a function declaration or definition.
Definition: Decl.h:1971
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2683
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition: Decl.h:2339
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition: Expr.h:4633
Represents a C11 generic selection.
Definition: Expr.h:5725
Expr * getResultExpr()
Return the result expression of this controlling expression.
Definition: Expr.h:6009
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:56
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition: Expr.h:1712
const Expr * getSubExpr() const
Definition: Expr.h:1724
Represents an implicitly-generated value initialization of an object of a given type.
Definition: Expr.h:5600
Describes an C or C++ initializer list.
Definition: Expr.h:4847
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
Definition: Expr.h:4941
ArrayRef< Expr * > inits()
Definition: Expr.h:4887
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1950
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
Definition: ExprCXX.h:2076
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Definition: ExprCXX.cpp:1332
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
Definition: DeclCXX.h:3229
APValue & getAsAPValue() const
Get the value of this MSGuidDecl as an APValue.
Definition: DeclCXX.cpp:3493
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition: ExprCXX.h:4710
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Definition: ExprCXX.h:4735
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition: ExprCXX.h:4727
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
Definition: ExprCXX.h:4760
LifetimeExtendedTemporaryDecl * getLifetimeExtendedTemporaryDecl()
Definition: ExprCXX.h:4750
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3172
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition: Expr.h:3255
Expr * getBase() const
Definition: Expr.h:3249
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition: ExprObjC.h:87
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition: Expr.h:2465
Expr * getIndexExpr(unsigned Idx)
Definition: Expr.h:2526
const OffsetOfNode & getComponent(unsigned Idx) const
Definition: Expr.h:2512
unsigned getNumComponents() const
Definition: Expr.h:2522
Helper class for OffsetOfExpr.
Definition: Expr.h:2359
@ Array
An index into an array.
Definition: Expr.h:2364
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1168
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition: Expr.h:1218
Expr * getSelectedExpr() const
Definition: ExprCXX.h:4442
ParenExpr - This represents a parethesized expression, e.g.
Definition: Expr.h:2130
const Expr * getSubExpr() const
Definition: Expr.h:2145
Represents a parameter to a function.
Definition: Decl.h:1761
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3139
[C99 6.4.2.2] - A predefined identifier such as func.
Definition: Expr.h:1986
StringLiteral * getFunctionName()
Definition: Expr.h:2030
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:6305
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
Definition: Expr.h:6358
ArrayRef< Expr * > semantics()
Definition: Expr.h:6384
A (possibly-)qualified type.
Definition: Type.h:940
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:7359
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:7432
Represents a struct/union/class.
Definition: Decl.h:4168
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5549
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Definition: Expr.h:6909
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3380
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Definition: ExprConcepts.h:510
bool isSatisfied() const
Whether or not the requires clause is satisfied.
Definition: ExprConcepts.h:562
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Definition: Expr.h:4431
llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const
Definition: Expr.h:4482
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Definition: Expr.h:4465
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Definition: Expr.h:4471
Represents an expression that computes the length of a parameter pack.
Definition: ExprCXX.h:4251
unsigned getPackLength() const
Retrieve the length of the parameter pack.
Definition: ExprCXX.h:4326
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition: Expr.h:4727
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:2273
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1773
unsigned getLength() const
Definition: Expr.h:1890
uint32_t getCodeUnit(size_t i) const
Definition: Expr.h:1865
unsigned getCharByteWidth() const
Definition: Expr.h:1891
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4466
bool isUnion() const
Definition: Decl.h:3790
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition: ExprCXX.h:2763
bool getValue() const
Definition: ExprCXX.h:2804
bool isVoidType() const
Definition: Type.h:7905
bool isBooleanType() const
Definition: Type.h:8033
bool isIncompleteArrayType() const
Definition: Type.h:7686
bool isVoidPointerType() const
Definition: Type.cpp:655
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
Definition: Type.cpp:2341
bool isArrayType() const
Definition: Type.h:7678
bool isPointerType() const
Definition: Type.h:7612
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:7945
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8193
bool isReferenceType() const
Definition: Type.h:7624
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:695
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:8020
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2653
bool isAnyComplexType() const
Definition: Type.h:7714
bool isAtomicType() const
Definition: Type.h:7757
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition: Type.h:8179
bool isFunctionType() const
Definition: Type.h:7608
bool isVectorType() const
Definition: Type.h:7718
bool isFloatingType() const
Definition: Type.cpp:2238
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8126
bool isRecordType() const
Definition: Type.h:7706
bool isSizelessVectorType() const
Returns true for all scalable vector types.
Definition: Type.cpp:2457
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition: Type.cpp:1875
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2568
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
Definition: Expr.h:2637
bool isArgumentType() const
Definition: Expr.h:2610
UnaryExprOrTypeTrait getKind() const
Definition: Expr.h:2600
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2183
Expr * getSubExpr() const
Definition: Expr.h:2228
Opcode getOpcode() const
Definition: Expr.h:2223
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:706
QualType getType() const
Definition: Decl.h:717
Represents a variable declaration or definition.
Definition: Decl.h:918
const Expr * getInit() const
Definition: Decl.h:1355
Represents a GCC generic vector type.
Definition: Type.h:3969
unsigned getNumElements() const
Definition: Type.h:3984
QualType getElementType() const
Definition: Type.h:3983
Scope for storage declared in a compound statement.
Compilation context for expressions.
bool visitExpr(const Expr *E) override
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
std::optional< unsigned > allocateLocal(DeclTy &&Decl, const ValueDecl *ExtendingDecl=nullptr)
Allocates a space storing a local given its type.
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsExtended=false)
Creates a local primitive value.
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool VisitDeclRefExpr(const DeclRefExpr *E)
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool VisitPseudoObjectExpr(const PseudoObjectExpr *E)
bool VisitComplexBinOp(const BinaryOperator *E)
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
bool VisitConvertVectorExpr(const ConvertVectorExpr *E)
bool VisitMemberExpr(const MemberExpr *E)
bool VisitOffsetOfExpr(const OffsetOfExpr *E)
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *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 VisitCXXUuidofExpr(const CXXUuidofExpr *E)
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 VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E)
bool VisitImaginaryLiteral(const ImaginaryLiteral *E)
bool VisitLambdaExpr(const LambdaExpr *E)
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool visitAPValueInitializer(const APValue &Val, const Expr *E)
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
bool VisitComplexUnaryOperator(const UnaryOperator *E)
bool VisitRequiresExpr(const RequiresExpr *E)
bool VisitBuiltinCallExpr(const CallExpr *E)
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E)
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init)
Pointer to the array(not the element!) must be on the stack when calling this.
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 VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
bool VisitPackIndexingExpr(const PackIndexingExpr *E)
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
bool VisitGenericSelectionExpr(const GenericSelectionExpr *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 VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *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)
bool visitInitList(ArrayRef< const Expr * > Inits, const Expr *ArrayFiller, const Expr *E)
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
typename Emitter::LabelTy LabelTy
bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E)
Visit an APValue.
bool VisitPointerArithBinOp(const BinaryOperator *E)
Perform addition/subtraction of a pointer and an integer or subtraction of two pointers.
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitCompoundAssignOperator(const CompoundAssignOperator *E)
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *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 VisitChooseExpr(const ChooseExpr *E)
bool VisitCastExpr(const CastExpr *E)
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E)
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
bool VisitRecoveryExpr(const RecoveryExpr *E)
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Definition: Context.h:97
Scope used to handle temporaries in toplevel variable declarations.
DeclScope(ByteCodeExprGen< Emitter > *Ctx, const ValueDecl *VD)
Bytecode function.
Definition: Function.h:77
unsigned getNumParams() const
Definition: Function.h:187
bool hasThisPointer() const
Definition: Function.h:171
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Definition: Function.h:110
Generic scope for local variables.
bool destroyLocals()
Explicit destruction of 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:131
Structure/Class descriptor.
Definition: Record.h:25
const CXXDestructorDecl * getDestructor() const
Returns the destructor of the record, if any.
Definition: Record.h:70
const Field * getField(const FieldDecl *FD) const
Returns a field.
Definition: Record.cpp:39
llvm::iterator_range< const_base_iter > bases() const
Definition: Record.h:85
unsigned getNumFields() const
Definition: Record.h:81
llvm::iterator_range< const_field_iter > fields() const
Definition: Record.h:77
const Base * getBase(const RecordDecl *FD) const
Returns a base descriptor.
Definition: Record.cpp:45
Describes a scope block.
Definition: Function.h:35
Describes the statement/declaration an opcode was generated from.
Definition: Source.h:72
Scope chain managing the variable lifetimes.
ByteCodeExprGen< Emitter > * Ctx
ByteCodeExprGen instance.
constexpr bool isPtrType(PrimType T)
Definition: PrimType.h:49
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition: PrimType.h:99
bool LE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:882
PrimType
Enumeration of the primitive types of the VM.
Definition: PrimType.h:32
llvm::BitVector collectNonNullArgs(const FunctionDecl *F, const llvm::ArrayRef< const Expr * > &Args)
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
Definition: PrimType.cpp:22
llvm::APSInt APSInt
Definition: Floating.h:24
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
Definition: Descriptor.h:27
constexpr bool isIntegralType(PrimType T)
Definition: PrimType.h:70
The JSON file list parser is used to communicate input to InstallAPI.
BinaryOperatorKind
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
Definition: TypeTraits.h:51
@ SD_Static
Static storage duration.
Definition: Specifiers.h:328
const FunctionProtoType * T
#define true
Definition: stdbool.h:25
Describes a memory block created by an allocation site.
Definition: Descriptor.h:91
unsigned getNumElems() const
Returns the number of elements stored in the block.
Definition: Descriptor.h:211
bool isPrimitive() const
Checks if the descriptor is of a primitive.
Definition: Descriptor.h:225
QualType getElemQualType() const
Definition: Descriptor.cpp:360
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
Definition: Descriptor.h:218
QualType getType() const
Definition: Descriptor.cpp:350
const Descriptor *const ElemDesc
Descriptor of the array element.
Definition: Descriptor.h:117
static constexpr MetadataSize InlineDescMD
Definition: Descriptor.h:112
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
Definition: Descriptor.h:216
bool isRecord() const
Checks if the descriptor is of a record.
Definition: Descriptor.h:230
const Record *const ElemRecord
Pointer to the record, if block contains records.
Definition: Descriptor.h:115
bool isArray() const
Checks if the descriptor is of an array.
Definition: Descriptor.h:228
const FieldDecl * Decl
Definition: Record.h:29
Information about a local's storage.
Definition: Function.h:38