clang 23.0.0git
Compiler.cpp
Go to the documentation of this file.
1//===--- Compiler.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 "Compiler.h"
10#include "ByteCodeEmitter.h"
11#include "Context.h"
12#include "FixedPoint.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#include "llvm/Support/SaveAndRestore.h"
20
21using namespace clang;
22using namespace clang::interp;
23
24using APSInt = llvm::APSInt;
25
26namespace clang {
27namespace interp {
28
29static std::optional<bool> getBoolValue(const Expr *E) {
30 if (const auto *CE = dyn_cast_if_present<ConstantExpr>(E);
31 CE && CE->hasAPValueResult() &&
32 CE->getResultAPValueKind() == APValue::ValueKind::Int) {
33 return CE->getResultAsAPSInt().getBoolValue();
34 }
35
36 return std::nullopt;
37}
38
39/// Scope used to handle temporaries in toplevel variable declarations.
40template <class Emitter> class DeclScope final : public LocalScope<Emitter> {
41public:
43 : LocalScope<Emitter>(Ctx), Scope(Ctx->P),
44 OldInitializingDecl(Ctx->InitializingDecl) {
45 Ctx->InitializingDecl = VD;
46 Ctx->InitStack.push_back(InitLink::Decl(VD));
47 }
48
50 this->Ctx->InitializingDecl = OldInitializingDecl;
51 this->Ctx->InitStack.pop_back();
52 }
53
54private:
56 const ValueDecl *OldInitializingDecl;
57};
58
59/// Scope used to handle initialization methods.
60template <class Emitter> class OptionScope final {
61public:
62 /// Root constructor, compiling or discarding primitives.
63 OptionScope(Compiler<Emitter> *Ctx, bool NewDiscardResult,
64 bool NewInitializing, bool NewToLValue)
65 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
66 OldInitializing(Ctx->Initializing), OldToLValue(Ctx->ToLValue) {
67 Ctx->DiscardResult = NewDiscardResult;
68 Ctx->Initializing = NewInitializing;
69 Ctx->ToLValue = NewToLValue;
70 }
71
73 Ctx->DiscardResult = OldDiscardResult;
74 Ctx->Initializing = OldInitializing;
75 Ctx->ToLValue = OldToLValue;
76 }
77
78private:
79 /// Parent context.
81 /// Old discard flag to restore.
82 bool OldDiscardResult;
83 bool OldInitializing;
84 bool OldToLValue;
85};
86
87template <class Emitter>
88bool InitLink::emit(Compiler<Emitter> *Ctx, const Expr *E) const {
89 switch (Kind) {
90 case K_This:
91 return Ctx->emitThis(E);
92 case K_Field:
93 // We're assuming there's a base pointer on the stack already.
94 return Ctx->emitGetPtrFieldPop(Offset, E);
95 case K_Temp:
96 return Ctx->emitGetPtrLocal(Offset, E);
97 case K_Decl:
98 return Ctx->visitDeclRef(D, E);
99 case K_Elem:
100 if (!Ctx->emitConstUint32(Offset, E))
101 return false;
102 return Ctx->emitArrayElemPtrPopUint32(E);
103 case K_RVO:
104 return Ctx->emitRVOPtr(E);
105 case K_InitList:
106 return true;
107 default:
108 llvm_unreachable("Unhandled InitLink kind");
109 }
110 return true;
111}
112
113/// Sets the context for break/continue statements.
114template <class Emitter> class LoopScope final {
115public:
119
120 LoopScope(Compiler<Emitter> *Ctx, const Stmt *Name, LabelTy BreakLabel,
121 LabelTy ContinueLabel)
122 : Ctx(Ctx) {
123#ifndef NDEBUG
124 for (const LabelInfo &LI : Ctx->LabelInfoStack)
125 assert(LI.Name != Name);
126#endif
127
128 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel, ContinueLabel,
129 /*DefaultLabel=*/std::nullopt,
130 Ctx->VarScope);
131 }
132
133 ~LoopScope() { this->Ctx->LabelInfoStack.pop_back(); }
134
135private:
137};
138
139// Sets the context for a switch scope, mapping labels.
140template <class Emitter> class SwitchScope final {
141public:
146
147 SwitchScope(Compiler<Emitter> *Ctx, const Stmt *Name, CaseMap &&CaseLabels,
148 LabelTy BreakLabel, OptLabelTy DefaultLabel)
149 : Ctx(Ctx), OldCaseLabels(std::move(this->Ctx->CaseLabels)) {
150#ifndef NDEBUG
151 for (const LabelInfo &LI : Ctx->LabelInfoStack)
152 assert(LI.Name != Name);
153#endif
154
155 this->Ctx->CaseLabels = std::move(CaseLabels);
156 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel,
157 /*ContinueLabel=*/std::nullopt,
158 DefaultLabel, Ctx->VarScope);
159 }
160
162 this->Ctx->CaseLabels = std::move(OldCaseLabels);
163 this->Ctx->LabelInfoStack.pop_back();
164 }
165
166private:
168 CaseMap OldCaseLabels;
169};
170
171template <class Emitter> class StmtExprScope final {
172public:
173 StmtExprScope(Compiler<Emitter> *Ctx) : Ctx(Ctx), OldFlag(Ctx->InStmtExpr) {
174 Ctx->InStmtExpr = true;
175 }
176
177 ~StmtExprScope() { Ctx->InStmtExpr = OldFlag; }
178
179private:
181 bool OldFlag;
182};
183
184/// When generating code for e.g. implicit field initializers in constructors,
185/// we don't have anything to point to in case the initializer causes an error.
186/// In that case, we need to disable location tracking for the initializer so
187/// we later point to the call range instead.
188template <class Emitter> class LocOverrideScope final {
189public:
191 bool Enabled = true)
192 : Ctx(Ctx), OldFlag(Ctx->LocOverride), Enabled(Enabled) {
193
194 if (Enabled)
195 Ctx->LocOverride = NewValue;
196 }
197
199 if (Enabled)
200 Ctx->LocOverride = OldFlag;
201 }
202
203private:
205 std::optional<SourceInfo> OldFlag;
206 bool Enabled;
207};
208
209} // namespace interp
210} // namespace clang
211
212template <class Emitter>
214 const Expr *SubExpr = E->getSubExpr();
215
216 if (DiscardResult)
217 return this->delegate(SubExpr);
218
219 switch (E->getCastKind()) {
220 case CK_LValueToRValue: {
221 if (ToLValue && E->getType()->isPointerType())
222 return this->delegate(SubExpr);
223
224 if (SubExpr->getType().isVolatileQualified())
225 return this->emitInvalidCast(CastKind::Volatile, /*Fatal=*/true, E);
226
227 OptPrimType SubExprT = classify(SubExpr->getType());
228 // Try to load the value directly. This is purely a performance
229 // optimization.
230 if (SubExprT) {
231 if (const auto *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
232 const ValueDecl *D = DRE->getDecl();
233 bool IsReference = D->getType()->isReferenceType();
234
235 if (!IsReference) {
237 if (auto GlobalIndex = P.getGlobal(D))
238 return this->emitGetGlobal(*SubExprT, *GlobalIndex, E);
239 } else if (auto It = Locals.find(D); It != Locals.end()) {
240 return this->emitGetLocal(*SubExprT, It->second.Offset, E);
241 } else if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
242 if (auto It = this->Params.find(PVD); It != this->Params.end()) {
243 return this->emitGetParam(*SubExprT, It->second.Index, E);
244 }
245 }
246 }
247 }
248 }
249
250 // Prepare storage for the result.
251 if (!Initializing && !SubExprT) {
252 UnsignedOrNone LocalIndex = allocateLocal(SubExpr);
253 if (!LocalIndex)
254 return false;
255 if (!this->emitGetPtrLocal(*LocalIndex, E))
256 return false;
257 }
258
259 if (!this->visit(SubExpr))
260 return false;
261
262 if (SubExprT)
263 return this->emitLoadPop(*SubExprT, E);
264
265 // If the subexpr type is not primitive, we need to perform a copy here.
266 // This happens for example in C when dereferencing a pointer of struct
267 // type.
268 return this->emitMemcpy(E);
269 }
270
271 case CK_DerivedToBaseMemberPointer: {
272 if (E->containsErrors())
273 return false;
274 assert(classifyPrim(E) == PT_MemberPtr);
275 assert(classifyPrim(SubExpr) == PT_MemberPtr);
276
277 if (!this->delegate(SubExpr))
278 return false;
279
280 const CXXRecordDecl *CurDecl = SubExpr->getType()
282 ->getMostRecentCXXRecordDecl();
283 for (const CXXBaseSpecifier *B : E->path()) {
284 const CXXRecordDecl *ToDecl = B->getType()->getAsCXXRecordDecl();
285 unsigned DerivedOffset = Ctx.collectBaseOffset(ToDecl, CurDecl);
286
287 if (!this->emitCastMemberPtrBasePop(DerivedOffset, ToDecl, E))
288 return false;
289 CurDecl = ToDecl;
290 }
291
292 return true;
293 }
294
295 case CK_BaseToDerivedMemberPointer: {
296 if (E->containsErrors())
297 return false;
298 assert(classifyPrim(E) == PT_MemberPtr);
299 assert(classifyPrim(SubExpr) == PT_MemberPtr);
300
301 if (!this->delegate(SubExpr))
302 return false;
303
304 const CXXRecordDecl *CurDecl = SubExpr->getType()
306 ->getMostRecentCXXRecordDecl();
307 // Base-to-derived member pointer casts store the path in derived-to-base
308 // order, so iterate backwards. The CXXBaseSpecifier also provides us with
309 // the wrong end of the derived->base arc, so stagger the path by one class.
310 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
311 for (ReverseIter PathI(E->path_end() - 1), PathE(E->path_begin());
312 PathI != PathE; ++PathI) {
313 const CXXRecordDecl *ToDecl = (*PathI)->getType()->getAsCXXRecordDecl();
314 unsigned DerivedOffset = Ctx.collectBaseOffset(CurDecl, ToDecl);
315
316 if (!this->emitCastMemberPtrDerivedPop(-DerivedOffset, ToDecl, E))
317 return false;
318 CurDecl = ToDecl;
319 }
320
321 const CXXRecordDecl *ToDecl =
322 E->getType()->castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
323 assert(ToDecl != CurDecl);
324 unsigned DerivedOffset = Ctx.collectBaseOffset(CurDecl, ToDecl);
325
326 if (!this->emitCastMemberPtrDerivedPop(-DerivedOffset, ToDecl, E))
327 return false;
328
329 return true;
330 }
331
332 case CK_UncheckedDerivedToBase:
333 case CK_DerivedToBase: {
334 if (!this->delegate(SubExpr))
335 return false;
336
337 const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
338 if (const auto *PT = dyn_cast<PointerType>(Ty))
339 return PT->getPointeeType()->getAsCXXRecordDecl();
340 return Ty->getAsCXXRecordDecl();
341 };
342
343 // FIXME: We can express a series of non-virtual casts as a single
344 // GetPtrBasePop op.
345 QualType CurType = SubExpr->getType();
346 for (const CXXBaseSpecifier *B : E->path()) {
347 if (B->isVirtual()) {
348 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), E))
349 return false;
350 CurType = B->getType();
351 } else {
352 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
353 if (!this->emitGetPtrBasePop(
354 DerivedOffset, /*NullOK=*/E->getType()->isPointerType(), E))
355 return false;
356 CurType = B->getType();
357 }
358 }
359
360 return true;
361 }
362
363 case CK_BaseToDerived: {
364 if (!this->delegate(SubExpr))
365 return false;
366 unsigned DerivedOffset =
367 collectBaseOffset(SubExpr->getType(), E->getType());
368
369 const Type *TargetType = E->getType().getTypePtr();
370 if (TargetType->isPointerOrReferenceType())
371 TargetType = TargetType->getPointeeType().getTypePtr();
372 return this->emitGetPtrDerivedPop(DerivedOffset,
373 /*NullOK=*/E->getType()->isPointerType(),
374 TargetType, E);
375 }
376
377 case CK_FloatingCast: {
378 // HLSL uses CK_FloatingCast to cast between vectors.
379 if (!SubExpr->getType()->isFloatingType() ||
380 !E->getType()->isFloatingType())
381 return false;
382 if (!this->visit(SubExpr))
383 return false;
384 const auto *TargetSemantics = &Ctx.getFloatSemantics(E->getType());
385 return this->emitCastFP(TargetSemantics, getRoundingMode(E), E);
386 }
387
388 case CK_IntegralToFloating: {
389 if (!E->getType()->isRealFloatingType())
390 return false;
391 if (!this->visit(SubExpr))
392 return false;
393 const auto *TargetSemantics = &Ctx.getFloatSemantics(E->getType());
394 return this->emitCastIntegralFloating(classifyPrim(SubExpr),
395 TargetSemantics, getFPOptions(E), E);
396 }
397
398 case CK_FloatingToBoolean: {
399 if (!SubExpr->getType()->isRealFloatingType() ||
400 !E->getType()->isBooleanType())
401 return false;
402 if (const auto *FL = dyn_cast<FloatingLiteral>(SubExpr))
403 return this->emitConstBool(FL->getValue().isNonZero(), E);
404 if (!this->visit(SubExpr))
405 return false;
406 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
407 }
408
409 case CK_FloatingToIntegral: {
411 return false;
412 if (!this->visit(SubExpr))
413 return false;
414 PrimType ToT = classifyPrim(E);
415 if (ToT == PT_IntAP)
416 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(E->getType()),
417 getFPOptions(E), E);
418 if (ToT == PT_IntAPS)
419 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(E->getType()),
420 getFPOptions(E), E);
421
422 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
423 }
424
425 case CK_NullToPointer:
426 case CK_NullToMemberPointer: {
427 if (!this->discard(SubExpr))
428 return false;
429 const Descriptor *Desc = nullptr;
430 const QualType PointeeType = E->getType()->getPointeeType();
431 if (!PointeeType.isNull()) {
432 if (OptPrimType T = classify(PointeeType))
433 Desc = P.createDescriptor(SubExpr, *T);
434 else
435 Desc = P.createDescriptor(SubExpr, PointeeType.getTypePtr(),
436 std::nullopt, /*IsConst=*/true);
437 }
438
439 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(E->getType());
440 return this->emitNull(classifyPrim(E->getType()), Val, Desc, E);
441 }
442
443 case CK_PointerToIntegral: {
444 if (!this->visit(SubExpr))
445 return false;
446
447 // If SubExpr doesn't result in a pointer, make it one.
448 if (PrimType FromT = classifyPrim(SubExpr->getType()); FromT != PT_Ptr) {
449 assert(isPtrType(FromT));
450 if (!this->emitDecayPtr(FromT, PT_Ptr, E))
451 return false;
452 }
453
454 PrimType T = classifyPrim(E->getType());
455 if (T == PT_IntAP)
456 return this->emitCastPointerIntegralAP(Ctx.getBitWidth(E->getType()), E);
457 if (T == PT_IntAPS)
458 return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(E->getType()), E);
459 return this->emitCastPointerIntegral(T, E);
460 }
461
462 case CK_ArrayToPointerDecay: {
463 if (!this->visit(SubExpr))
464 return false;
465 return this->emitArrayDecay(E);
466 }
467
468 case CK_IntegralToPointer: {
469 QualType IntType = SubExpr->getType();
470 assert(IntType->isIntegralOrEnumerationType());
471 if (!this->visit(SubExpr))
472 return false;
473 // FIXME: I think the discard is wrong since the int->ptr cast might cause a
474 // diagnostic.
475 PrimType T = classifyPrim(IntType);
476 QualType PtrType = E->getType();
477 const Descriptor *Desc;
478 if (OptPrimType T = classify(PtrType->getPointeeType()))
479 Desc = P.createDescriptor(SubExpr, *T);
480 else if (PtrType->getPointeeType()->isVoidType())
481 Desc = nullptr;
482 else
483 Desc = P.createDescriptor(E, PtrType->getPointeeType().getTypePtr(),
484 Descriptor::InlineDescMD, /*IsConst=*/true);
485
486 if (!this->emitGetIntPtr(T, Desc, E))
487 return false;
488
489 PrimType DestPtrT = classifyPrim(PtrType);
490 if (DestPtrT == PT_Ptr)
491 return true;
492
493 // In case we're converting the integer to a non-Pointer.
494 return this->emitDecayPtr(PT_Ptr, DestPtrT, E);
495 }
496
497 case CK_AtomicToNonAtomic:
498 case CK_ConstructorConversion:
499 case CK_FunctionToPointerDecay:
500 case CK_NonAtomicToAtomic:
501 case CK_NoOp:
502 case CK_UserDefinedConversion:
503 case CK_AddressSpaceConversion:
504 case CK_CPointerToObjCPointerCast:
505 return this->delegate(SubExpr);
506
507 case CK_BitCast: {
508 if (E->containsErrors())
509 return false;
510 QualType ETy = E->getType();
511 // Reject bitcasts to atomic types.
512 if (ETy->isAtomicType()) {
513 if (!this->discard(SubExpr))
514 return false;
515 return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, E);
516 }
517 QualType SubExprTy = SubExpr->getType();
518 OptPrimType FromT = classify(SubExprTy);
519 // Casts from integer/vector to vector.
520 if (E->getType()->isVectorType())
521 return this->emitBuiltinBitCast(E);
522
523 OptPrimType ToT = classify(E->getType());
524 if (!FromT || !ToT)
525 return false;
526
527 assert(isPtrType(*FromT));
528 assert(isPtrType(*ToT));
529 bool SrcIsVoidPtr = SubExprTy->isVoidPointerType();
530 if (FromT == ToT) {
531 if (E->getType()->isVoidPointerType() &&
532 !SubExprTy->isFunctionPointerType()) {
533 return this->delegate(SubExpr);
534 }
535
536 if (!this->visit(SubExpr))
537 return false;
538 if (!this->emitCheckBitCast(ETy->getPointeeType().getTypePtr(),
539 SrcIsVoidPtr, E))
540 return false;
541
542 if (E->getType()->isFunctionPointerType() ||
543 SubExprTy->isFunctionPointerType()) {
544 return this->emitFnPtrCast(E);
545 }
546 if (FromT == PT_Ptr)
547 return this->emitPtrPtrCast(SubExprTy->isVoidPointerType(), E);
548 return true;
549 }
550
551 if (!this->visit(SubExpr))
552 return false;
553 return this->emitDecayPtr(*FromT, *ToT, E);
554 }
555 case CK_IntegralToBoolean:
556 case CK_FixedPointToBoolean: {
557 // HLSL uses this to cast to one-element vectors.
558 OptPrimType FromT = classify(SubExpr->getType());
559 if (!FromT)
560 return false;
561
562 if (const auto *IL = dyn_cast<IntegerLiteral>(SubExpr))
563 return this->emitConst(IL->getValue(), E);
564 if (!this->visit(SubExpr))
565 return false;
566 return this->emitCast(*FromT, classifyPrim(E), E);
567 }
568
569 case CK_BooleanToSignedIntegral:
570 case CK_IntegralCast: {
571 OptPrimType FromT = classify(SubExpr->getType());
572 OptPrimType ToT = classify(E->getType());
573 if (!FromT || !ToT)
574 return false;
575
576 // Try to emit a casted known constant value directly.
577 if (const auto *IL = dyn_cast<IntegerLiteral>(SubExpr)) {
578 if (ToT != PT_IntAP && ToT != PT_IntAPS && FromT != PT_IntAP &&
579 FromT != PT_IntAPS && !E->getType()->isEnumeralType())
580 return this->emitConst(APSInt(IL->getValue(), !isSignedType(*FromT)),
581 E);
582 if (!this->emitConst(IL->getValue(), SubExpr))
583 return false;
584 } else {
585 if (!this->visit(SubExpr))
586 return false;
587 }
588
589 // Possibly diagnose casts to enum types if the target type does not
590 // have a fixed size.
591 if (Ctx.getLangOpts().CPlusPlus && E->getType()->isEnumeralType()) {
592 const auto *ED = E->getType()->castAsEnumDecl();
593 if (!ED->isFixed()) {
594 if (!this->emitCheckEnumValue(*FromT, ED, E))
595 return false;
596 }
597 }
598
599 if (ToT == PT_IntAP) {
600 if (!this->emitCastAP(*FromT, Ctx.getBitWidth(E->getType()), E))
601 return false;
602 } else if (ToT == PT_IntAPS) {
603 if (!this->emitCastAPS(*FromT, Ctx.getBitWidth(E->getType()), E))
604 return false;
605 } else {
606 if (FromT == ToT)
607 return true;
608 if (!this->emitCast(*FromT, *ToT, E))
609 return false;
610 }
611 if (E->getCastKind() == CK_BooleanToSignedIntegral)
612 return this->emitNeg(*ToT, E);
613 return true;
614 }
615
616 case CK_PointerToBoolean:
617 case CK_MemberPointerToBoolean: {
618 PrimType PtrT = classifyPrim(SubExpr->getType());
619
620 if (!this->visit(SubExpr))
621 return false;
622 return this->emitIsNonNull(PtrT, E);
623 }
624
625 case CK_IntegralComplexToBoolean:
626 case CK_FloatingComplexToBoolean: {
627 if (!this->visit(SubExpr))
628 return false;
629 return this->emitComplexBoolCast(SubExpr);
630 }
631
632 case CK_IntegralComplexToReal:
633 case CK_FloatingComplexToReal:
634 return this->emitComplexReal(SubExpr);
635
636 case CK_IntegralRealToComplex:
637 case CK_FloatingRealToComplex: {
638 // We're creating a complex value here, so we need to
639 // allocate storage for it.
640 if (!Initializing) {
641 UnsignedOrNone LocalIndex = allocateTemporary(E);
642 if (!LocalIndex)
643 return false;
644 if (!this->emitGetPtrLocal(*LocalIndex, E))
645 return false;
646 }
647
648 PrimType T = classifyPrim(SubExpr->getType());
649 // Init the complex value to {SubExpr, 0}.
650 if (!this->visitArrayElemInit(0, SubExpr, T))
651 return false;
652 // Zero-init the second element.
653 if (!this->visitZeroInitializer(T, SubExpr->getType(), SubExpr))
654 return false;
655 return this->emitInitElem(T, 1, SubExpr);
656 }
657
658 case CK_IntegralComplexCast:
659 case CK_FloatingComplexCast:
660 case CK_IntegralComplexToFloatingComplex:
661 case CK_FloatingComplexToIntegralComplex: {
662 assert(E->getType()->isAnyComplexType());
663 assert(SubExpr->getType()->isAnyComplexType());
664 if (!Initializing) {
665 UnsignedOrNone LocalIndex = allocateLocal(E);
666 if (!LocalIndex)
667 return false;
668 if (!this->emitGetPtrLocal(*LocalIndex, E))
669 return false;
670 }
671
672 // Location for the SubExpr.
673 // Since SubExpr is of complex type, visiting it results in a pointer
674 // anyway, so we just create a temporary pointer variable.
675 unsigned SubExprOffset =
676 allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
677 if (!this->visit(SubExpr))
678 return false;
679 if (!this->emitSetLocal(PT_Ptr, SubExprOffset, E))
680 return false;
681
682 PrimType SourceElemT = classifyComplexElementType(SubExpr->getType());
683 QualType DestElemType =
684 E->getType()->getAs<ComplexType>()->getElementType();
685 PrimType DestElemT = classifyPrim(DestElemType);
686 // Cast both elements individually.
687 for (unsigned I = 0; I != 2; ++I) {
688 if (!this->emitGetLocal(PT_Ptr, SubExprOffset, E))
689 return false;
690 if (!this->emitArrayElemPop(SourceElemT, I, E))
691 return false;
692
693 // Do the cast.
694 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, E))
695 return false;
696
697 // Save the value.
698 if (!this->emitInitElem(DestElemT, I, E))
699 return false;
700 }
701 return true;
702 }
703
704 case CK_VectorSplat: {
705 assert(!canClassify(E->getType()));
706 assert(E->getType()->isVectorType());
707
708 if (!canClassify(SubExpr->getType()))
709 return false;
710
711 if (!Initializing) {
712 UnsignedOrNone LocalIndex = allocateLocal(E);
713 if (!LocalIndex)
714 return false;
715 if (!this->emitGetPtrLocal(*LocalIndex, E))
716 return false;
717 }
718
719 const auto *VT = E->getType()->getAs<VectorType>();
720 PrimType ElemT = classifyPrim(SubExpr->getType());
721 unsigned ElemOffset =
722 allocateLocalPrimitive(SubExpr, ElemT, /*IsConst=*/true);
723
724 // Prepare a local variable for the scalar value.
725 if (!this->visit(SubExpr))
726 return false;
727 if (classifyPrim(SubExpr) == PT_Ptr && !this->emitLoadPop(ElemT, E))
728 return false;
729
730 if (!this->emitSetLocal(ElemT, ElemOffset, E))
731 return false;
732
733 for (unsigned I = 0; I != VT->getNumElements(); ++I) {
734 if (!this->emitGetLocal(ElemT, ElemOffset, E))
735 return false;
736 if (!this->emitInitElem(ElemT, I, E))
737 return false;
738 }
739
740 return true;
741 }
742
743 case CK_HLSLVectorTruncation: {
744 assert(SubExpr->getType()->isVectorType());
745 if (OptPrimType ResultT = classify(E)) {
746 assert(!DiscardResult);
747 // Result must be either a float or integer. Take the first element.
748 if (!this->visit(SubExpr))
749 return false;
750 return this->emitArrayElemPop(*ResultT, 0, E);
751 }
752 // Otherwise, this truncates from one vector type to another.
753 assert(E->getType()->isVectorType());
754
755 if (!Initializing) {
756 UnsignedOrNone LocalIndex = allocateTemporary(E);
757 if (!LocalIndex)
758 return false;
759 if (!this->emitGetPtrLocal(*LocalIndex, E))
760 return false;
761 }
762 unsigned ToSize = E->getType()->getAs<VectorType>()->getNumElements();
763 assert(SubExpr->getType()->getAs<VectorType>()->getNumElements() > ToSize);
764 if (!this->visit(SubExpr))
765 return false;
766 return this->emitCopyArray(classifyVectorElementType(E->getType()), 0, 0,
767 ToSize, E);
768 };
769
770 case CK_IntegralToFixedPoint: {
771 if (!this->visit(SubExpr))
772 return false;
773
774 auto Sem =
775 Ctx.getASTContext().getFixedPointSemantics(E->getType()).toOpaqueInt();
776 if (!this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->getType()), Sem,
777 E))
778 return false;
779 if (DiscardResult)
780 return this->emitPopFixedPoint(E);
781 return true;
782 }
783 case CK_FloatingToFixedPoint: {
784 if (!this->visit(SubExpr))
785 return false;
786
787 auto Sem =
788 Ctx.getASTContext().getFixedPointSemantics(E->getType()).toOpaqueInt();
789 if (!this->emitCastFloatingFixedPoint(Sem, E))
790 return false;
791 if (DiscardResult)
792 return this->emitPopFixedPoint(E);
793 return true;
794 }
795 case CK_FixedPointToFloating: {
796 if (!this->visit(SubExpr))
797 return false;
798 const auto *TargetSemantics = &Ctx.getFloatSemantics(E->getType());
799 if (!this->emitCastFixedPointFloating(TargetSemantics, E))
800 return false;
801 if (DiscardResult)
802 return this->emitPopFloat(E);
803 return true;
804 }
805 case CK_FixedPointToIntegral: {
806 if (!this->visit(SubExpr))
807 return false;
808 PrimType IntegralT = classifyPrim(E->getType());
809 if (!this->emitCastFixedPointIntegral(IntegralT, E))
810 return false;
811 if (DiscardResult)
812 return this->emitPop(IntegralT, E);
813 return true;
814 }
815 case CK_FixedPointCast: {
816 if (!this->visit(SubExpr))
817 return false;
818 auto Sem =
819 Ctx.getASTContext().getFixedPointSemantics(E->getType()).toOpaqueInt();
820 if (!this->emitCastFixedPoint(Sem, E))
821 return false;
822 if (DiscardResult)
823 return this->emitPopFixedPoint(E);
824 return true;
825 }
826
827 case CK_ToVoid:
828 return discard(SubExpr);
829
830 case CK_Dynamic:
831 // This initially goes through VisitCXXDynamicCastExpr, where we emit
832 // a diagnostic if appropriate.
833 return this->delegate(SubExpr);
834
835 case CK_LValueBitCast:
836 if (!this->emitInvalidCast(CastKind::ReinterpretLike, /*Fatal=*/false, E))
837 return false;
838 return this->delegate(SubExpr);
839
840 case CK_HLSLArrayRValue: {
841 // Non-decaying array rvalue cast - creates an rvalue copy of an lvalue
842 // array, similar to LValueToRValue for composite types.
843 if (!Initializing) {
844 UnsignedOrNone LocalIndex = allocateLocal(E);
845 if (!LocalIndex)
846 return false;
847 if (!this->emitGetPtrLocal(*LocalIndex, E))
848 return false;
849 }
850 if (!this->visit(SubExpr))
851 return false;
852 return this->emitMemcpy(E);
853 }
854
855 case CK_HLSLMatrixTruncation: {
856 assert(SubExpr->getType()->isConstantMatrixType());
857 if (OptPrimType ResultT = classify(E)) {
858 assert(!DiscardResult);
859 // Result must be either a float or integer. Take the first element.
860 if (!this->visit(SubExpr))
861 return false;
862 return this->emitArrayElemPop(*ResultT, 0, E);
863 }
864 // Otherwise, this truncates to a a constant matrix type.
865 assert(E->getType()->isConstantMatrixType());
866
867 if (!Initializing) {
868 UnsignedOrNone LocalIndex = allocateTemporary(E);
869 if (!LocalIndex)
870 return false;
871 if (!this->emitGetPtrLocal(*LocalIndex, E))
872 return false;
873 }
874 unsigned ToSize =
875 E->getType()->getAs<ConstantMatrixType>()->getNumElementsFlattened();
876 if (!this->visit(SubExpr))
877 return false;
878 return this->emitCopyArray(classifyMatrixElementType(SubExpr->getType()), 0,
879 0, ToSize, E);
880 }
881
882 case CK_HLSLAggregateSplatCast: {
883 // Aggregate splat cast: convert a scalar value to one of an aggregate type
884 // by replicating and casting the scalar to every element of the destination
885 // aggregate (vector, matrix, array, or struct).
886 assert(canClassify(SubExpr->getType()));
887
888 if (!Initializing) {
889 UnsignedOrNone LocalIndex = allocateLocal(E);
890 if (!LocalIndex)
891 return false;
892 if (!this->emitGetPtrLocal(*LocalIndex, E))
893 return false;
894 }
895
896 // The scalar to be splatted is stored in a local to be repeatedly loaded
897 // once for every scalar element of the destination.
898 PrimType SrcElemT = classifyPrim(SubExpr->getType());
899 unsigned SrcOffset =
900 allocateLocalPrimitive(SubExpr, SrcElemT, /*IsConst=*/true);
901
902 if (!this->visit(SubExpr))
903 return false;
904 if (!this->emitSetLocal(SrcElemT, SrcOffset, E))
905 return false;
906
907 // Recursively splat the scalar into every element of the destination.
908 return emitHLSLAggregateSplat(SrcElemT, SrcOffset, E->getType(), E);
909 }
910
911 case CK_HLSLElementwiseCast: {
912 // Elementwise cast: flatten the elements of one aggregate source type and
913 // store to a destination scalar or aggregate type of the same or fewer
914 // number of elements. Casts are inserted element-wise to convert each
915 // source scalar element to its corresponding destination scalar element.
916 QualType SrcType = SubExpr->getType();
917 QualType DestType = E->getType();
918
919 if (OptPrimType DestT = classify(DestType)) {
920 // When the destination is a scalar, we only need the first scalar
921 // element of the source.
922 unsigned SrcPtrOffset =
923 allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
924 if (!this->visit(SubExpr))
925 return false;
926 if (!this->emitSetLocal(PT_Ptr, SrcPtrOffset, E))
927 return false;
928
930 if (!emitHLSLFlattenAggregate(SrcType, SrcPtrOffset, Elements, 1, E))
931 return false;
932 if (Elements.empty())
933 return false;
934
935 const HLSLFlatElement &Src = Elements[0];
936 if (!this->emitGetLocal(Src.Type, Src.LocalOffset, E))
937 return false;
938 return this->emitPrimCast(Src.Type, *DestT, DestType, E);
939 }
940
941 if (!Initializing) {
942 UnsignedOrNone LocalIndex = allocateLocal(E);
943 if (!LocalIndex)
944 return false;
945 if (!this->emitGetPtrLocal(*LocalIndex, E))
946 return false;
947 }
948
949 unsigned SrcOffset =
950 allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
951 if (!this->visit(SubExpr))
952 return false;
953 if (!this->emitSetLocal(PT_Ptr, SrcOffset, E))
954 return false;
955
956 // Only flatten as many source elements as the destination requires.
957 unsigned ElemCount = countHLSLFlatElements(DestType);
958
960 Elements.reserve(ElemCount);
961 if (!emitHLSLFlattenAggregate(SrcType, SrcOffset, Elements, ElemCount, E))
962 return false;
963
964 // Sema is expected to reject an elementwise cast whose source has fewer
965 // scalar elements than the destination.
966 assert(Elements.size() == ElemCount &&
967 "Source type has fewer scalar elements than the destination type");
968
969 return emitHLSLConstructAggregate(DestType, Elements, E);
970 }
971
972 case CK_ToUnion: {
973 const FieldDecl *UnionField = E->getTargetUnionField();
974 const Record *R = this->getRecord(E->getType());
975 assert(R);
976 const Record::Field *RF = R->getField(UnionField);
977 QualType FieldType = RF->Decl->getType();
978
979 if (OptPrimType PT = classify(FieldType)) {
980 if (!this->visit(SubExpr))
981 return false;
982 if (RF->isBitField())
983 return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(),
984 E);
985 return this->emitInitFieldActivate(*PT, RF->Offset, E);
986 }
987
988 if (!this->emitGetPtrField(RF->Offset, E))
989 return false;
990 if (!this->emitActivate(E))
991 return false;
992 return this->visitInitializerPop(SubExpr);
993 }
994
995 default:
996 return this->emitInvalid(E);
997 }
998 llvm_unreachable("Unhandled clang::CastKind enum");
999}
1000
1001template <class Emitter>
1003 return this->emitBuiltinBitCast(E);
1004}
1005
1006template <class Emitter>
1008 if (DiscardResult)
1009 return true;
1010
1011 return this->emitConst(LE->getValue(), LE);
1012}
1013
1014template <class Emitter>
1016 if (DiscardResult)
1017 return true;
1018
1019 APFloat F = E->getValue();
1020 return this->emitFloat(F, E);
1021}
1022
1023template <class Emitter>
1025 assert(E->getType()->isAnyComplexType());
1026 if (DiscardResult)
1027 return true;
1028
1029 if (!Initializing) {
1030 UnsignedOrNone LocalIndex = allocateTemporary(E);
1031 if (!LocalIndex)
1032 return false;
1033 if (!this->emitGetPtrLocal(*LocalIndex, E))
1034 return false;
1035 }
1036
1037 const Expr *SubExpr = E->getSubExpr();
1038 PrimType SubExprT = classifyPrim(SubExpr->getType());
1039
1040 if (!this->visitZeroInitializer(SubExprT, SubExpr->getType(), SubExpr))
1041 return false;
1042 if (!this->emitInitElem(SubExprT, 0, SubExpr))
1043 return false;
1044 return this->visitArrayElemInit(1, SubExpr, SubExprT);
1045}
1046
1047template <class Emitter>
1049 assert(E->getType()->isFixedPointType());
1050 assert(classifyPrim(E) == PT_FixedPoint);
1051
1052 if (DiscardResult)
1053 return true;
1054
1055 auto Sem = Ctx.getASTContext().getFixedPointSemantics(E->getType());
1056 APInt Value = E->getValue();
1057 return this->emitConstFixedPoint(FixedPoint(Value, Sem), E);
1058}
1059
1060template <class Emitter>
1062 return this->delegate(E->getSubExpr());
1063}
1064
1065template <class Emitter>
1067 // Need short-circuiting for these.
1068 if (E->isLogicalOp() && !E->getType()->isVectorType())
1069 return this->VisitLogicalBinOp(E);
1070
1071 const Expr *LHS = E->getLHS();
1072 const Expr *RHS = E->getRHS();
1073
1074 // Handle comma operators. Just discard the LHS
1075 // and delegate to RHS.
1076 if (E->isCommaOp()) {
1077 if (!this->discard(LHS))
1078 return false;
1079 if (RHS->getType()->isVoidType())
1080 return this->discard(RHS);
1081
1082 return this->delegate(RHS);
1083 }
1084
1085 if (E->getType()->isAnyComplexType())
1086 return this->VisitComplexBinOp(E);
1087 if (E->getType()->isVectorType())
1088 return this->VisitVectorBinOp(E);
1089 if ((LHS->getType()->isAnyComplexType() ||
1090 RHS->getType()->isAnyComplexType()) &&
1091 E->isComparisonOp())
1092 return this->emitComplexComparison(LHS, RHS, E);
1093 if (LHS->getType()->isFixedPointType() || RHS->getType()->isFixedPointType())
1094 return this->VisitFixedPointBinOp(E);
1095
1096 if (E->isPtrMemOp()) {
1097 if (E->containsErrors())
1098 return false;
1099
1100 if (!this->visit(LHS))
1101 return false;
1102
1103 if (!this->visit(RHS))
1104 return false;
1105
1106 if (!this->emitToMemberPtr(E))
1107 return false;
1108
1109 if (classifyPrim(E) == PT_MemberPtr)
1110 return true;
1111
1112 if (!this->emitCastMemberPtrPtr(E))
1113 return false;
1114 return DiscardResult ? this->emitPopPtr(E) : true;
1115 }
1116
1117 // Typecheck the args.
1118 OptPrimType LT = classify(LHS);
1119 OptPrimType RT = classify(RHS);
1120 OptPrimType T = classify(E->getType());
1121
1122 // Special case for C++'s three-way/spaceship operator <=>, which
1123 // returns a std::{strong,weak,partial}_ordering (which is a class, so doesn't
1124 // have a PrimType).
1125 if (!T && E->getOpcode() == BO_Cmp) {
1126 if (DiscardResult)
1127 return true;
1128 const ComparisonCategoryInfo *CmpInfo =
1129 Ctx.getASTContext().CompCategories.lookupInfoForType(E->getType());
1130 assert(CmpInfo);
1131
1132 // We need a temporary variable holding our return value.
1133 if (!Initializing) {
1134 UnsignedOrNone ResultIndex = this->allocateLocal(E);
1135 if (!this->emitGetPtrLocal(*ResultIndex, E))
1136 return false;
1137 }
1138
1139 if (!visit(LHS) || !visit(RHS))
1140 return false;
1141
1142 return this->emitCMP3(*LT, CmpInfo, E);
1143 }
1144
1145 if (!LT || !RT || !T)
1146 return false;
1147
1148 // Pointer arithmetic special case.
1149 if (E->getOpcode() == BO_Add || E->getOpcode() == BO_Sub) {
1150 if (isPtrType(*T) || (isPtrType(*LT) && isPtrType(*RT)))
1151 return this->VisitPointerArithBinOp(E);
1152 }
1153
1154 if (E->getOpcode() == BO_Assign)
1155 return this->visitAssignment(LHS, RHS, E);
1156
1157 if (!visit(LHS) || !visit(RHS))
1158 return false;
1159
1160 // For languages such as C, cast the result of one
1161 // of our comparision opcodes to T (which is usually int).
1162 auto MaybeCastToBool = [this, T, E](bool Result) {
1163 if (!Result)
1164 return false;
1165 if (DiscardResult)
1166 return this->emitPopBool(E);
1167 if (T != PT_Bool)
1168 return this->emitCast(PT_Bool, *T, E);
1169 return true;
1170 };
1171
1172 auto Discard = [this, T, E](bool Result) {
1173 if (!Result)
1174 return false;
1175 return DiscardResult ? this->emitPop(*T, E) : true;
1176 };
1177
1178 switch (E->getOpcode()) {
1179 case BO_EQ:
1180 return MaybeCastToBool(this->emitEQ(*LT, E));
1181 case BO_NE:
1182 return MaybeCastToBool(this->emitNE(*LT, E));
1183 case BO_LT:
1184 return MaybeCastToBool(this->emitLT(*LT, E));
1185 case BO_LE:
1186 return MaybeCastToBool(this->emitLE(*LT, E));
1187 case BO_GT:
1188 return MaybeCastToBool(this->emitGT(*LT, E));
1189 case BO_GE:
1190 return MaybeCastToBool(this->emitGE(*LT, E));
1191 case BO_Sub:
1192 if (E->getType()->isFloatingType())
1193 return Discard(this->emitSubf(getFPOptions(E), E));
1194 return Discard(this->emitSub(*T, E));
1195 case BO_Add:
1196 if (E->getType()->isFloatingType())
1197 return Discard(this->emitAddf(getFPOptions(E), E));
1198 return Discard(this->emitAdd(*T, E));
1199 case BO_Mul:
1200 if (E->getType()->isFloatingType())
1201 return Discard(this->emitMulf(getFPOptions(E), E));
1202 return Discard(this->emitMul(*T, E));
1203 case BO_Rem:
1204 return Discard(this->emitRem(*T, E));
1205 case BO_Div:
1206 if (E->getType()->isFloatingType())
1207 return Discard(this->emitDivf(getFPOptions(E), E));
1208 return Discard(this->emitDiv(*T, E));
1209 case BO_And:
1210 return Discard(this->emitBitAnd(*T, E));
1211 case BO_Or:
1212 return Discard(this->emitBitOr(*T, E));
1213 case BO_Shl:
1214 return Discard(this->emitShl(*LT, *RT, E));
1215 case BO_Shr:
1216 return Discard(this->emitShr(*LT, *RT, E));
1217 case BO_Xor:
1218 return Discard(this->emitBitXor(*T, E));
1219 case BO_LOr:
1220 case BO_LAnd:
1221 llvm_unreachable("Already handled earlier");
1222 default:
1223 return false;
1224 }
1225
1226 llvm_unreachable("Unhandled binary op");
1227}
1228
1229/// Perform addition/subtraction of a pointer and an integer or
1230/// subtraction of two pointers.
1231template <class Emitter>
1233 BinaryOperatorKind Op = E->getOpcode();
1234 const Expr *LHS = E->getLHS();
1235 const Expr *RHS = E->getRHS();
1236
1237 if ((Op != BO_Add && Op != BO_Sub) ||
1238 (!LHS->getType()->isPointerType() && !RHS->getType()->isPointerType()))
1239 return false;
1240
1241 OptPrimType LT = classify(LHS);
1242 OptPrimType RT = classify(RHS);
1243
1244 if (!LT || !RT)
1245 return false;
1246
1247 // Visit the given pointer expression and optionally convert to a PT_Ptr.
1248 auto visitAsPointer = [&](const Expr *E, PrimType T) -> bool {
1249 if (!this->visit(E))
1250 return false;
1251 if (T != PT_Ptr)
1252 return this->emitDecayPtr(T, PT_Ptr, E);
1253 return true;
1254 };
1255
1256 if (LHS->getType()->isPointerType() && RHS->getType()->isPointerType()) {
1257 if (Op != BO_Sub)
1258 return false;
1259
1260 assert(E->getType()->isIntegerType());
1261 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *LT))
1262 return false;
1263
1264 QualType ElemType = LHS->getType()->getPointeeType();
1265 CharUnits ElemTypeSize;
1266 if (ElemType->isVoidType() || ElemType->isFunctionType())
1267 ElemTypeSize = CharUnits::One();
1268 else
1269 ElemTypeSize = Ctx.getASTContext().getTypeSizeInChars(ElemType);
1270
1271 PrimType IntT = classifyPrim(E->getType());
1272 if (!this->emitSubPtr(IntT, ElemTypeSize.isZero(), E))
1273 return false;
1274 return DiscardResult ? this->emitPop(IntT, E) : true;
1275 }
1276
1277 PrimType OffsetType;
1278 if (LHS->getType()->isIntegerType()) {
1279 if (!visitAsPointer(RHS, *RT))
1280 return false;
1281 if (!this->visit(LHS))
1282 return false;
1283 OffsetType = *LT;
1284 } else if (RHS->getType()->isIntegerType()) {
1285 if (!visitAsPointer(LHS, *LT))
1286 return false;
1287 if (!this->visit(RHS))
1288 return false;
1289 OffsetType = *RT;
1290 } else {
1291 return false;
1292 }
1293
1294 // Do the operation and optionally transform to
1295 // result pointer type.
1296 switch (Op) {
1297 case BO_Add:
1298 if (!this->emitAddOffset(OffsetType, E))
1299 return false;
1300 break;
1301 case BO_Sub:
1302 if (!this->emitSubOffset(OffsetType, E))
1303 return false;
1304 break;
1305 default:
1306 return false;
1307 }
1308
1309 if (classifyPrim(E) != PT_Ptr) {
1310 if (!this->emitDecayPtr(PT_Ptr, classifyPrim(E), E))
1311 return false;
1312 }
1313
1314 if (DiscardResult)
1315 return this->emitPop(classifyPrim(E), E);
1316 return true;
1317}
1318
1319template <class Emitter>
1321 assert(E->isLogicalOp());
1322 BinaryOperatorKind Op = E->getOpcode();
1323 const Expr *LHS = E->getLHS();
1324 const Expr *RHS = E->getRHS();
1325 OptPrimType T = classify(E->getType());
1326
1327 if (Op == BO_LOr) {
1328 // Logical OR. Visit LHS and only evaluate RHS if LHS was FALSE.
1329 LabelTy LabelTrue = this->getLabel();
1330 LabelTy LabelEnd = this->getLabel();
1331
1332 if (!this->visitBool(LHS))
1333 return false;
1334 if (!this->jumpTrue(LabelTrue, E))
1335 return false;
1336
1337 if (!this->visitBool(RHS))
1338 return false;
1339 if (!this->jump(LabelEnd, E))
1340 return false;
1341
1342 this->emitLabel(LabelTrue);
1343 this->emitConstBool(true, E);
1344 this->fallthrough(LabelEnd);
1345 this->emitLabel(LabelEnd);
1346
1347 } else {
1348 assert(Op == BO_LAnd);
1349 // Logical AND.
1350 // Visit LHS. Only visit RHS if LHS was TRUE.
1351 LabelTy LabelFalse = this->getLabel();
1352 LabelTy LabelEnd = this->getLabel();
1353
1354 if (!this->visitBool(LHS))
1355 return false;
1356 if (!this->jumpFalse(LabelFalse, E))
1357 return false;
1358
1359 if (!this->visitBool(RHS))
1360 return false;
1361 if (!this->jump(LabelEnd, E))
1362 return false;
1363
1364 this->emitLabel(LabelFalse);
1365 this->emitConstBool(false, E);
1366 this->fallthrough(LabelEnd);
1367 this->emitLabel(LabelEnd);
1368 }
1369
1370 if (DiscardResult)
1371 return this->emitPopBool(E);
1372
1373 // For C, cast back to integer type.
1374 assert(T);
1375 if (T != PT_Bool)
1376 return this->emitCast(PT_Bool, *T, E);
1377 return true;
1378}
1379
1380template <class Emitter>
1382 // Prepare storage for result.
1383 if (!Initializing) {
1384 UnsignedOrNone LocalIndex = allocateTemporary(E);
1385 if (!LocalIndex)
1386 return false;
1387 if (!this->emitGetPtrLocal(*LocalIndex, E))
1388 return false;
1389 }
1390
1391 // Both LHS and RHS might _not_ be of complex type, but one of them
1392 // needs to be.
1393 const Expr *LHS = E->getLHS();
1394 const Expr *RHS = E->getRHS();
1395
1396 PrimType ResultElemT = this->classifyComplexElementType(E->getType());
1397 unsigned ResultOffset = ~0u;
1398 if (!DiscardResult)
1399 ResultOffset = this->allocateLocalPrimitive(E, PT_Ptr, /*IsConst=*/true);
1400
1401 // Save result pointer in ResultOffset
1402 if (!this->DiscardResult) {
1403 if (!this->emitDupPtr(E))
1404 return false;
1405 if (!this->emitSetLocal(PT_Ptr, ResultOffset, E))
1406 return false;
1407 }
1408 QualType LHSType = LHS->getType();
1409 if (const auto *AT = LHSType->getAs<AtomicType>())
1410 LHSType = AT->getValueType();
1411 QualType RHSType = RHS->getType();
1412 if (const auto *AT = RHSType->getAs<AtomicType>())
1413 RHSType = AT->getValueType();
1414
1415 bool LHSIsComplex = LHSType->isAnyComplexType();
1416 unsigned LHSOffset;
1417 bool RHSIsComplex = RHSType->isAnyComplexType();
1418
1419 // For ComplexComplex Mul, we have special ops to make their implementation
1420 // easier.
1421 BinaryOperatorKind Op = E->getOpcode();
1422 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1423 assert(classifyPrim(LHSType->getAs<ComplexType>()->getElementType()) ==
1425 PrimType ElemT =
1427 if (!this->visit(LHS))
1428 return false;
1429 if (!this->visit(RHS))
1430 return false;
1431 if (!this->emitMulc(ElemT, E))
1432 return false;
1433 if (DiscardResult)
1434 return this->emitPopPtr(E);
1435 return true;
1436 }
1437
1438 if (Op == BO_Div && RHSIsComplex) {
1439 QualType ElemQT = RHSType->getAs<ComplexType>()->getElementType();
1440 PrimType ElemT = classifyPrim(ElemQT);
1441 // If the LHS is not complex, we still need to do the full complex
1442 // division, so just stub create a complex value and stub it out with
1443 // the LHS and a zero.
1444
1445 if (!LHSIsComplex) {
1446 // This is using the RHS type for the fake-complex LHS.
1447 UnsignedOrNone LocalIndex = allocateTemporary(RHS);
1448 if (!LocalIndex)
1449 return false;
1450 LHSOffset = *LocalIndex;
1451
1452 if (!this->emitGetPtrLocal(LHSOffset, E))
1453 return false;
1454
1455 if (!this->visit(LHS))
1456 return false;
1457 // real is LHS
1458 if (!this->emitInitElem(ElemT, 0, E))
1459 return false;
1460 // imag is zero
1461 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1462 return false;
1463 if (!this->emitInitElem(ElemT, 1, E))
1464 return false;
1465 } else {
1466 if (!this->visit(LHS))
1467 return false;
1468 }
1469
1470 if (!this->visit(RHS))
1471 return false;
1472 if (!this->emitDivc(ElemT, E))
1473 return false;
1474 if (DiscardResult)
1475 return this->emitPopPtr(E);
1476 return true;
1477 }
1478
1479 // Evaluate LHS and save value to LHSOffset.
1480 if (LHSType->isAnyComplexType()) {
1481 LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true);
1482 if (!this->visit(LHS))
1483 return false;
1484 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
1485 return false;
1486 } else {
1487 PrimType LHST = classifyPrim(LHSType);
1488 LHSOffset = this->allocateLocalPrimitive(LHS, LHST, /*IsConst=*/true);
1489 if (!this->visit(LHS))
1490 return false;
1491 if (!this->emitSetLocal(LHST, LHSOffset, E))
1492 return false;
1493 }
1494
1495 // Same with RHS.
1496 unsigned RHSOffset;
1497 if (RHSType->isAnyComplexType()) {
1498 RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, /*IsConst=*/true);
1499 if (!this->visit(RHS))
1500 return false;
1501 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
1502 return false;
1503 } else {
1504 PrimType RHST = classifyPrim(RHSType);
1505 RHSOffset = this->allocateLocalPrimitive(RHS, RHST, /*IsConst=*/true);
1506 if (!this->visit(RHS))
1507 return false;
1508 if (!this->emitSetLocal(RHST, RHSOffset, E))
1509 return false;
1510 }
1511
1512 // For both LHS and RHS, either load the value from the complex pointer, or
1513 // directly from the local variable. For index 1 (i.e. the imaginary part),
1514 // just load 0 and do the operation anyway.
1515 auto loadComplexValue = [this](bool IsComplex, bool LoadZero,
1516 unsigned ElemIndex, unsigned Offset,
1517 const Expr *E) -> bool {
1518 if (IsComplex) {
1519 if (!this->emitGetLocal(PT_Ptr, Offset, E))
1520 return false;
1521 return this->emitArrayElemPop(classifyComplexElementType(E->getType()),
1522 ElemIndex, E);
1523 }
1524 if (ElemIndex == 0 || !LoadZero)
1525 return this->emitGetLocal(classifyPrim(E->getType()), Offset, E);
1526 return this->visitZeroInitializer(classifyPrim(E->getType()), E->getType(),
1527 E);
1528 };
1529
1530 // Now we can get pointers to the LHS and RHS from the offsets above.
1531 for (unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1532 // Result pointer for the store later.
1533 if (!this->DiscardResult) {
1534 if (!this->emitGetLocal(PT_Ptr, ResultOffset, E))
1535 return false;
1536 }
1537
1538 // The actual operation.
1539 switch (Op) {
1540 case BO_Add:
1541 if (!loadComplexValue(LHSIsComplex, true, ElemIndex, LHSOffset, LHS))
1542 return false;
1543
1544 if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))
1545 return false;
1546 if (ResultElemT == PT_Float) {
1547 if (!this->emitAddf(getFPOptions(E), E))
1548 return false;
1549 } else {
1550 if (!this->emitAdd(ResultElemT, E))
1551 return false;
1552 }
1553 break;
1554 case BO_Sub:
1555 if (!loadComplexValue(LHSIsComplex, true, ElemIndex, LHSOffset, LHS))
1556 return false;
1557
1558 if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))
1559 return false;
1560 if (ResultElemT == PT_Float) {
1561 if (!this->emitSubf(getFPOptions(E), E))
1562 return false;
1563 } else {
1564 if (!this->emitSub(ResultElemT, E))
1565 return false;
1566 }
1567 break;
1568 case BO_Mul:
1569 if (!loadComplexValue(LHSIsComplex, false, ElemIndex, LHSOffset, LHS))
1570 return false;
1571
1572 if (!loadComplexValue(RHSIsComplex, false, ElemIndex, RHSOffset, RHS))
1573 return false;
1574
1575 if (ResultElemT == PT_Float) {
1576 if (!this->emitMulf(getFPOptions(E), E))
1577 return false;
1578 } else {
1579 if (!this->emitMul(ResultElemT, E))
1580 return false;
1581 }
1582 break;
1583 case BO_Div:
1584 assert(!RHSIsComplex);
1585 if (!loadComplexValue(LHSIsComplex, false, ElemIndex, LHSOffset, LHS))
1586 return false;
1587
1588 if (!loadComplexValue(RHSIsComplex, false, ElemIndex, RHSOffset, RHS))
1589 return false;
1590
1591 if (ResultElemT == PT_Float) {
1592 if (!this->emitDivf(getFPOptions(E), E))
1593 return false;
1594 } else {
1595 if (!this->emitDiv(ResultElemT, E))
1596 return false;
1597 }
1598 break;
1599
1600 default:
1601 return false;
1602 }
1603
1604 if (!this->DiscardResult) {
1605 // Initialize array element with the value we just computed.
1606 if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))
1607 return false;
1608 } else {
1609 if (!this->emitPop(ResultElemT, E))
1610 return false;
1611 // Remove the Complex temporary pointer we created ourselves at the
1612 // beginning of this function.
1613 if (!Initializing)
1614 return this->emitPopPtr(E);
1615 }
1616 }
1617 return true;
1618}
1619
1620template <class Emitter>
1622 const Expr *LHS = E->getLHS();
1623 const Expr *RHS = E->getRHS();
1624 assert(!E->isCommaOp() &&
1625 "Comma op should be handled in VisitBinaryOperator");
1626 assert(E->getType()->isVectorType());
1627 assert(LHS->getType()->isVectorType());
1628 assert(RHS->getType()->isVectorType());
1629
1630 // We can only handle vectors with primitive element types.
1632 return false;
1633
1634 // Prepare storage for result.
1635 if (!Initializing && !E->isCompoundAssignmentOp() && !E->isAssignmentOp()) {
1636 UnsignedOrNone LocalIndex = allocateTemporary(E);
1637 if (!LocalIndex)
1638 return false;
1639 if (!this->emitGetPtrLocal(*LocalIndex, E))
1640 return false;
1641 }
1642
1643 const auto *VecTy = E->getType()->getAs<VectorType>();
1644 auto Op = E->isCompoundAssignmentOp()
1646 : E->getOpcode();
1647
1648 PrimType ElemT = this->classifyVectorElementType(LHS->getType());
1649 PrimType RHSElemT = this->classifyVectorElementType(RHS->getType());
1650 PrimType ResultElemT = this->classifyVectorElementType(E->getType());
1651
1652 if (E->getOpcode() == BO_Assign) {
1653 assert(Ctx.getASTContext().hasSameUnqualifiedType(
1655 RHS->getType()->castAs<VectorType>()->getElementType()));
1656 if (!this->visit(LHS))
1657 return false;
1658 if (!this->visit(RHS))
1659 return false;
1660 if (!this->emitCopyArray(ElemT, 0, 0, VecTy->getNumElements(), E))
1661 return false;
1662 if (DiscardResult)
1663 return this->emitPopPtr(E);
1664 return true;
1665 }
1666
1667 // Evaluate LHS and save value to LHSOffset.
1668 unsigned LHSOffset =
1669 this->allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true);
1670 if (!this->visit(LHS))
1671 return false;
1672 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
1673 return false;
1674
1675 // Evaluate RHS and save value to RHSOffset.
1676 unsigned RHSOffset =
1677 this->allocateLocalPrimitive(RHS, PT_Ptr, /*IsConst=*/true);
1678 if (!this->visit(RHS))
1679 return false;
1680 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
1681 return false;
1682
1683 if (E->isCompoundAssignmentOp() && !this->emitGetLocal(PT_Ptr, LHSOffset, E))
1684 return false;
1685
1686 // BitAdd/BitOr/BitXor/Shl/Shr doesn't support bool type, we need perform the
1687 // integer promotion.
1688 bool NeedIntPromot = ElemT == PT_Bool && (E->isBitwiseOp() || E->isShiftOp());
1689 QualType PromotTy;
1690 PrimType PromotT = PT_Bool;
1691 PrimType OpT = ElemT;
1692 if (NeedIntPromot) {
1693 PromotTy =
1694 Ctx.getASTContext().getPromotedIntegerType(Ctx.getASTContext().BoolTy);
1695 PromotT = classifyPrim(PromotTy);
1696 OpT = PromotT;
1697 }
1698
1699 auto getElem = [=](unsigned Offset, PrimType ElemT, unsigned Index) {
1700 if (!this->emitGetLocal(PT_Ptr, Offset, E))
1701 return false;
1702 if (!this->emitArrayElemPop(ElemT, Index, E))
1703 return false;
1704 if (E->isLogicalOp()) {
1705 if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E))
1706 return false;
1707 if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E))
1708 return false;
1709 } else if (NeedIntPromot) {
1710 if (!this->emitPrimCast(ElemT, PromotT, PromotTy, E))
1711 return false;
1712 }
1713 return true;
1714 };
1715
1716#define EMIT_ARITH_OP(OP) \
1717 { \
1718 if (ElemT == PT_Float) { \
1719 if (!this->emit##OP##f(getFPOptions(E), E)) \
1720 return false; \
1721 } else { \
1722 if (!this->emit##OP(ElemT, E)) \
1723 return false; \
1724 } \
1725 break; \
1726 }
1727
1728 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
1729 if (!getElem(LHSOffset, ElemT, I))
1730 return false;
1731 if (!getElem(RHSOffset, RHSElemT, I))
1732 return false;
1733 switch (Op) {
1734 case BO_Add:
1736 case BO_Sub:
1738 case BO_Mul:
1740 case BO_Div:
1742 case BO_Rem:
1743 if (!this->emitRem(ElemT, E))
1744 return false;
1745 break;
1746 case BO_And:
1747 if (!this->emitBitAnd(OpT, E))
1748 return false;
1749 break;
1750 case BO_Or:
1751 if (!this->emitBitOr(OpT, E))
1752 return false;
1753 break;
1754 case BO_Xor:
1755 if (!this->emitBitXor(OpT, E))
1756 return false;
1757 break;
1758 case BO_Shl:
1759 if (!this->emitShl(OpT, RHSElemT, E))
1760 return false;
1761 break;
1762 case BO_Shr:
1763 if (!this->emitShr(OpT, RHSElemT, E))
1764 return false;
1765 break;
1766 case BO_EQ:
1767 if (!this->emitEQ(ElemT, E))
1768 return false;
1769 break;
1770 case BO_NE:
1771 if (!this->emitNE(ElemT, E))
1772 return false;
1773 break;
1774 case BO_LE:
1775 if (!this->emitLE(ElemT, E))
1776 return false;
1777 break;
1778 case BO_LT:
1779 if (!this->emitLT(ElemT, E))
1780 return false;
1781 break;
1782 case BO_GE:
1783 if (!this->emitGE(ElemT, E))
1784 return false;
1785 break;
1786 case BO_GT:
1787 if (!this->emitGT(ElemT, E))
1788 return false;
1789 break;
1790 case BO_LAnd:
1791 // a && b is equivalent to a!=0 & b!=0
1792 if (!this->emitBitAnd(ResultElemT, E))
1793 return false;
1794 break;
1795 case BO_LOr:
1796 // a || b is equivalent to a!=0 | b!=0
1797 if (!this->emitBitOr(ResultElemT, E))
1798 return false;
1799 break;
1800 default:
1801 return this->emitInvalid(E);
1802 }
1803
1804 // The result of the comparison is a vector of the same width and number
1805 // of elements as the comparison operands with a signed integral element
1806 // type.
1807 //
1808 // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
1809 if (E->isComparisonOp()) {
1810 if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E))
1811 return false;
1812 if (!this->emitNeg(ResultElemT, E))
1813 return false;
1814 }
1815
1816 // If we performed an integer promotion, we need to cast the compute result
1817 // into result vector element type.
1818 if (NeedIntPromot &&
1819 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(), E))
1820 return false;
1821
1822 // Initialize array element with the value we just computed.
1823 if (!this->emitInitElem(ResultElemT, I, E))
1824 return false;
1825 }
1826
1827 if (DiscardResult && E->isCompoundAssignmentOp() && !this->emitPopPtr(E))
1828 return false;
1829 return true;
1830}
1831
1832template <class Emitter>
1834 const Expr *LHS = E->getLHS();
1835 const Expr *RHS = E->getRHS();
1836 const ASTContext &ASTCtx = Ctx.getASTContext();
1837
1838 assert(LHS->getType()->isFixedPointType() ||
1839 RHS->getType()->isFixedPointType());
1840
1841 auto LHSSema = ASTCtx.getFixedPointSemantics(LHS->getType());
1842 auto LHSSemaInt = LHSSema.toOpaqueInt();
1843 auto RHSSema = ASTCtx.getFixedPointSemantics(RHS->getType());
1844 auto RHSSemaInt = RHSSema.toOpaqueInt();
1845
1846 if (!this->visit(LHS))
1847 return false;
1848 if (!LHS->getType()->isFixedPointType()) {
1849 if (!this->emitCastIntegralFixedPoint(classifyPrim(LHS->getType()),
1850 LHSSemaInt, E))
1851 return false;
1852 }
1853
1854 if (!this->visit(RHS))
1855 return false;
1856 if (!RHS->getType()->isFixedPointType()) {
1857 if (!this->emitCastIntegralFixedPoint(classifyPrim(RHS->getType()),
1858 RHSSemaInt, E))
1859 return false;
1860 }
1861
1862 // Convert the result to the target semantics.
1863 auto ConvertResult = [&](bool R) -> bool {
1864 if (!R)
1865 return false;
1866 auto ResultSema = ASTCtx.getFixedPointSemantics(E->getType()).toOpaqueInt();
1867 auto CommonSema = LHSSema.getCommonSemantics(RHSSema).toOpaqueInt();
1868 if (ResultSema != CommonSema)
1869 return this->emitCastFixedPoint(ResultSema, E);
1870 return true;
1871 };
1872
1873 auto MaybeCastToBool = [&](bool Result) {
1874 if (!Result)
1875 return false;
1876 PrimType T = classifyPrim(E);
1877 if (DiscardResult)
1878 return this->emitPop(T, E);
1879 if (T != PT_Bool)
1880 return this->emitCast(PT_Bool, T, E);
1881 return true;
1882 };
1883
1884 switch (E->getOpcode()) {
1885 case BO_EQ:
1886 return MaybeCastToBool(this->emitEQFixedPoint(E));
1887 case BO_NE:
1888 return MaybeCastToBool(this->emitNEFixedPoint(E));
1889 case BO_LT:
1890 return MaybeCastToBool(this->emitLTFixedPoint(E));
1891 case BO_LE:
1892 return MaybeCastToBool(this->emitLEFixedPoint(E));
1893 case BO_GT:
1894 return MaybeCastToBool(this->emitGTFixedPoint(E));
1895 case BO_GE:
1896 return MaybeCastToBool(this->emitGEFixedPoint(E));
1897 case BO_Add:
1898 return ConvertResult(this->emitAddFixedPoint(E));
1899 case BO_Sub:
1900 return ConvertResult(this->emitSubFixedPoint(E));
1901 case BO_Mul:
1902 return ConvertResult(this->emitMulFixedPoint(E));
1903 case BO_Div:
1904 return ConvertResult(this->emitDivFixedPoint(E));
1905 case BO_Shl:
1906 return ConvertResult(this->emitShiftFixedPoint(/*Left=*/true, E));
1907 case BO_Shr:
1908 return ConvertResult(this->emitShiftFixedPoint(/*Left=*/false, E));
1909
1910 default:
1911 return this->emitInvalid(E);
1912 }
1913
1914 llvm_unreachable("unhandled binop opcode");
1915}
1916
1917template <class Emitter>
1919 const Expr *SubExpr = E->getSubExpr();
1920 assert(SubExpr->getType()->isFixedPointType());
1921
1922 switch (E->getOpcode()) {
1923 case UO_Plus:
1924 return this->delegate(SubExpr);
1925 case UO_Minus:
1926 if (!this->visit(SubExpr))
1927 return false;
1928 if (!this->emitNegFixedPoint(E))
1929 return false;
1930 if (DiscardResult)
1931 return this->emitPopFixedPoint(E);
1932 return true;
1933 default:
1934 return false;
1935 }
1936
1937 llvm_unreachable("Unhandled unary opcode");
1938}
1939
1940template <class Emitter>
1942 const ImplicitValueInitExpr *E) {
1943 if (DiscardResult)
1944 return true;
1945
1946 QualType QT = E->getType();
1947
1948 if (OptPrimType T = classify(QT))
1949 return this->visitZeroInitializer(*T, QT, E);
1950
1951 if (QT->isRecordType()) {
1952 const RecordDecl *RD = QT->getAsRecordDecl();
1953 assert(RD);
1954 if (RD->isInvalidDecl())
1955 return false;
1956
1957 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1958 CXXRD && CXXRD->getNumVBases() > 0) {
1959 // TODO: Diagnose.
1960 return false;
1961 }
1962
1963 const Record *R = getRecord(QT);
1964 if (!R)
1965 return false;
1966
1967 assert(Initializing);
1968 return this->visitZeroRecordInitializer(R, E);
1969 }
1970
1971 if (QT->isIncompleteArrayType())
1972 return true;
1973
1974 if (QT->isArrayType())
1975 return this->visitZeroArrayInitializer(QT, E);
1976
1977 if (const auto *ComplexTy = E->getType()->getAs<ComplexType>()) {
1978 assert(Initializing);
1979 QualType ElemQT = ComplexTy->getElementType();
1980 PrimType ElemT = classifyPrim(ElemQT);
1981 for (unsigned I = 0; I < 2; ++I) {
1982 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1983 return false;
1984 if (!this->emitInitElem(ElemT, I, E))
1985 return false;
1986 }
1987 return true;
1988 }
1989
1990 if (const auto *VecT = E->getType()->getAs<VectorType>()) {
1991 unsigned NumVecElements = VecT->getNumElements();
1992 QualType ElemQT = VecT->getElementType();
1993 PrimType ElemT = classifyPrim(ElemQT);
1994
1995 for (unsigned I = 0; I < NumVecElements; ++I) {
1996 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1997 return false;
1998 if (!this->emitInitElem(ElemT, I, E))
1999 return false;
2000 }
2001 return true;
2002 }
2003
2004 if (const auto *MT = E->getType()->getAs<ConstantMatrixType>()) {
2005 unsigned NumElems = MT->getNumElementsFlattened();
2006 QualType ElemQT = MT->getElementType();
2007 PrimType ElemT = classifyPrim(ElemQT);
2008
2009 for (unsigned I = 0; I != NumElems; ++I) {
2010 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2011 return false;
2012 if (!this->emitInitElem(ElemT, I, E))
2013 return false;
2014 }
2015 return true;
2016 }
2017
2018 return false;
2019}
2020
2021template <class Emitter>
2023 if (E->getType()->isVoidType() || E->containsErrors())
2024 return false;
2025
2026 const Expr *LHS = E->getLHS();
2027 const Expr *RHS = E->getRHS();
2028 const Expr *Index = E->getIdx();
2029 const Expr *Base = E->getBase();
2030
2031 // C++17's rules require us to evaluate the LHS first, regardless of which
2032 // side is the base.
2033 bool Success = true;
2034 for (const Expr *SubExpr : {LHS, RHS}) {
2035 if (!this->visit(SubExpr)) {
2036 Success = false;
2037 continue;
2038 }
2039
2040 // Expand the base if this is a subscript on a
2041 // pointer expression.
2042 if (SubExpr == Base && Base->getType()->isPointerType()) {
2043 if (!this->emitExpandPtr(E))
2044 Success = false;
2045 }
2046 }
2047
2048 if (!Success)
2049 return false;
2050
2051 OptPrimType IndexT = classify(Index->getType());
2052 // In error-recovery cases, the index expression has a dependent type.
2053 if (!IndexT)
2054 return this->emitError(E);
2055 // If the index is first, we need to change that.
2056 if (LHS == Index) {
2057 if (!this->emitFlip(PT_Ptr, *IndexT, E))
2058 return false;
2059 }
2060
2061 if (!this->emitArrayElemPtrPop(*IndexT, E))
2062 return false;
2063 if (DiscardResult)
2064 return this->emitPopPtr(E);
2065
2066 if (E->isGLValue())
2067 return true;
2068
2070 return this->emitLoadPop(*T, E);
2071}
2072
2073template <class Emitter>
2075 const Expr *ArrayFiller, const Expr *E) {
2077
2078 QualType QT = E->getType();
2079 if (const auto *AT = QT->getAs<AtomicType>())
2080 QT = AT->getValueType();
2081
2082 if (QT->isVoidType()) {
2083 if (Inits.size() == 0)
2084 return true;
2085 return this->emitInvalid(E);
2086 }
2087
2088 // Handle discarding first.
2089 if (DiscardResult) {
2090 for (const Expr *Init : Inits) {
2091 if (!this->discard(Init))
2092 return false;
2093 }
2094 return true;
2095 }
2096
2097 // Primitive values.
2098 if (OptPrimType T = classify(QT)) {
2099 assert(!DiscardResult);
2100 if (Inits.size() == 0)
2101 return this->visitZeroInitializer(*T, QT, E);
2102 assert(Inits.size() == 1);
2103 return this->delegate(Inits[0]);
2104 }
2105
2106 if (QT->isRecordType()) {
2107 const Record *R = getRecord(QT);
2108
2109 if (Inits.size() == 1 && E->getType() == Inits[0]->getType())
2110 return this->delegate(Inits[0]);
2111
2112 if (!R)
2113 return false;
2114
2115 auto initPrimitiveField = [=](const Record::Field *FieldToInit,
2116 const Expr *Init, PrimType T,
2117 bool Activate = false) -> bool {
2119 if (!this->visit(Init))
2120 return false;
2121
2122 bool BitField = FieldToInit->isBitField();
2123 if (BitField && Activate)
2124 return this->emitInitBitFieldActivate(T, FieldToInit->Offset,
2125 FieldToInit->bitWidth(), E);
2126 if (BitField)
2127 return this->emitInitBitField(T, FieldToInit->Offset,
2128 FieldToInit->bitWidth(), E);
2129 if (Activate)
2130 return this->emitInitFieldActivate(T, FieldToInit->Offset, E);
2131 return this->emitInitField(T, FieldToInit->Offset, E);
2132 };
2133
2134 auto initCompositeField = [=](const Record::Field *FieldToInit,
2135 const Expr *Init,
2136 bool Activate = false) -> bool {
2138 InitLinkScope<Emitter> ILS(this, InitLink::Field(FieldToInit->Offset));
2139
2140 // Non-primitive case. Get a pointer to the field-to-initialize
2141 // on the stack and recurse into visitInitializer().
2142 if (!this->emitGetPtrField(FieldToInit->Offset, Init))
2143 return false;
2144
2145 if (Activate && !this->emitActivate(E))
2146 return false;
2147
2148 return this->visitInitializerPop(Init);
2149 };
2150
2151 if (R->isUnion()) {
2152 if (Inits.size() == 0) {
2153 if (!this->visitZeroRecordInitializer(R, E))
2154 return false;
2155 } else {
2156 const Expr *Init = Inits[0];
2157 const FieldDecl *FToInit = nullptr;
2158 if (const auto *ILE = dyn_cast<InitListExpr>(E))
2159 FToInit = ILE->getInitializedFieldInUnion();
2160 else
2161 FToInit = cast<CXXParenListInitExpr>(E)->getInitializedFieldInUnion();
2162
2163 const Record::Field *FieldToInit = R->getField(FToInit);
2164 if (OptPrimType T = classify(Init)) {
2165 if (!initPrimitiveField(FieldToInit, Init, *T, /*Activate=*/true))
2166 return false;
2167 } else {
2168 if (!initCompositeField(FieldToInit, Init, /*Activate=*/true))
2169 return false;
2170 }
2171 }
2172 return this->emitFinishInit(E);
2173 }
2174
2175 assert(!R->isUnion());
2176 unsigned InitIndex = 0;
2177 for (const Expr *Init : Inits) {
2178 // Skip unnamed bitfields.
2179 while (InitIndex < R->getNumFields() &&
2180 R->getField(InitIndex)->isUnnamedBitField())
2181 ++InitIndex;
2182
2183 // If this is a child of a DesignatedInitUpdateExpr, skip elements which
2184 // aren't supposed to be modified.
2185 if (isa<NoInitExpr>(Init)) {
2186 ++InitIndex;
2187 continue;
2188 }
2189
2190 if (OptPrimType T = classify(Init)) {
2191 const Record::Field *FieldToInit = R->getField(InitIndex);
2192 if (!initPrimitiveField(FieldToInit, Init, *T))
2193 return false;
2194 ++InitIndex;
2195 } else {
2196 // Initializer for a direct base class.
2197 if (const Record::Base *B = R->getBase(Init->getType())) {
2198 if (!this->emitGetPtrBase(B->Offset, Init))
2199 return false;
2200
2201 if (!this->visitInitializerPop(Init))
2202 return false;
2203 // Base initializers don't increase InitIndex, since they don't count
2204 // into the Record's fields.
2205 } else {
2206 const Record::Field *FieldToInit = R->getField(InitIndex);
2207 if (!initCompositeField(FieldToInit, Init))
2208 return false;
2209 ++InitIndex;
2210 }
2211 }
2212 }
2213 return this->emitFinishInit(E);
2214 }
2215
2216 if (QT->isArrayType()) {
2217 const ConstantArrayType *CAT =
2218 Ctx.getASTContext().getAsConstantArrayType(QT);
2219 uint64_t NumElems = CAT->getZExtSize();
2220
2221 if (Initializing && !this->emitCheckArrayDestSize(NumElems, E))
2222 return false;
2223
2224 if (Inits.size() == 1 && QT == Inits[0]->getType())
2225 return this->delegate(Inits[0]);
2226
2227 OptPrimType InitT = classify(CAT->getElementType());
2228 unsigned ElementIndex = 0;
2229 for (const Expr *Init : Inits) {
2230 if (const auto *EmbedS =
2231 dyn_cast<EmbedExpr>(Init->IgnoreParenImpCasts())) {
2232 PrimType TargetT = classifyPrim(Init->getType());
2233
2234 auto Eval = [&](const IntegerLiteral *IL, unsigned ElemIndex) {
2235 if (TargetT == PT_Float) {
2236 if (!this->emitConst(IL->getValue(), classifyPrim(IL), Init))
2237 return false;
2238 const auto *Sem = &Ctx.getFloatSemantics(CAT->getElementType());
2239 if (!this->emitCastIntegralFloating(classifyPrim(IL), Sem,
2240 getFPOptions(E), E))
2241 return false;
2242 } else {
2243 if (!this->emitConst(IL->getValue(), TargetT, Init))
2244 return false;
2245 }
2246 return this->emitInitElem(TargetT, ElemIndex, IL);
2247 };
2248 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
2249 return false;
2250 } else if (isa<NoInitExpr>(Init)) {
2251 // If this is a child of a DesignatedInitUpdateExpr, skip elements which
2252 // aren't supposed to be modified.
2253 ++ElementIndex;
2254 } else {
2255 if (!this->visitArrayElemInit(ElementIndex, Init, InitT))
2256 return false;
2257 ++ElementIndex;
2258 }
2259 }
2260
2261 // Expand the filler expression.
2262 // FIXME: This should go away.
2263 if (ArrayFiller && !isa<NoInitExpr>(ArrayFiller)) {
2264 for (; ElementIndex != NumElems; ++ElementIndex) {
2265 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller, InitT))
2266 return false;
2267 }
2268 }
2269
2270 return this->emitFinishInit(E);
2271 }
2272
2273 if (const auto *ComplexTy = QT->getAs<ComplexType>()) {
2274 unsigned NumInits = Inits.size();
2275
2276 if (NumInits == 1)
2277 return this->delegate(Inits[0]);
2278
2279 QualType ElemQT = ComplexTy->getElementType();
2280 PrimType ElemT = classifyPrim(ElemQT);
2281 if (NumInits == 0) {
2282 // Zero-initialize both elements.
2283 for (unsigned I = 0; I < 2; ++I) {
2284 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2285 return false;
2286 if (!this->emitInitElem(ElemT, I, E))
2287 return false;
2288 }
2289 } else if (NumInits == 2) {
2290 unsigned InitIndex = 0;
2291 for (const Expr *Init : Inits) {
2292 if (!this->visit(Init))
2293 return false;
2294
2295 if (!this->emitInitElem(ElemT, InitIndex, E))
2296 return false;
2297 ++InitIndex;
2298 }
2299 }
2300 return true;
2301 }
2302
2303 if (const auto *VecT = QT->getAs<VectorType>()) {
2304 unsigned NumVecElements = VecT->getNumElements();
2305 assert(NumVecElements >= Inits.size());
2306
2307 QualType ElemQT = VecT->getElementType();
2308 PrimType ElemT = classifyPrim(ElemQT);
2309
2310 // All initializer elements.
2311 unsigned InitIndex = 0;
2312 for (const Expr *Init : Inits) {
2313 if (!this->visit(Init))
2314 return false;
2315
2316 // If the initializer is of vector type itself, we have to deconstruct
2317 // that and initialize all the target fields from the initializer fields.
2318 if (const auto *InitVecT = Init->getType()->getAs<VectorType>()) {
2319 if (!this->emitCopyArray(ElemT, 0, InitIndex,
2320 InitVecT->getNumElements(), E))
2321 return false;
2322 InitIndex += InitVecT->getNumElements();
2323 } else {
2324 if (!this->emitInitElem(ElemT, InitIndex, E))
2325 return false;
2326 ++InitIndex;
2327 }
2328 }
2329
2330 assert(InitIndex <= NumVecElements);
2331
2332 // Fill the rest with zeroes.
2333 for (; InitIndex != NumVecElements; ++InitIndex) {
2334 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2335 return false;
2336 if (!this->emitInitElem(ElemT, InitIndex, E))
2337 return false;
2338 }
2339 return true;
2340 }
2341
2342 if (const auto *MT = QT->getAs<ConstantMatrixType>()) {
2343 unsigned NumElems = MT->getNumElementsFlattened();
2344 assert(Inits.size() == NumElems);
2345
2346 QualType ElemQT = MT->getElementType();
2347 PrimType ElemT = classifyPrim(ElemQT);
2348
2349 // Matrix initializer list elements are in row-major order, which matches
2350 // the matrix APValue convention and therefore no index remapping is
2351 // required.
2352 for (unsigned I = 0; I != NumElems; ++I) {
2353 if (!this->visit(Inits[I]))
2354 return false;
2355 if (!this->emitInitElem(ElemT, I, E))
2356 return false;
2357 }
2358 return true;
2359 }
2360
2361 return false;
2362}
2363
2364/// Pointer to the array(not the element!) must be on the stack when calling
2365/// this.
2366template <class Emitter>
2367bool Compiler<Emitter>::visitArrayElemInit(unsigned ElemIndex, const Expr *Init,
2368 OptPrimType InitT) {
2369 if (InitT) {
2370 // Visit the primitive element like normal.
2371 if (!this->visit(Init))
2372 return false;
2373 return this->emitInitElem(*InitT, ElemIndex, Init);
2374 }
2375
2376 InitLinkScope<Emitter> ILS(this, InitLink::Elem(ElemIndex));
2377 // Advance the pointer currently on the stack to the given
2378 // dimension.
2379 if (!this->emitConstUint32(ElemIndex, Init))
2380 return false;
2381 if (!this->emitArrayElemPtrUint32(Init))
2382 return false;
2383 return this->visitInitializerPop(Init);
2384}
2385
2386template <class Emitter>
2388 const FunctionDecl *FuncDecl,
2389 bool Activate, bool IsOperatorCall) {
2390 assert(VarScope->getKind() == ScopeKind::Call);
2391 llvm::BitVector NonNullArgs;
2392 if (FuncDecl && FuncDecl->hasAttr<NonNullAttr>())
2393 NonNullArgs = collectNonNullArgs(FuncDecl, Args);
2394
2395 bool ExplicitMemberFn = false;
2396 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl))
2397 ExplicitMemberFn = MD->isExplicitObjectMemberFunction();
2398
2399 unsigned ArgIndex = 0;
2400 for (const Expr *Arg : Args) {
2401 if (canClassify(Arg)) {
2402 if (!this->visit(Arg))
2403 return false;
2404 } else {
2405
2406 DeclTy Source = Arg;
2407 if (FuncDecl) {
2408 // Try to use the parameter declaration instead of the argument
2409 // expression as a source.
2410 unsigned DeclIndex = ArgIndex - IsOperatorCall + ExplicitMemberFn;
2411 if (DeclIndex < FuncDecl->getNumParams())
2412 Source = FuncDecl->getParamDecl(ArgIndex - IsOperatorCall +
2413 ExplicitMemberFn);
2414 }
2415
2416 UnsignedOrNone LocalIndex =
2417 allocateLocal(std::move(Source), Arg->getType(), ScopeKind::Call);
2418 if (!LocalIndex)
2419 return false;
2420
2421 if (!this->emitGetPtrLocal(*LocalIndex, Arg))
2422 return false;
2423 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
2424 if (!this->visitInitializer(Arg))
2425 return false;
2426 }
2427
2428 if (ArgIndex == 1 && Activate) {
2429 if (!this->emitActivate(Arg))
2430 return false;
2431 }
2432
2433 if (!NonNullArgs.empty() && NonNullArgs[ArgIndex]) {
2434 PrimType ArgT = classify(Arg).value_or(PT_Ptr);
2435 if (ArgT == PT_Ptr) {
2436 if (!this->emitCheckNonNullArg(ArgT, Arg))
2437 return false;
2438 }
2439 }
2440
2441 ++ArgIndex;
2442 }
2443
2444 return true;
2445}
2446
2447template <class Emitter>
2449 return this->visitInitList(E->inits(), E->getArrayFiller(), E);
2450}
2451
2452template <class Emitter>
2457
2458template <class Emitter>
2463
2464template <class Emitter>
2466 if (!E->hasAPValueResult())
2467 return this->delegate(E->getSubExpr());
2468
2469 if (OptPrimType T = classify(E)) {
2470 // Try to emit the APValue directly, without visiting the subexpr.
2471 // This will only fail if we can't emit the APValue, so won't emit any
2472 // diagnostics or any double values.
2473 if (DiscardResult)
2474 return true;
2475 return this->visitAPValue(E->getAPValueResult(), *T, E);
2476 }
2477
2478 // Fall back to the subexpr for non-primitive APValues.
2479 return this->delegate(E->getSubExpr());
2480}
2481
2482template <class Emitter>
2484 auto It = E->begin();
2485 return this->visit(*It);
2486}
2487
2489 UnaryExprOrTypeTrait Kind) {
2490 bool AlignOfReturnsPreferred =
2491 ASTCtx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
2492
2493 // C++ [expr.alignof]p3:
2494 // When alignof is applied to a reference type, the result is the
2495 // alignment of the referenced type.
2496 if (const auto *Ref = T->getAs<ReferenceType>())
2497 T = Ref->getPointeeType();
2498
2499 if (T.getQualifiers().hasUnaligned())
2500 return CharUnits::One();
2501
2502 // __alignof is defined to return the preferred alignment.
2503 // Before 8, clang returned the preferred alignment for alignof and
2504 // _Alignof as well.
2505 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2506 return ASTCtx.toCharUnitsFromBits(ASTCtx.getPreferredTypeAlign(T));
2507
2508 return ASTCtx.getTypeAlignInChars(T);
2509}
2510
2511template <class Emitter>
2513 const UnaryExprOrTypeTraitExpr *E) {
2514
2515 UnaryExprOrTypeTrait Kind = E->getKind();
2516 const ASTContext &ASTCtx = Ctx.getASTContext();
2517
2518 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2520
2521 // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
2522 // the result is the size of the referenced type."
2523 if (const auto *Ref = ArgType->getAs<ReferenceType>())
2524 ArgType = Ref->getPointeeType();
2525
2526 CharUnits Size;
2527 if (ArgType->isVoidType() || ArgType->isFunctionType())
2528 Size = CharUnits::One();
2529 else {
2530 if (ArgType->isDependentType() || !ArgType->isConstantSizeType())
2531 return this->emitInvalid(E);
2532
2533 if (Kind == UETT_SizeOf)
2534 Size = ASTCtx.getTypeSizeInChars(ArgType);
2535 else
2537 }
2538
2539 if (DiscardResult)
2540 return true;
2541
2542 return this->emitConst(Size.getQuantity(), E);
2543 }
2544
2545 if (Kind == UETT_CountOf) {
2546 QualType Ty = E->getTypeOfArgument();
2547 assert(Ty->isArrayType());
2548
2549 // We don't need to worry about array element qualifiers, so getting the
2550 // unsafe array type is fine.
2551 if (const auto *CAT =
2552 dyn_cast<ConstantArrayType>(Ty->getAsArrayTypeUnsafe())) {
2553 if (DiscardResult)
2554 return true;
2555 return this->emitConst(CAT->getSize(), E);
2556 }
2557
2558 assert(!Ty->isConstantSizeType());
2559
2560 // If it's a variable-length array type, we need to check whether it is a
2561 // multidimensional array. If so, we need to check the size expression of
2562 // the VLA to see if it's a constant size. If so, we can return that value.
2563 const auto *VAT = ASTCtx.getAsVariableArrayType(Ty);
2564 assert(VAT);
2565 if (VAT->getElementType()->isArrayType()) {
2566 std::optional<APSInt> Res =
2567 VAT->getSizeExpr()
2568 ? VAT->getSizeExpr()->getIntegerConstantExpr(ASTCtx)
2569 : std::nullopt;
2570 if (Res) {
2571 if (DiscardResult)
2572 return true;
2573 return this->emitConst(*Res, E);
2574 }
2575 }
2576 }
2577
2578 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2579 CharUnits Size;
2580
2581 if (E->isArgumentType()) {
2583
2584 Size = AlignOfType(ArgType, ASTCtx, Kind);
2585 } else {
2586 // Argument is an expression, not a type.
2587 const Expr *Arg = E->getArgumentExpr()->IgnoreParens();
2588
2589 if (Arg->getType()->isDependentType())
2590 return false;
2591
2592 // The kinds of expressions that we have special-case logic here for
2593 // should be kept up to date with the special checks for those
2594 // expressions in Sema.
2595
2596 // alignof decl is always accepted, even if it doesn't make sense: we
2597 // default to 1 in those cases.
2598 if (const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2599 Size = ASTCtx.getDeclAlign(DRE->getDecl(),
2600 /*RefAsPointee*/ true);
2601 else if (const auto *ME = dyn_cast<MemberExpr>(Arg))
2602 Size = ASTCtx.getDeclAlign(ME->getMemberDecl(),
2603 /*RefAsPointee*/ true);
2604 else
2605 Size = AlignOfType(Arg->getType(), ASTCtx, Kind);
2606 }
2607
2608 if (DiscardResult)
2609 return true;
2610
2611 return this->emitConst(Size.getQuantity(), E);
2612 }
2613
2614 if (Kind == UETT_VectorElements) {
2615 if (E->containsErrors())
2616 return false;
2617
2618 if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>())
2619 return this->emitConst(VT->getNumElements(), E);
2621 return this->emitSizelessVectorElementSize(E);
2622 }
2623
2624 if (Kind == UETT_VecStep) {
2625 if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>()) {
2626 unsigned N = VT->getNumElements();
2627
2628 // The vec_step built-in functions that take a 3-component
2629 // vector return 4. (OpenCL 1.1 spec 6.11.12)
2630 if (N == 3)
2631 N = 4;
2632
2633 return this->emitConst(N, E);
2634 }
2635 return this->emitConst(1, E);
2636 }
2637
2638 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2639 assert(E->isArgumentType());
2640 unsigned Bits = ASTCtx.getOpenMPDefaultSimdAlign(E->getArgumentType());
2641
2642 return this->emitConst(ASTCtx.toCharUnitsFromBits(Bits).getQuantity(), E);
2643 }
2644
2645 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2646 if (E->getArgumentType()->isDependentType())
2647 return this->emitInvalid(E);
2648
2649 return this->emitConst(
2650 const_cast<ASTContext &>(ASTCtx).getPointerAuthTypeDiscriminator(
2651 E->getArgumentType()),
2652 E);
2653 }
2654
2655 return false;
2656}
2657
2658template <class Emitter>
2660 // 'Base.Member'
2661 const Expr *Base = E->getBase();
2662 const ValueDecl *Member = E->getMemberDecl();
2663
2664 if (DiscardResult)
2665 return this->discard(Base);
2666
2667 if (const auto *VD = dyn_cast<VarDecl>(Member)) {
2668 // I am almost confident in saying that a var decl must be static
2669 // and therefore registered as a global variable.
2670 if (auto GlobalIndex = P.getGlobal(VD)) {
2671 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2672 return false;
2673 if (Member->getType()->isReferenceType())
2674 return this->emitLoadPopPtr(E);
2675 return true;
2676 }
2677 return false;
2678 }
2679
2680 if (!isa<FieldDecl>(Member)) {
2681 // A non-static member function access only makes sense as part of the
2682 // enclosing call here. Don't try to evaluate it in isolation.
2683 if (const auto *MD = dyn_cast<CXXMethodDecl>(Member);
2684 MD && !MD->isStatic()) {
2685 return false;
2686 }
2687
2688 if (!this->discard(Base) && !this->emitSideEffect(E))
2689 return false;
2690
2691 return this->visitDeclRef(Member, E);
2692 }
2693
2694 if (!this->visit(Base))
2695 return false;
2696
2697 // Base above gives us a pointer on the stack.
2698 const auto *FD = cast<FieldDecl>(Member);
2699 const RecordDecl *RD = FD->getParent();
2700 const Record *R = getRecord(RD);
2701 if (!R)
2702 return false;
2703 const Record::Field *F = R->getField(FD);
2704
2705 // MemberExprs are almost always lvalues, in which case we don't need to
2706 // do the load. But sometimes they aren't.
2707 const auto maybeLoadValue = [&]() -> bool {
2708 if (E->isGLValue())
2709 return true;
2710 if (OptPrimType T = classify(E))
2711 return this->emitLoadPop(*T, E);
2712 return false;
2713 };
2714
2715 // Leave a pointer to the field on the stack.
2716 if (F->Decl->getType()->isReferenceType())
2717 return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue();
2718 return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue();
2719}
2720
2721template <class Emitter>
2723 assert(!DiscardResult);
2724 // ArrayIndex might not be set if a ArrayInitIndexExpr is being evaluated
2725 // stand-alone, e.g. via EvaluateAsInt().
2726 if (!ArrayIndex)
2727 return false;
2728 return this->emitConst(*ArrayIndex, E);
2729}
2730
2731template <class Emitter>
2733 assert(Initializing);
2734 assert(!DiscardResult);
2735
2736 const Expr *Common = E->getCommonExpr();
2737 const Expr *SubExpr = E->getSubExpr();
2738 OptPrimType SubExprT = classify(SubExpr);
2739 size_t Size = E->getArraySize().getZExtValue();
2740
2741 if (SubExprT) {
2742 // Unwrap the OpaqueValueExpr so we don't cache something we won't reuse.
2743 Common = cast<OpaqueValueExpr>(Common)->getSourceExpr();
2744
2745 if (!this->visit(Common))
2746 return false;
2747 return this->emitCopyArray(*SubExprT, 0, 0, Size, E);
2748 }
2749
2750 // We visit the common opaque expression here once so we have its value
2751 // cached.
2752 if (!this->discard(Common))
2753 return false;
2754
2755 // TODO: This compiles to quite a lot of bytecode if the array is larger.
2756 // Investigate compiling this to a loop.
2757
2758 // So, every iteration, we execute an assignment here
2759 // where the LHS is on the stack (the target array)
2760 // and the RHS is our SubExpr.
2761 for (size_t I = 0; I != Size; ++I) {
2762 ArrayIndexScope<Emitter> IndexScope(this, I);
2764
2765 if (!this->visitArrayElemInit(I, SubExpr, SubExprT))
2766 return false;
2767 if (!BS.destroyLocals())
2768 return false;
2769 }
2770 return true;
2771}
2772
2773template <class Emitter>
2775 const Expr *SourceExpr = E->getSourceExpr();
2776 if (!SourceExpr)
2777 return false;
2778
2779 if (Initializing) {
2780 assert(!DiscardResult);
2781 return this->visitInitializer(SourceExpr);
2782 }
2783
2784 PrimType SubExprT = classify(SourceExpr).value_or(PT_Ptr);
2785 if (auto It = OpaqueExprs.find(E); It != OpaqueExprs.end()) {
2786 if (DiscardResult)
2787 return true;
2788 return this->emitGetLocal(SubExprT, It->second, E);
2789 }
2790
2791 if (!this->visit(SourceExpr))
2792 return false;
2793
2794 // At this point we either have the evaluated source expression or a pointer
2795 // to an object on the stack. We want to create a local variable that stores
2796 // this value.
2797 unsigned LocalIndex = allocateLocalPrimitive(E, SubExprT, /*IsConst=*/true);
2798 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
2799 return false;
2800
2801 // This is cleaned up when the local variable is destroyed.
2802 OpaqueExprs.insert({E, LocalIndex});
2803
2804 // Here the local variable is created but the value is removed from the stack,
2805 // so we put it back if the caller needs it.
2806 if (!DiscardResult)
2807 return this->emitGetLocal(SubExprT, LocalIndex, E);
2808 return true;
2809}
2810
2811template <class Emitter>
2813 const AbstractConditionalOperator *E) {
2814 const Expr *Condition = E->getCond();
2815 const Expr *TrueExpr = E->getTrueExpr();
2816 const Expr *FalseExpr = E->getFalseExpr();
2817
2818 if (std::optional<bool> BoolValue = getBoolValue(Condition)) {
2819 if (*BoolValue)
2820 return this->delegate(TrueExpr);
2821 return this->delegate(FalseExpr);
2822 }
2823
2824 // Force-init the scope, which creates a InitScope op. This is necessary so
2825 // the scope is not only initialized in one arm of the conditional operator.
2826 this->VarScope->forceInit();
2827 // The TrueExpr and FalseExpr of a conditional operator do _not_ create a
2828 // scope, which means the local variables created within them unconditionally
2829 // always exist. However, we need to later differentiate which branch was
2830 // taken and only destroy the varibles of the active branch. This is what the
2831 // "enabled" flags on local variables are used for.
2832 llvm::SaveAndRestore LAAA(this->VarScope->LocalsAlwaysEnabled,
2833 /*NewValue=*/false);
2834 bool IsBcpCall = false;
2835 if (const auto *CE = dyn_cast<CallExpr>(Condition->IgnoreParenCasts());
2836 CE && CE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) {
2837 IsBcpCall = true;
2838 }
2839
2840 LabelTy LabelEnd = this->getLabel(); // Label after the operator.
2841 LabelTy LabelFalse = this->getLabel(); // Label for the false expr.
2842
2843 if (IsBcpCall) {
2844 if (!this->emitPushIgnoreDiags(E))
2845 return false;
2846 }
2847
2848 if (!this->visitBool(Condition)) {
2849 // If the condition failed and we're checking for undefined behavior
2850 // (which only happens with EvalEmitter) check the TrueExpr and FalseExpr
2851 // as well.
2852 if (this->checkingForUndefinedBehavior()) {
2853 if (!this->discard(TrueExpr))
2854 return false;
2855 if (!this->discard(FalseExpr))
2856 return false;
2857 }
2858 return false;
2859 }
2860
2861 if (!this->jumpFalse(LabelFalse, E))
2862 return false;
2863 if (!this->delegate(TrueExpr))
2864 return false;
2865
2866 if (!this->jump(LabelEnd, E))
2867 return false;
2868 this->emitLabel(LabelFalse);
2869 if (!this->delegate(FalseExpr))
2870 return false;
2871
2872 this->fallthrough(LabelEnd);
2873 this->emitLabel(LabelEnd);
2874
2875 if (IsBcpCall)
2876 return this->emitPopIgnoreDiags(E);
2877 return true;
2878}
2879
2880template <class Emitter>
2882 if (DiscardResult)
2883 return true;
2884
2885 if (!Initializing) {
2886 unsigned StringIndex = P.createGlobalString(E);
2887 return this->emitGetPtrGlobal(StringIndex, E);
2888 }
2889
2890 // We are initializing an array on the stack.
2891 const ConstantArrayType *CAT =
2892 Ctx.getASTContext().getAsConstantArrayType(E->getType());
2893 assert(CAT && "a string literal that's not a constant array?");
2894
2895 // If the initializer string is too long, a diagnostic has already been
2896 // emitted. Read only the array length from the string literal.
2897 unsigned ArraySize = CAT->getZExtSize();
2898 unsigned N = std::min(ArraySize, E->getLength());
2899 unsigned CharWidth = E->getCharByteWidth();
2900
2901 for (unsigned I = 0; I != N; ++I) {
2902 uint32_t CodeUnit = E->getCodeUnit(I);
2903
2904 if (CharWidth == 1) {
2905 this->emitConstSint8(CodeUnit, E);
2906 this->emitInitElemSint8(I, E);
2907 } else if (CharWidth == 2) {
2908 this->emitConstUint16(CodeUnit, E);
2909 this->emitInitElemUint16(I, E);
2910 } else if (CharWidth == 4) {
2911 this->emitConstUint32(CodeUnit, E);
2912 this->emitInitElemUint32(I, E);
2913 } else {
2914 llvm_unreachable("unsupported character width");
2915 }
2916 }
2917
2918 // Fill up the rest of the char array with NUL bytes.
2919 for (unsigned I = N; I != ArraySize; ++I) {
2920 if (CharWidth == 1) {
2921 this->emitConstSint8(0, E);
2922 this->emitInitElemSint8(I, E);
2923 } else if (CharWidth == 2) {
2924 this->emitConstUint16(0, E);
2925 this->emitInitElemUint16(I, E);
2926 } else if (CharWidth == 4) {
2927 this->emitConstUint32(0, E);
2928 this->emitInitElemUint32(I, E);
2929 } else {
2930 llvm_unreachable("unsupported character width");
2931 }
2932 }
2933
2934 return true;
2935}
2936
2937template <class Emitter>
2939 if (DiscardResult)
2940 return true;
2941 return this->emitDummyPtr(E, E);
2942}
2943
2944template <class Emitter>
2946 auto &A = Ctx.getASTContext();
2947 std::string Str;
2948 A.getObjCEncodingForType(E->getEncodedType(), Str);
2949 StringLiteral *SL =
2951 /*Pascal=*/false, E->getType(), E->getAtLoc());
2952 return this->delegate(SL);
2953}
2954
2955template <class Emitter>
2957 const SYCLUniqueStableNameExpr *E) {
2958 if (DiscardResult)
2959 return true;
2960
2961 assert(!Initializing);
2962
2963 auto &A = Ctx.getASTContext();
2964 std::string ResultStr = E->ComputeName(A);
2965
2966 QualType CharTy = A.CharTy.withConst();
2967 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
2968 QualType ArrayTy = A.getConstantArrayType(CharTy, Size, nullptr,
2970
2971 StringLiteral *SL =
2973 /*Pascal=*/false, ArrayTy, E->getLocation());
2974
2975 unsigned StringIndex = P.createGlobalString(SL);
2976 return this->emitGetPtrGlobal(StringIndex, E);
2977}
2978
2979template <class Emitter>
2981 if (DiscardResult)
2982 return true;
2983 return this->emitConst(E->getValue(), E);
2984}
2985
2986template <class Emitter>
2988 const CompoundAssignOperator *E) {
2989
2990 const Expr *LHS = E->getLHS();
2991 const Expr *RHS = E->getRHS();
2992 QualType LHSType = LHS->getType();
2993 QualType LHSComputationType = E->getComputationLHSType();
2994 QualType ResultType = E->getComputationResultType();
2995 OptPrimType LT = classify(LHSComputationType);
2996 OptPrimType RT = classify(ResultType);
2997
2998 assert(ResultType->isFloatingType());
2999
3000 if (!LT || !RT)
3001 return false;
3002
3003 PrimType LHST = classifyPrim(LHSType);
3004
3005 // C++17 onwards require that we evaluate the RHS first.
3006 // Compute RHS and save it in a temporary variable so we can
3007 // load it again later.
3008 if (!visit(RHS))
3009 return false;
3010
3011 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
3012 if (!this->emitSetLocal(*RT, TempOffset, E))
3013 return false;
3014
3015 // First, visit LHS.
3016 if (!visit(LHS))
3017 return false;
3018 if (!this->emitLoad(LHST, E))
3019 return false;
3020
3021 // If necessary, convert LHS to its computation type.
3022 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
3023 LHSComputationType, E))
3024 return false;
3025
3026 // Now load RHS.
3027 if (!this->emitGetLocal(*RT, TempOffset, E))
3028 return false;
3029
3030 switch (E->getOpcode()) {
3031 case BO_AddAssign:
3032 if (!this->emitAddf(getFPOptions(E), E))
3033 return false;
3034 break;
3035 case BO_SubAssign:
3036 if (!this->emitSubf(getFPOptions(E), E))
3037 return false;
3038 break;
3039 case BO_MulAssign:
3040 if (!this->emitMulf(getFPOptions(E), E))
3041 return false;
3042 break;
3043 case BO_DivAssign:
3044 if (!this->emitDivf(getFPOptions(E), E))
3045 return false;
3046 break;
3047 default:
3048 return false;
3049 }
3050
3051 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->getType(), E))
3052 return false;
3053
3054 if (DiscardResult)
3055 return this->emitStorePop(LHST, E);
3056 return this->emitStore(LHST, E);
3057}
3058
3059template <class Emitter>
3061 const CompoundAssignOperator *E) {
3062 BinaryOperatorKind Op = E->getOpcode();
3063 const Expr *LHS = E->getLHS();
3064 const Expr *RHS = E->getRHS();
3065 OptPrimType LT = classify(LHS->getType());
3066 OptPrimType RT = classify(RHS->getType());
3067
3068 if (Op != BO_AddAssign && Op != BO_SubAssign)
3069 return false;
3070
3071 if (!LT || !RT)
3072 return false;
3073
3074 if (!visit(LHS))
3075 return false;
3076
3077 if (!this->emitLoad(*LT, LHS))
3078 return false;
3079
3080 if (!visit(RHS))
3081 return false;
3082
3083 if (Op == BO_AddAssign) {
3084 if (!this->emitAddOffset(*RT, E))
3085 return false;
3086 } else {
3087 if (!this->emitSubOffset(*RT, E))
3088 return false;
3089 }
3090
3091 if (DiscardResult)
3092 return this->emitStorePopPtr(E);
3093 return this->emitStorePtr(E);
3094}
3095
3096template <class Emitter>
3098 const CompoundAssignOperator *E) {
3099 if (E->getType()->isVectorType())
3100 return VisitVectorBinOp(E);
3101
3102 const Expr *LHS = E->getLHS();
3103 const Expr *RHS = E->getRHS();
3104 OptPrimType LHSComputationT = classify(E->getComputationLHSType());
3105 OptPrimType LT = classify(LHS->getType());
3106 OptPrimType RT = classify(RHS->getType());
3107 OptPrimType ResultT = classify(E->getType());
3108
3109 if (!Ctx.getLangOpts().CPlusPlus14)
3110 return this->visit(RHS) && this->visit(LHS) && this->emitError(E);
3111
3112 if (!LT || !RT || !ResultT || !LHSComputationT)
3113 return false;
3114
3115 // Handle floating point operations separately here, since they
3116 // require special care.
3117
3118 if (ResultT == PT_Float || RT == PT_Float)
3120
3121 if (E->getType()->isPointerType())
3123
3124 assert(!E->getType()->isPointerType() && "Handled above");
3125 assert(!E->getType()->isFloatingType() && "Handled above");
3126
3127 // C++17 onwards require that we evaluate the RHS first.
3128 // Compute RHS and save it in a temporary variable so we can
3129 // load it again later.
3130 // FIXME: Compound assignments are unsequenced in C, so we might
3131 // have to figure out how to reject them.
3132 if (!visit(RHS))
3133 return false;
3134
3135 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
3136
3137 if (!this->emitSetLocal(*RT, TempOffset, E))
3138 return false;
3139
3140 // Get LHS pointer, load its value and cast it to the
3141 // computation type if necessary.
3142 if (!visit(LHS))
3143 return false;
3144 if (!this->emitLoad(*LT, E))
3145 return false;
3146 if (LT != LHSComputationT &&
3147 !this->emitIntegralCast(*LT, *LHSComputationT, E->getComputationLHSType(),
3148 E))
3149 return false;
3150
3151 // Get the RHS value on the stack.
3152 if (!this->emitGetLocal(*RT, TempOffset, E))
3153 return false;
3154
3155 // Perform operation.
3156 switch (E->getOpcode()) {
3157 case BO_AddAssign:
3158 if (!this->emitAdd(*LHSComputationT, E))
3159 return false;
3160 break;
3161 case BO_SubAssign:
3162 if (!this->emitSub(*LHSComputationT, E))
3163 return false;
3164 break;
3165 case BO_MulAssign:
3166 if (!this->emitMul(*LHSComputationT, E))
3167 return false;
3168 break;
3169 case BO_DivAssign:
3170 if (!this->emitDiv(*LHSComputationT, E))
3171 return false;
3172 break;
3173 case BO_RemAssign:
3174 if (!this->emitRem(*LHSComputationT, E))
3175 return false;
3176 break;
3177 case BO_ShlAssign:
3178 if (!this->emitShl(*LHSComputationT, *RT, E))
3179 return false;
3180 break;
3181 case BO_ShrAssign:
3182 if (!this->emitShr(*LHSComputationT, *RT, E))
3183 return false;
3184 break;
3185 case BO_AndAssign:
3186 if (!this->emitBitAnd(*LHSComputationT, E))
3187 return false;
3188 break;
3189 case BO_XorAssign:
3190 if (!this->emitBitXor(*LHSComputationT, E))
3191 return false;
3192 break;
3193 case BO_OrAssign:
3194 if (!this->emitBitOr(*LHSComputationT, E))
3195 return false;
3196 break;
3197 default:
3198 llvm_unreachable("Unimplemented compound assign operator");
3199 }
3200
3201 // And now cast from LHSComputationT to ResultT.
3202 if (ResultT != LHSComputationT &&
3203 !this->emitIntegralCast(*LHSComputationT, *ResultT, E->getType(), E))
3204 return false;
3205
3206 // And store the result in LHS.
3207 if (DiscardResult) {
3208 if (LHS->refersToBitField())
3209 return this->emitStoreBitFieldPop(*ResultT, E);
3210 return this->emitStorePop(*ResultT, E);
3211 }
3212 if (LHS->refersToBitField())
3213 return this->emitStoreBitField(*ResultT, E);
3214 return this->emitStore(*ResultT, E);
3215}
3216
3217template <class Emitter>
3220 const Expr *SubExpr = E->getSubExpr();
3221
3222 return this->delegate(SubExpr) && ES.destroyLocals(E);
3223}
3224
3225template <class Emitter>
3227 const MaterializeTemporaryExpr *E) {
3228 if (Initializing) {
3229 // We already have a value, just initialize that.
3230 return this->delegate(E->getSubExpr());
3231 }
3232 // If we don't end up using the materialized temporary anyway, don't
3233 // bother creating it.
3234 if (DiscardResult)
3235 return this->discard(E->getSubExpr());
3236
3239 const Expr *Inner;
3240 if (!Ctx.getLangOpts().CPlusPlus11)
3241 Inner =
3242 E->getSubExpr()->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
3243 else
3244 Inner = E->getSubExpr();
3245
3246 // If we passed any comma operators, evaluate their LHSs.
3247 for (const Expr *LHS : CommaLHSs) {
3248 if (!this->discard(LHS))
3249 return false;
3250 }
3251
3252 // FIXME: Find a test case where Adjustments matters.
3253
3254 // When we're extending a global variable *or* the storage duration of
3255 // the temporary is explicitly static, create a global variable.
3256 OptPrimType InnerT = classify(Inner);
3257 const ValueDecl *ExtendingDecl = E->getExtendingDecl();
3258 bool IsStatic = E->getStorageDuration() == SD_Static;
3259 if (IsStatic ||
3260 (ExtendingDecl && Context::shouldBeGloballyIndexed(ExtendingDecl))) {
3261 UnsignedOrNone GlobalIndex = P.createGlobal(E, Inner->getType());
3262 if (!GlobalIndex)
3263 return false;
3264
3265 const LifetimeExtendedTemporaryDecl *TempDecl =
3267
3268 if (InnerT) {
3269 if (!this->visit(Inner))
3270 return false;
3271
3272 if (IsStatic) {
3273 assert(TempDecl);
3274 if (!this->emitInitGlobalTemp(*InnerT, *GlobalIndex, TempDecl, E))
3275 return false;
3276 } else {
3277 if (!this->emitInitGlobal(*InnerT, *GlobalIndex, E))
3278 return false;
3279 }
3280 return this->emitGetPtrGlobal(*GlobalIndex, E);
3281 }
3282
3283 if (!this->checkLiteralType(Inner))
3284 return false;
3285 // Non-primitive values.
3286 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3287 return false;
3288 if (!this->visitInitializer(Inner))
3289 return false;
3290 if (IsStatic) {
3291 assert(TempDecl);
3292 return this->emitInitGlobalTempComp(TempDecl, E);
3293 }
3294 return true;
3295 }
3296
3300
3301 // For everyhing else, use local variables.
3302 if (InnerT) {
3303 bool IsConst = Inner->getType().isConstQualified();
3304 bool IsVolatile = Inner->getType().isVolatileQualified();
3305 unsigned LocalIndex =
3306 allocateLocalPrimitive(E, *InnerT, IsConst, IsVolatile, VarScope);
3307 if (!this->VarScope->LocalsAlwaysEnabled &&
3308 !this->emitEnableLocal(LocalIndex, E))
3309 return false;
3310
3311 if (!this->visit(Inner))
3312 return false;
3313 if (!this->emitSetLocal(*InnerT, LocalIndex, E))
3314 return false;
3315
3316 return this->emitGetPtrLocal(LocalIndex, E);
3317 }
3318
3319 if (!this->checkLiteralType(Inner))
3320 return false;
3321
3322 if (UnsignedOrNone LocalIndex =
3323 allocateLocal(E, Inner->getType(), VarScope)) {
3324 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
3325
3326 if (!this->VarScope->LocalsAlwaysEnabled &&
3327 !this->emitEnableLocal(*LocalIndex, E))
3328 return false;
3329
3330 if (!this->emitGetPtrLocal(*LocalIndex, E))
3331 return false;
3332 return this->visitInitializer(Inner);
3333 }
3334 return false;
3335}
3336
3337template <class Emitter>
3339 const CXXBindTemporaryExpr *E) {
3340 const Expr *SubExpr = E->getSubExpr();
3341
3342 if (Initializing)
3343 return this->delegate(SubExpr);
3344
3345 // Make sure we create a temporary even if we're discarding, since that will
3346 // make sure we will also call the destructor.
3347
3348 if (!this->visit(SubExpr))
3349 return false;
3350
3351 if (DiscardResult)
3352 return this->emitPopPtr(E);
3353 return true;
3354}
3355
3356template <class Emitter>
3358 const Expr *Init = E->getInitializer();
3359 if (DiscardResult)
3360 return this->discard(Init);
3361
3362 if (Initializing) {
3363 // We already have a value, just initialize that.
3364 return this->visitInitializer(Init);
3365 }
3366
3367 OptPrimType T = classify(E->getType());
3368 if (E->isFileScope()) {
3369 // Avoid creating a variable if this is a primitive RValue anyway.
3370 if (T && !E->isLValue())
3371 return this->delegate(Init);
3372
3373 UnsignedOrNone GlobalIndex = P.createGlobal(E, E->getType());
3374 if (!GlobalIndex)
3375 return false;
3376
3377 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3378 return false;
3379
3380 // Since this is a global variable, we might've already seen,
3381 // don't do it again.
3382 if (P.isGlobalInitialized(*GlobalIndex))
3383 return true;
3384
3385 if (T) {
3386 if (!this->visit(Init))
3387 return false;
3388 return this->emitInitGlobal(*T, *GlobalIndex, E);
3389 }
3390
3391 return this->visitInitializer(Init);
3392 }
3393
3394 // Otherwise, use a local variable.
3395 if (T && !E->isLValue()) {
3396 // For primitive types, we just visit the initializer.
3397 return this->delegate(Init);
3398 }
3399
3400 unsigned LocalIndex;
3401 if (T)
3402 LocalIndex = this->allocateLocalPrimitive(Init, *T, /*IsConst=*/false);
3403 else if (UnsignedOrNone MaybeIndex = this->allocateLocal(Init))
3404 LocalIndex = *MaybeIndex;
3405 else
3406 return false;
3407
3408 if (!this->emitGetPtrLocal(LocalIndex, E))
3409 return false;
3410
3411 if (T)
3412 return this->visit(Init) && this->emitInit(*T, E);
3413 return this->visitInitializer(Init);
3414}
3415
3416template <class Emitter>
3418 if (DiscardResult)
3419 return true;
3420 if (E->isStoredAsBoolean()) {
3421 if (E->getType()->isBooleanType())
3422 return this->emitConstBool(E->getBoolValue(), E);
3423 return this->emitConst(E->getBoolValue(), E);
3424 }
3425 PrimType T = classifyPrim(E->getType());
3426 return this->visitAPValue(E->getAPValue(), T, E);
3427}
3428
3429template <class Emitter>
3431 if (DiscardResult)
3432 return true;
3433 return this->emitConst(E->getValue(), E);
3434}
3435
3436template <class Emitter>
3438 if (DiscardResult)
3439 return true;
3440
3441 assert(Initializing);
3442 const Record *R = P.getOrCreateRecord(E->getLambdaClass());
3443 if (!R)
3444 return false;
3445
3446 auto *CaptureInitIt = E->capture_init_begin();
3447 // Initialize all fields (which represent lambda captures) of the
3448 // record with their initializers.
3449 for (const Record::Field &F : R->fields()) {
3450 const Expr *Init = *CaptureInitIt;
3451 if (!Init || Init->containsErrors())
3452 continue;
3453 ++CaptureInitIt;
3454
3455 if (OptPrimType T = classify(Init)) {
3456 if (!this->visit(Init))
3457 return false;
3458
3459 if (!this->emitInitField(*T, F.Offset, E))
3460 return false;
3461 } else {
3462 if (!this->emitGetPtrField(F.Offset, E))
3463 return false;
3464
3465 if (!this->visitInitializerPop(Init))
3466 return false;
3467 }
3468 }
3469
3470 return true;
3471}
3472
3473template <class Emitter>
3475 if (DiscardResult)
3476 return true;
3477
3478 if (!Initializing) {
3479 unsigned StringIndex = P.createGlobalString(E->getFunctionName(), E);
3480 return this->emitGetPtrGlobal(StringIndex, E);
3481 }
3482
3483 return this->delegate(E->getFunctionName());
3484}
3485
3486template <class Emitter>
3488 if (E->getSubExpr() && !this->discard(E->getSubExpr()))
3489 return false;
3490
3491 return this->emitInvalid(E);
3492}
3493
3494template <class Emitter>
3496 const CXXReinterpretCastExpr *E) {
3497 const Expr *SubExpr = E->getSubExpr();
3498
3499 OptPrimType FromT = classify(SubExpr);
3500 OptPrimType ToT = classify(E);
3501
3502 if (!FromT || !ToT)
3503 return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, E);
3504
3505 if (FromT == PT_Ptr || ToT == PT_Ptr) {
3506 // Both types could be PT_Ptr because their expressions are glvalues.
3507 OptPrimType PointeeFromT;
3508 if (SubExpr->getType()->isPointerOrReferenceType())
3509 PointeeFromT = classify(SubExpr->getType()->getPointeeType());
3510 else
3511 PointeeFromT = classify(SubExpr->getType());
3512
3513 OptPrimType PointeeToT;
3515 PointeeToT = classify(E->getType()->getPointeeType());
3516 else
3517 PointeeToT = classify(E->getType());
3518
3519 bool Fatal = true;
3520 if (PointeeToT && PointeeFromT) {
3521 if (isIntegerOrBoolType(*PointeeFromT) &&
3522 isIntegerOrBoolType(*PointeeToT))
3523 Fatal = false;
3524 else if (E->getCastKind() == CK_LValueBitCast)
3525 Fatal = false;
3526 } else {
3527 Fatal = SubExpr->getType().getTypePtr() != E->getType().getTypePtr();
3528 }
3529
3530 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal, E))
3531 return false;
3532
3533 if (E->getCastKind() == CK_LValueBitCast)
3534 return this->delegate(SubExpr);
3535 return this->VisitCastExpr(E);
3536 }
3537
3538 // Try to actually do the cast.
3539 bool Fatal = (ToT != FromT);
3540 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal, E))
3541 return false;
3542
3543 return this->VisitCastExpr(E);
3544}
3545
3546template <class Emitter>
3548
3549 if (!Ctx.getLangOpts().CPlusPlus20) {
3550 if (!this->emitInvalidCast(CastKind::Dynamic, /*Fatal=*/false, E))
3551 return false;
3552 return this->VisitCastExpr(E);
3553 }
3554
3555 if (!this->visit(E->getSubExpr()))
3556 return false;
3557 if (!this->emitCheckDynamicCast(E))
3558 return false;
3559
3560 return true;
3561}
3562
3563template <class Emitter>
3565 assert(E->getType()->isBooleanType());
3566
3567 if (DiscardResult)
3568 return true;
3569 return this->emitConstBool(E->getValue(), E);
3570}
3571
3572template <class Emitter>
3574 QualType T = E->getType();
3575 assert(!canClassify(T));
3576
3577 if (T->isRecordType()) {
3578 const CXXConstructorDecl *Ctor = E->getConstructor();
3579
3580 // If we're discarding a construct expression, we still need
3581 // to allocate a variable and call the constructor and destructor.
3582 if (DiscardResult) {
3583 if (Ctor->isTrivial())
3584 return true;
3585 assert(!Initializing);
3586 UnsignedOrNone LocalIndex = allocateLocal(E);
3587
3588 if (!LocalIndex)
3589 return false;
3590
3591 if (!this->emitGetPtrLocal(*LocalIndex, E))
3592 return false;
3593 }
3594
3595 // Trivial copy/move constructor. Avoid copy.
3596 if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&
3597 Ctor->isTrivial() &&
3598 E->getArg(0)->isTemporaryObject(Ctx.getASTContext(),
3599 T->getAsCXXRecordDecl()))
3600 return this->visitInitializer(E->getArg(0));
3601
3602 // Zero initialization.
3603 bool ZeroInit = E->requiresZeroInitialization();
3604 if (ZeroInit) {
3605 const Record *R = getRecord(E->getType());
3606 if (!R)
3607 return false;
3608
3609 if (!this->visitZeroRecordInitializer(R, E))
3610 return false;
3611
3612 // If the constructor is trivial anyway, we're done.
3613 if (Ctor->isTrivial())
3614 return true;
3615 }
3616
3617 // Avoid materializing a temporary for an elidable copy/move constructor.
3618 if (!ZeroInit && E->isElidable()) {
3619 const Expr *SrcObj = E->getArg(0);
3620 assert(SrcObj->isTemporaryObject(Ctx.getASTContext(), Ctor->getParent()));
3621 assert(Ctx.getASTContext().hasSameUnqualifiedType(E->getType(),
3622 SrcObj->getType()));
3623 if (const auto *ME = dyn_cast<MaterializeTemporaryExpr>(SrcObj)) {
3624 if (!this->emitCheckFunctionDecl(Ctor, E))
3625 return false;
3626 return this->visitInitializer(ME->getSubExpr());
3627 }
3628 }
3629
3630 const Function *Func = getFunction(Ctor);
3631
3632 if (!Func)
3633 return false;
3634
3635 assert(Func->hasThisPointer());
3636 assert(!Func->hasRVO());
3637
3638 // The This pointer is already on the stack because this is an initializer,
3639 // but we need to dup() so the call() below has its own copy.
3640 if (!this->emitDupPtr(E))
3641 return false;
3642
3643 // Constructor arguments.
3644 for (const auto *Arg : E->arguments()) {
3645 if (!this->visit(Arg))
3646 return false;
3647 }
3648
3649 if (Func->isVariadic()) {
3650 uint32_t VarArgSize = 0;
3651 unsigned NumParams = Func->getNumWrittenParams();
3652 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I) {
3653 VarArgSize +=
3654 align(primSize(classify(E->getArg(I)->getType()).value_or(PT_Ptr)));
3655 }
3656 if (!this->emitCallVar(Func, VarArgSize, E))
3657 return false;
3658 } else {
3659 if (!this->emitCall(Func, 0, E)) {
3660 // When discarding, we don't need the result anyway, so clean up
3661 // the instance dup we did earlier in case surrounding code wants
3662 // to keep evaluating.
3663 if (DiscardResult)
3664 (void)this->emitPopPtr(E);
3665 return false;
3666 }
3667 }
3668
3669 if (DiscardResult)
3670 return this->emitPopPtr(E);
3671 return true;
3672 }
3673
3674 if (T->isArrayType()) {
3675 const Function *Func = getFunction(E->getConstructor());
3676 if (!Func)
3677 return false;
3678
3679 if (!this->emitDupPtr(E))
3680 return false;
3681
3682 std::function<bool(QualType)> initArrayDimension;
3683 initArrayDimension = [&](QualType T) -> bool {
3684 if (!T->isArrayType()) {
3685 // Constructor arguments.
3686 for (const auto *Arg : E->arguments()) {
3687 if (!this->visit(Arg))
3688 return false;
3689 }
3690
3691 return this->emitCall(Func, 0, E);
3692 }
3693
3694 const ConstantArrayType *CAT =
3695 Ctx.getASTContext().getAsConstantArrayType(T);
3696 if (!CAT)
3697 return false;
3698 QualType ElemTy = CAT->getElementType();
3699 unsigned NumElems = CAT->getZExtSize();
3700 for (size_t I = 0; I != NumElems; ++I) {
3701 if (!this->emitConstUint64(I, E))
3702 return false;
3703 if (!this->emitArrayElemPtrUint64(E))
3704 return false;
3705 if (!initArrayDimension(ElemTy))
3706 return false;
3707 }
3708 return this->emitPopPtr(E);
3709 };
3710
3711 return initArrayDimension(E->getType());
3712 }
3713
3714 return false;
3715}
3716
3717template <class Emitter>
3719 if (DiscardResult)
3720 return true;
3721
3722 const APValue Val =
3723 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
3724
3725 // Things like __builtin_LINE().
3726 if (E->getType()->isIntegerType()) {
3727 assert(Val.isInt());
3728 const APSInt &I = Val.getInt();
3729 return this->emitConst(I, E);
3730 }
3731 // Otherwise, the APValue is an LValue, with only one element.
3732 // Theoretically, we don't need the APValue at all of course.
3733 assert(E->getType()->isPointerType());
3734 assert(Val.isLValue());
3735 const APValue::LValueBase &Base = Val.getLValueBase();
3736 if (const Expr *LValueExpr = Base.dyn_cast<const Expr *>())
3737 return this->visit(LValueExpr);
3738
3739 // Otherwise, we have a decl (which is the case for
3740 // __builtin_source_location).
3741 assert(Base.is<const ValueDecl *>());
3742 assert(Val.getLValuePath().size() == 0);
3743 const auto *BaseDecl = Base.dyn_cast<const ValueDecl *>();
3744 assert(BaseDecl);
3745
3746 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
3747
3748 UnsignedOrNone GlobalIndex = P.getOrCreateGlobal(UGCD);
3749 if (!GlobalIndex)
3750 return false;
3751
3752 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3753 return false;
3754
3755 const Record *R = getRecord(E->getType());
3756 const APValue &V = UGCD->getValue();
3757 for (unsigned I = 0, N = R->getNumFields(); I != N; ++I) {
3758 const Record::Field *F = R->getField(I);
3759 const APValue &FieldValue = V.getStructField(I);
3760
3761 PrimType FieldT = classifyPrim(F->Decl->getType());
3762
3763 if (!this->visitAPValue(FieldValue, FieldT, E))
3764 return false;
3765 if (!this->emitInitField(FieldT, F->Offset, E))
3766 return false;
3767 }
3768
3769 // Leave the pointer to the global on the stack.
3770 return true;
3771}
3772
3773template <class Emitter>
3775 unsigned N = E->getNumComponents();
3776 if (N == 0)
3777 return false;
3778
3779 for (unsigned I = 0; I != N; ++I) {
3780 const OffsetOfNode &Node = E->getComponent(I);
3781 if (Node.getKind() == OffsetOfNode::Array) {
3782 const Expr *ArrayIndexExpr = E->getIndexExpr(Node.getArrayExprIndex());
3783 PrimType IndexT = classifyPrim(ArrayIndexExpr->getType());
3784
3785 if (DiscardResult) {
3786 if (!this->discard(ArrayIndexExpr))
3787 return false;
3788 continue;
3789 }
3790
3791 if (!this->visit(ArrayIndexExpr))
3792 return false;
3793 // Cast to Sint64.
3794 if (IndexT != PT_Sint64) {
3795 if (!this->emitCast(IndexT, PT_Sint64, E))
3796 return false;
3797 }
3798 }
3799 }
3800
3801 if (DiscardResult)
3802 return true;
3803
3804 PrimType T = classifyPrim(E->getType());
3805 return this->emitOffsetOf(T, E, E);
3806}
3807
3808template <class Emitter>
3810 const CXXScalarValueInitExpr *E) {
3811 QualType Ty = E->getType();
3812
3813 if (DiscardResult || Ty->isVoidType())
3814 return true;
3815
3816 if (OptPrimType T = classify(Ty))
3817 return this->visitZeroInitializer(*T, Ty, E);
3818
3819 if (const auto *CT = Ty->getAs<ComplexType>()) {
3820 if (!Initializing) {
3821 UnsignedOrNone LocalIndex = allocateLocal(E);
3822 if (!LocalIndex)
3823 return false;
3824 if (!this->emitGetPtrLocal(*LocalIndex, E))
3825 return false;
3826 }
3827
3828 // Initialize both fields to 0.
3829 QualType ElemQT = CT->getElementType();
3830 PrimType ElemT = classifyPrim(ElemQT);
3831
3832 for (unsigned I = 0; I != 2; ++I) {
3833 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
3834 return false;
3835 if (!this->emitInitElem(ElemT, I, E))
3836 return false;
3837 }
3838 return true;
3839 }
3840
3841 if (const auto *VT = Ty->getAs<VectorType>()) {
3842 // FIXME: Code duplication with the _Complex case above.
3843 if (!Initializing) {
3844 UnsignedOrNone LocalIndex = allocateLocal(E);
3845 if (!LocalIndex)
3846 return false;
3847 if (!this->emitGetPtrLocal(*LocalIndex, E))
3848 return false;
3849 }
3850
3851 // Initialize all fields to 0.
3852 QualType ElemQT = VT->getElementType();
3853 PrimType ElemT = classifyPrim(ElemQT);
3854
3855 for (unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
3856 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
3857 return false;
3858 if (!this->emitInitElem(ElemT, I, E))
3859 return false;
3860 }
3861 return true;
3862 }
3863
3864 return false;
3865}
3866
3867template <class Emitter>
3869 return this->emitConst(E->getPackLength(), E);
3870}
3871
3872template <class Emitter>
3877
3878template <class Emitter>
3880 return this->delegate(E->getChosenSubExpr());
3881}
3882
3883template <class Emitter>
3885 if (DiscardResult)
3886 return true;
3887
3888 return this->emitConst(E->getValue(), E);
3889}
3890
3891template <class Emitter>
3893 const CXXInheritedCtorInitExpr *E) {
3894 const CXXConstructorDecl *Ctor = E->getConstructor();
3895 assert(!Ctor->isTrivial() &&
3896 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
3897 const Function *F = this->getFunction(Ctor);
3898 assert(F);
3899 assert(!F->hasRVO());
3900 assert(F->hasThisPointer());
3901
3902 if (!this->emitDupPtr(SourceInfo{}))
3903 return false;
3904
3905 // Forward all arguments of the current function (which should be a
3906 // constructor itself) to the inherited ctor.
3907 // This is necessary because the calling code has pushed the pointer
3908 // of the correct base for us already, but the arguments need
3909 // to come after.
3910 unsigned ParamIndex = 0;
3911 for (const ParmVarDecl *PD : Ctor->parameters()) {
3912 PrimType PT = this->classify(PD->getType()).value_or(PT_Ptr);
3913
3914 if (!this->emitGetParam(PT, ParamIndex, E))
3915 return false;
3916 ++ParamIndex;
3917 }
3918
3919 return this->emitCall(F, 0, E);
3920}
3921
3922// FIXME: This function has become rather unwieldy, especially
3923// the part where we initialize an array allocation of dynamic size.
3924template <class Emitter>
3926 assert(classifyPrim(E->getType()) == PT_Ptr);
3927 const Expr *Init = E->getInitializer();
3928 QualType ElementType = E->getAllocatedType();
3929 OptPrimType ElemT = classify(ElementType);
3930 unsigned PlacementArgs = E->getNumPlacementArgs();
3931 const FunctionDecl *OperatorNew = E->getOperatorNew();
3932 const Expr *PlacementDest = nullptr;
3933 bool IsNoThrow = false;
3934
3935 if (E->containsErrors())
3936 return false;
3937
3938 if (PlacementArgs != 0) {
3939 // FIXME: There is no restriction on this, but it's not clear that any
3940 // other form makes any sense. We get here for cases such as:
3941 //
3942 // new (std::align_val_t{N}) X(int)
3943 //
3944 // (which should presumably be valid only if N is a multiple of
3945 // alignof(int), and in any case can't be deallocated unless N is
3946 // alignof(X) and X has new-extended alignment).
3947 if (PlacementArgs == 1) {
3948 const Expr *Arg1 = E->getPlacementArg(0);
3949 if (Arg1->getType()->isNothrowT()) {
3950 if (!this->discard(Arg1))
3951 return false;
3952 IsNoThrow = true;
3953 } else {
3954 // Invalid unless we have C++26 or are in a std:: function.
3955 if (!this->emitInvalidNewDeleteExpr(E, E))
3956 return false;
3957
3958 // If we have a placement-new destination, we'll later use that instead
3959 // of allocating.
3960 if (OperatorNew->isReservedGlobalPlacementOperator())
3961 PlacementDest = Arg1;
3962 }
3963 } else {
3964 // Always invalid.
3965 return this->emitInvalid(E);
3966 }
3967 } else if (!OperatorNew
3968 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
3969 return this->emitInvalidNewDeleteExpr(E, E);
3970
3971 const Descriptor *Desc;
3972 if (!PlacementDest) {
3973 if (ElemT) {
3974 if (E->isArray())
3975 Desc = nullptr; // We're not going to use it in this case.
3976 else
3977 Desc = P.createDescriptor(E, *ElemT, /*SourceTy=*/nullptr,
3979 } else {
3980 Desc = P.createDescriptor(
3981 E, ElementType.getTypePtr(),
3982 E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
3983 /*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false,
3984 /*IsVolatile=*/false, Init);
3985 }
3986 }
3987
3988 if (E->isArray()) {
3989 std::optional<const Expr *> ArraySizeExpr = E->getArraySize();
3990 if (!ArraySizeExpr)
3991 return false;
3992
3993 const Expr *Stripped = *ArraySizeExpr;
3994 for (; auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
3995 Stripped = ICE->getSubExpr())
3996 if (ICE->getCastKind() != CK_NoOp &&
3997 ICE->getCastKind() != CK_IntegralCast)
3998 break;
3999
4000 PrimType SizeT = classifyPrim(Stripped->getType());
4001
4002 // Save evaluated array size to a variable.
4003 unsigned ArrayLen =
4004 allocateLocalPrimitive(Stripped, SizeT, /*IsConst=*/false);
4005 if (!this->visit(Stripped))
4006 return false;
4007 if (!this->emitSetLocal(SizeT, ArrayLen, E))
4008 return false;
4009
4010 if (PlacementDest) {
4011 if (!this->visit(PlacementDest))
4012 return false;
4013 if (!this->emitGetLocal(SizeT, ArrayLen, E))
4014 return false;
4015 if (!this->emitCheckNewTypeMismatchArray(SizeT, E, E))
4016 return false;
4017 } else {
4018 if (!this->emitGetLocal(SizeT, ArrayLen, E))
4019 return false;
4020
4021 if (ElemT) {
4022 // N primitive elements.
4023 if (!this->emitAllocN(SizeT, *ElemT, E, IsNoThrow, E))
4024 return false;
4025 } else {
4026 // N Composite elements.
4027 if (!this->emitAllocCN(SizeT, Desc, IsNoThrow, E))
4028 return false;
4029 }
4030 }
4031
4032 if (Init) {
4033 QualType InitType = Init->getType();
4034 size_t StaticInitElems = 0;
4035 const Expr *DynamicInit = nullptr;
4036 OptPrimType ElemT;
4037
4038 if (const ConstantArrayType *CAT =
4039 Ctx.getASTContext().getAsConstantArrayType(InitType)) {
4040 StaticInitElems = CAT->getZExtSize();
4041 // Initialize the first S element from the initializer.
4042 if (!this->visitInitializer(Init))
4043 return false;
4044
4045 if (const auto *ILE = dyn_cast<InitListExpr>(Init)) {
4046 if (ILE->hasArrayFiller())
4047 DynamicInit = ILE->getArrayFiller();
4048 else if (isa<StringLiteral>(ILE->getInit(0)))
4049 ElemT = classifyPrim(CAT->getElementType());
4050 }
4051 }
4052
4053 // The initializer initializes a certain number of elements, S.
4054 // However, the complete number of elements, N, might be larger than that.
4055 // In this case, we need to get an initializer for the remaining elements.
4056 // There are three cases:
4057 // 1) For the form 'new Struct[n];', the initializer is a
4058 // CXXConstructExpr and its type is an IncompleteArrayType.
4059 // 2) For the form 'new Struct[n]{1,2,3}', the initializer is an
4060 // InitListExpr and the initializer for the remaining elements
4061 // is the array filler.
4062 // 3) StringLiterals don't have an array filler, so we need to zero
4063 // the remaining elements.
4064
4065 if (DynamicInit || ElemT || InitType->isIncompleteArrayType()) {
4066 const Function *CtorFunc = nullptr;
4067 if (const auto *CE = dyn_cast<CXXConstructExpr>(Init)) {
4068 CtorFunc = getFunction(CE->getConstructor());
4069 if (!CtorFunc)
4070 return false;
4071 } else if (!DynamicInit && !ElemT)
4072 DynamicInit = Init;
4073
4074 LabelTy EndLabel = this->getLabel();
4075 LabelTy StartLabel = this->getLabel();
4076
4077 // In the nothrow case, the alloc above might have returned nullptr.
4078 // Don't call any constructors that case.
4079 if (IsNoThrow) {
4080 if (!this->emitDupPtr(E))
4081 return false;
4082 if (!this->emitNullPtr(0, nullptr, E))
4083 return false;
4084 if (!this->emitEQPtr(E))
4085 return false;
4086 if (!this->jumpTrue(EndLabel, E))
4087 return false;
4088 }
4089
4090 // Create loop variables.
4091 unsigned Iter =
4092 allocateLocalPrimitive(Stripped, SizeT, /*IsConst=*/false);
4093 if (!this->emitConst(StaticInitElems, SizeT, E))
4094 return false;
4095 if (!this->emitSetLocal(SizeT, Iter, E))
4096 return false;
4097
4098 this->fallthrough(StartLabel);
4099 this->emitLabel(StartLabel);
4100 // Condition. Iter < ArrayLen?
4101 if (!this->emitGetLocal(SizeT, Iter, E))
4102 return false;
4103 if (!this->emitGetLocal(SizeT, ArrayLen, E))
4104 return false;
4105 if (!this->emitLT(SizeT, E))
4106 return false;
4107 if (!this->jumpFalse(EndLabel, E))
4108 return false;
4109
4110 // Pointer to the allocated array is already on the stack.
4111 if (!this->emitGetLocal(SizeT, Iter, E))
4112 return false;
4113 if (!this->emitArrayElemPtr(SizeT, E))
4114 return false;
4115
4116 if (isa_and_nonnull<ImplicitValueInitExpr>(DynamicInit) &&
4117 DynamicInit->getType()->isArrayType()) {
4118 QualType ElemType =
4119 DynamicInit->getType()->getAsArrayTypeUnsafe()->getElementType();
4120 PrimType InitT = classifyPrim(ElemType);
4121 if (!this->visitZeroInitializer(InitT, ElemType, E))
4122 return false;
4123 if (!this->emitStorePop(InitT, E))
4124 return false;
4125 } else if (DynamicInit) {
4126 if (OptPrimType InitT = classify(DynamicInit)) {
4127 if (!this->visit(DynamicInit))
4128 return false;
4129 if (!this->emitStorePop(*InitT, E))
4130 return false;
4131 } else {
4132 if (!this->visitInitializerPop(DynamicInit))
4133 return false;
4134 }
4135 } else if (ElemT) {
4136 if (!this->visitZeroInitializer(
4137 *ElemT, InitType->getAsArrayTypeUnsafe()->getElementType(),
4138 Init))
4139 return false;
4140 if (!this->emitStorePop(*ElemT, E))
4141 return false;
4142 } else {
4143 assert(CtorFunc);
4144 if (!this->emitCall(CtorFunc, 0, E))
4145 return false;
4146 }
4147
4148 // ++Iter;
4149 if (!this->emitGetPtrLocal(Iter, E))
4150 return false;
4151 if (!this->emitIncPop(SizeT, false, E))
4152 return false;
4153
4154 if (!this->jump(StartLabel, E))
4155 return false;
4156
4157 this->fallthrough(EndLabel);
4158 this->emitLabel(EndLabel);
4159 }
4160 }
4161 } else { // Non-array.
4162 if (PlacementDest) {
4163 if (!this->visit(PlacementDest))
4164 return false;
4165 if (!this->emitCheckNewTypeMismatch(E, E))
4166 return false;
4167
4168 } else {
4169 // Allocate just one element.
4170 if (!this->emitAlloc(Desc, E))
4171 return false;
4172 }
4173
4174 if (Init) {
4175 if (ElemT) {
4176 if (!this->visit(Init))
4177 return false;
4178
4179 if (!this->emitInit(*ElemT, E))
4180 return false;
4181 } else {
4182 // Composite.
4183 if (!this->visitInitializer(Init))
4184 return false;
4185 }
4186 }
4187 }
4188
4189 if (DiscardResult)
4190 return this->emitPopPtr(E);
4191
4192 return true;
4193}
4194
4195template <class Emitter>
4197 if (E->containsErrors())
4198 return false;
4199 const FunctionDecl *OperatorDelete = E->getOperatorDelete();
4200
4201 if (!OperatorDelete->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4202 return this->emitInvalidNewDeleteExpr(E, E);
4203
4204 // Arg must be an lvalue.
4205 if (!this->visit(E->getArgument()))
4206 return false;
4207
4208 return this->emitFree(E->isArrayForm(), E->isGlobalDelete(), E);
4209}
4210
4211template <class Emitter>
4213 if (DiscardResult)
4214 return true;
4215
4216 const Function *Func = nullptr;
4217 if (const Function *F = Ctx.getOrCreateObjCBlock(E))
4218 Func = F;
4219
4220 if (!Func)
4221 return false;
4222 return this->emitGetFnPtr(Func, E);
4223}
4224
4225template <class Emitter>
4227 const Type *TypeInfoType = E->getType().getTypePtr();
4228
4229 auto canonType = [](const Type *T) {
4230 return T->getCanonicalTypeUnqualified().getTypePtr();
4231 };
4232
4233 if (!E->isPotentiallyEvaluated()) {
4234 if (DiscardResult)
4235 return true;
4236
4237 if (E->isTypeOperand())
4238 return this->emitGetTypeid(
4239 canonType(E->getTypeOperand(Ctx.getASTContext()).getTypePtr()),
4240 TypeInfoType, E);
4241
4242 return this->emitGetTypeid(
4243 canonType(E->getExprOperand()->getType().getTypePtr()), TypeInfoType,
4244 E);
4245 }
4246
4247 // Otherwise, we need to evaluate the expression operand.
4248 assert(E->getExprOperand());
4249 assert(E->getExprOperand()->isLValue());
4250
4251 if (!Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(E))
4252 return false;
4253
4254 if (!this->visit(E->getExprOperand()))
4255 return false;
4256
4257 if (!this->emitGetTypeidPtr(TypeInfoType, E))
4258 return false;
4259 if (DiscardResult)
4260 return this->emitPopPtr(E);
4261 return true;
4262}
4263
4264template <class Emitter>
4266 const ObjCDictionaryLiteral *E) {
4268 return this->emitDummyPtr(E, E);
4269 return this->emitError(E);
4270}
4271
4272template <class Emitter>
4275 return this->emitDummyPtr(E, E);
4276 return this->emitError(E);
4277}
4278
4279template <class Emitter>
4281 assert(Ctx.getLangOpts().CPlusPlus);
4282 return this->emitConstBool(E->getValue(), E);
4283}
4284
4285template <class Emitter>
4287 if (DiscardResult)
4288 return true;
4289 assert(!Initializing);
4290
4291 const MSGuidDecl *GuidDecl = E->getGuidDecl();
4292 const RecordDecl *RD = GuidDecl->getType()->getAsRecordDecl();
4293 assert(RD);
4294 // If the definiton of the result type is incomplete, just return a dummy.
4295 // If (and when) that is read from, we will fail, but not now.
4296 if (!RD->isCompleteDefinition())
4297 return this->emitDummyPtr(GuidDecl, E);
4298
4299 UnsignedOrNone GlobalIndex = P.getOrCreateGlobal(GuidDecl);
4300 if (!GlobalIndex)
4301 return false;
4302 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4303 return false;
4304
4305 assert(this->getRecord(E->getType()));
4306
4307 const APValue &V = GuidDecl->getAsAPValue();
4308 if (V.getKind() == APValue::None)
4309 return true;
4310
4311 assert(V.isStruct());
4312 assert(V.getStructNumBases() == 0);
4313 if (!this->visitAPValueInitializer(V, E, E->getType()))
4314 return false;
4315
4316 return this->emitFinishInit(E);
4317}
4318
4319template <class Emitter>
4321 assert(classifyPrim(E->getType()) == PT_Bool);
4322 if (E->isValueDependent())
4323 return false;
4324 if (DiscardResult)
4325 return true;
4326 return this->emitConstBool(E->isSatisfied(), E);
4327}
4328
4329template <class Emitter>
4331 const ConceptSpecializationExpr *E) {
4332 assert(classifyPrim(E->getType()) == PT_Bool);
4333 if (DiscardResult)
4334 return true;
4335 return this->emitConstBool(E->isSatisfied(), E);
4336}
4337
4338template <class Emitter>
4343
4344template <class Emitter>
4346
4347 for (const Expr *SemE : E->semantics()) {
4348 if (auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
4349 if (SemE == E->getResultExpr())
4350 return false;
4351
4352 if (OVE->isUnique())
4353 continue;
4354
4355 if (!this->discard(OVE))
4356 return false;
4357 } else if (SemE == E->getResultExpr()) {
4358 if (!this->delegate(SemE))
4359 return false;
4360 } else {
4361 if (!this->discard(SemE))
4362 return false;
4363 }
4364 }
4365 return true;
4366}
4367
4368template <class Emitter>
4372
4373template <class Emitter>
4375 return this->emitError(E);
4376}
4377
4378template <class Emitter>
4380 assert(E->getType()->isVoidPointerType());
4381 if (DiscardResult)
4382 return true;
4383
4384 return this->emitDummyPtr(E, E);
4385}
4386
4387template <class Emitter>
4389 assert(Initializing);
4390 const auto *VT = E->getType()->castAs<VectorType>();
4391 QualType ElemType = VT->getElementType();
4392 PrimType ElemT = classifyPrim(ElemType);
4393 const Expr *Src = E->getSrcExpr();
4394 QualType SrcType = Src->getType();
4395 PrimType SrcElemT = classifyVectorElementType(SrcType);
4396
4397 unsigned SrcOffset =
4398 this->allocateLocalPrimitive(Src, PT_Ptr, /*IsConst=*/true);
4399 if (!this->visit(Src))
4400 return false;
4401 if (!this->emitSetLocal(PT_Ptr, SrcOffset, E))
4402 return false;
4403
4404 for (unsigned I = 0; I != VT->getNumElements(); ++I) {
4405 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
4406 return false;
4407 if (!this->emitArrayElemPop(SrcElemT, I, E))
4408 return false;
4409
4410 // Cast to the desired result element type.
4411 if (SrcElemT != ElemT) {
4412 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
4413 return false;
4414 } else if (ElemType->isFloatingType() && SrcType != ElemType) {
4415 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
4416 if (!this->emitCastFP(TargetSemantics, getRoundingMode(E), E))
4417 return false;
4418 }
4419 if (!this->emitInitElem(ElemT, I, E))
4420 return false;
4421 }
4422
4423 return true;
4424}
4425
4426template <class Emitter>
4428 // FIXME: Unary shuffle with mask not currently supported.
4429 if (E->getNumSubExprs() == 2)
4430 return this->emitInvalid(E);
4431
4432 assert(E->getNumSubExprs() > 2);
4433
4434 const Expr *Vecs[] = {E->getExpr(0), E->getExpr(1)};
4435 const VectorType *VT = Vecs[0]->getType()->castAs<VectorType>();
4436 PrimType ElemT = classifyPrim(VT->getElementType());
4437 unsigned NumInputElems = VT->getNumElements();
4438 unsigned NumOutputElems = E->getNumSubExprs() - 2;
4439 assert(NumOutputElems > 0);
4440
4441 if (!Initializing) {
4442 UnsignedOrNone LocalIndex = allocateLocal(E);
4443 if (!LocalIndex)
4444 return false;
4445 if (!this->emitGetPtrLocal(*LocalIndex, E))
4446 return false;
4447 }
4448
4449 // Save both input vectors to a local variable.
4450 unsigned VectorOffsets[2];
4451 for (unsigned I = 0; I != 2; ++I) {
4452 VectorOffsets[I] =
4453 this->allocateLocalPrimitive(Vecs[I], PT_Ptr, /*IsConst=*/true);
4454 if (!this->visit(Vecs[I]))
4455 return false;
4456 if (!this->emitSetLocal(PT_Ptr, VectorOffsets[I], E))
4457 return false;
4458 }
4459 for (unsigned I = 0; I != NumOutputElems; ++I) {
4460 APSInt ShuffleIndex = E->getShuffleMaskIdx(I);
4461 assert(ShuffleIndex >= -1);
4462 if (ShuffleIndex == -1)
4463 return this->emitInvalidShuffleVectorIndex(I, E);
4464
4465 assert(ShuffleIndex < (NumInputElems * 2));
4466 if (!this->emitGetLocal(PT_Ptr,
4467 VectorOffsets[ShuffleIndex >= NumInputElems], E))
4468 return false;
4469 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
4470 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
4471 return false;
4472
4473 if (!this->emitInitElem(ElemT, I, E))
4474 return false;
4475 }
4476
4477 if (DiscardResult)
4478 return this->emitPopPtr(E);
4479
4480 return true;
4481}
4482
4483template <class Emitter>
4485 const ExtVectorElementExpr *E) {
4486 const Expr *Base = E->getBase();
4487 assert(
4488 Base->getType()->isVectorType() ||
4489 Base->getType()->getAs<PointerType>()->getPointeeType()->isVectorType());
4490
4492 E->getEncodedElementAccess(Indices);
4493
4494 if (Indices.size() == 1) {
4495 if (!this->visit(Base))
4496 return false;
4497
4498 if (E->isGLValue()) {
4499 if (!this->emitConstUint32(Indices[0], E))
4500 return false;
4501 return this->emitArrayElemPtrPop(PT_Uint32, E);
4502 }
4503 // Else, also load the value.
4504 return this->emitArrayElemPop(classifyPrim(E->getType()), Indices[0], E);
4505 }
4506
4507 // Create a local variable for the base.
4508 unsigned BaseOffset = allocateLocalPrimitive(Base, PT_Ptr, /*IsConst=*/true);
4509 if (!this->visit(Base))
4510 return false;
4511 if (!this->emitSetLocal(PT_Ptr, BaseOffset, E))
4512 return false;
4513
4514 // Now the vector variable for the return value.
4515 if (!Initializing) {
4516 UnsignedOrNone ResultIndex = allocateLocal(E);
4517 if (!ResultIndex)
4518 return false;
4519 if (!this->emitGetPtrLocal(*ResultIndex, E))
4520 return false;
4521 }
4522
4523 assert(Indices.size() == E->getType()->getAs<VectorType>()->getNumElements());
4524
4525 PrimType ElemT =
4527 uint32_t DstIndex = 0;
4528 for (uint32_t I : Indices) {
4529 if (!this->emitGetLocal(PT_Ptr, BaseOffset, E))
4530 return false;
4531 if (!this->emitArrayElemPop(ElemT, I, E))
4532 return false;
4533 if (!this->emitInitElem(ElemT, DstIndex, E))
4534 return false;
4535 ++DstIndex;
4536 }
4537
4538 // Leave the result pointer on the stack.
4539 assert(!DiscardResult);
4540 return true;
4541}
4542
4543template <class Emitter>
4545 const Expr *SubExpr = E->getSubExpr();
4547 return this->discard(SubExpr) && this->emitInvalid(E);
4548
4549 if (DiscardResult)
4550 return true;
4551
4552 assert(classifyPrim(E) == PT_Ptr);
4553 return this->emitDummyPtr(E, E);
4554}
4555
4556template <class Emitter>
4558 const CXXStdInitializerListExpr *E) {
4559 const Expr *SubExpr = E->getSubExpr();
4561 Ctx.getASTContext().getAsConstantArrayType(SubExpr->getType());
4562 const Record *R = getRecord(E->getType());
4563 assert(Initializing);
4564 assert(SubExpr->isGLValue());
4565
4566 if (!this->visit(SubExpr))
4567 return false;
4568 if (!this->emitConstUint8(0, E))
4569 return false;
4570 if (!this->emitArrayElemPtrPopUint8(E))
4571 return false;
4572 if (!this->emitInitFieldPtr(R->getField(0u)->Offset, E))
4573 return false;
4574
4575 PrimType SecondFieldT = classifyPrim(R->getField(1u)->Decl->getType());
4576 if (isIntegerOrBoolType(SecondFieldT)) {
4577 if (!this->emitConst(ArrayType->getSize(), SecondFieldT, E))
4578 return false;
4579 return this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E);
4580 }
4581 assert(SecondFieldT == PT_Ptr);
4582
4583 if (!this->emitGetFieldPtr(R->getField(0u)->Offset, E))
4584 return false;
4585 if (!this->emitExpandPtr(E))
4586 return false;
4587 if (!this->emitConst(ArrayType->getSize(), PT_Uint64, E))
4588 return false;
4589 if (!this->emitArrayElemPtrPop(PT_Uint64, E))
4590 return false;
4591 return this->emitInitFieldPtr(R->getField(1u)->Offset, E);
4592}
4593
4594template <class Emitter>
4596 LocalScope<Emitter> BS(this);
4597 StmtExprScope<Emitter> SS(this);
4598
4599 const CompoundStmt *CS = E->getSubStmt();
4600 const Stmt *Result = CS->body_back();
4601 for (const Stmt *S : CS->body()) {
4602 if (S != Result) {
4603 if (!this->visitStmt(S))
4604 return false;
4605 continue;
4606 }
4607
4608 assert(S == Result);
4609 if (const Expr *ResultExpr = dyn_cast<Expr>(S))
4610 return this->delegate(ResultExpr);
4611 return this->emitUnsupported(E);
4612 }
4613
4614 return BS.destroyLocals();
4615}
4616
4617template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {
4618 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
4619 /*NewInitializing=*/false, /*ToLValue=*/false);
4620 return this->Visit(E);
4621}
4622
4623template <class Emitter> bool Compiler<Emitter>::delegate(const Expr *E) {
4624 // We're basically doing:
4625 // OptionScope<Emitter> Scope(this, DicardResult, Initializing, ToLValue);
4626 // but that's unnecessary of course.
4627 return this->Visit(E);
4628}
4629
4631 if (const auto *PE = dyn_cast<ParenExpr>(E))
4632 return stripCheckedDerivedToBaseCasts(PE->getSubExpr());
4633
4634 if (const auto *CE = dyn_cast<CastExpr>(E);
4635 CE &&
4636 (CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp))
4637 return stripCheckedDerivedToBaseCasts(CE->getSubExpr());
4638
4639 return E;
4640}
4641
4642static const Expr *stripDerivedToBaseCasts(const Expr *E) {
4643 if (const auto *PE = dyn_cast<ParenExpr>(E))
4644 return stripDerivedToBaseCasts(PE->getSubExpr());
4645
4646 if (const auto *CE = dyn_cast<CastExpr>(E);
4647 CE && (CE->getCastKind() == CK_DerivedToBase ||
4648 CE->getCastKind() == CK_UncheckedDerivedToBase ||
4649 CE->getCastKind() == CK_NoOp))
4650 return stripDerivedToBaseCasts(CE->getSubExpr());
4651
4652 return E;
4653}
4654
4655template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) {
4656 if (E->getType().isNull())
4657 return false;
4658
4659 if (E->getType()->isVoidType())
4660 return this->discard(E);
4661
4662 // Create local variable to hold the return value.
4663 if (!E->isGLValue() && !canClassify(E->getType())) {
4664 UnsignedOrNone LocalIndex = allocateLocal(
4666 if (!LocalIndex)
4667 return false;
4668
4669 if (!this->emitGetPtrLocal(*LocalIndex, E))
4670 return false;
4671 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
4672 return this->visitInitializer(E);
4673 }
4674
4675 // Otherwise,we have a primitive return value, produce the value directly
4676 // and push it on the stack.
4677 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
4678 /*NewInitializing=*/false, /*ToLValue=*/ToLValue);
4679 return this->Visit(E);
4680}
4681
4682template <class Emitter>
4684 assert(!canClassify(E->getType()));
4685
4686 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
4687 /*NewInitializing=*/true, /*ToLValue=*/false);
4688 return this->Visit(E) && this->emitFinishInit(E);
4689}
4690
4691template <class Emitter>
4693 assert(!canClassify(E->getType()));
4694
4695 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
4696 /*NewInitializing=*/true, /*ToLValue=*/false);
4697 return this->Visit(E) && this->emitFinishInitPop(E);
4698}
4699
4700template <class Emitter> bool Compiler<Emitter>::visitAsLValue(const Expr *E) {
4701 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
4702 /*NewInitializing=*/false, /*ToLValue=*/true);
4703 return this->Visit(E);
4704}
4705
4706template <class Emitter> bool Compiler<Emitter>::visitBool(const Expr *E) {
4707 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
4708 /*NewInitializing=*/false, /*ToLValue=*/ToLValue);
4709
4710 OptPrimType T = classify(E->getType());
4711 if (!T) {
4712 // Convert complex values to bool.
4713 if (E->getType()->isAnyComplexType()) {
4714 if (!this->visit(E))
4715 return false;
4716 return this->emitComplexBoolCast(E);
4717 }
4718 return false;
4719 }
4720
4721 if (!this->visit(E))
4722 return false;
4723
4724 if (T == PT_Bool)
4725 return true;
4726
4727 // Convert pointers to bool.
4728 if (T == PT_Ptr)
4729 return this->emitIsNonNullPtr(E);
4730
4731 // Or Floats.
4732 if (T == PT_Float)
4733 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
4734
4735 // Or anything else we can.
4736 return this->emitCast(*T, PT_Bool, E);
4737}
4738
4739template <class Emitter>
4740bool Compiler<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
4741 const Expr *E) {
4742 if (const auto *AT = QT->getAs<AtomicType>())
4743 QT = AT->getValueType();
4744
4745 switch (T) {
4746 case PT_Bool:
4747 return this->emitZeroBool(E);
4748 case PT_Sint8:
4749 return this->emitZeroSint8(E);
4750 case PT_Uint8:
4751 return this->emitZeroUint8(E);
4752 case PT_Sint16:
4753 return this->emitZeroSint16(E);
4754 case PT_Uint16:
4755 return this->emitZeroUint16(E);
4756 case PT_Sint32:
4757 return this->emitZeroSint32(E);
4758 case PT_Uint32:
4759 return this->emitZeroUint32(E);
4760 case PT_Sint64:
4761 return this->emitZeroSint64(E);
4762 case PT_Uint64:
4763 return this->emitZeroUint64(E);
4764 case PT_IntAP:
4765 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
4766 case PT_IntAPS:
4767 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
4768 case PT_Ptr:
4769 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
4770 nullptr, E);
4771 case PT_MemberPtr:
4772 return this->emitNullMemberPtr(0, nullptr, E);
4773 case PT_Float: {
4774 APFloat F = APFloat::getZero(Ctx.getFloatSemantics(QT));
4775 return this->emitFloat(F, E);
4776 }
4777 case PT_FixedPoint: {
4778 auto Sem = Ctx.getASTContext().getFixedPointSemantics(QT);
4779 return this->emitConstFixedPoint(FixedPoint::zero(Sem), E);
4780 }
4781 }
4782 llvm_unreachable("unknown primitive type");
4783}
4784
4785template <class Emitter>
4786bool Compiler<Emitter>::visitZeroRecordInitializer(const Record *R,
4787 const Expr *E) {
4788 assert(E);
4789 assert(R);
4790 // Fields
4791 for (const Record::Field &Field : R->fields()) {
4792 if (Field.isUnnamedBitField())
4793 continue;
4794
4795 const Descriptor *D = Field.Desc;
4796 if (D->isPrimitive()) {
4797 QualType QT = D->getType();
4798 PrimType T = D->getPrimType();
4799 if (!this->visitZeroInitializer(T, QT, E))
4800 return false;
4801 if (R->isUnion()) {
4802 if (!this->emitInitFieldActivate(T, Field.Offset, E))
4803 return false;
4804 break;
4805 }
4806 if (!this->emitInitField(T, Field.Offset, E))
4807 return false;
4808 continue;
4809 }
4810
4811 if (!this->emitGetPtrField(Field.Offset, E))
4812 return false;
4813
4814 if (D->isPrimitiveArray()) {
4815 QualType ET = D->getElemQualType();
4816 PrimType T = D->getPrimType();
4817 for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
4818 if (!this->visitZeroInitializer(T, ET, E))
4819 return false;
4820 if (!this->emitInitElem(T, I, E))
4821 return false;
4822 }
4823 } else if (D->isCompositeArray()) {
4824 // Can't be a vector or complex field.
4825 if (!this->visitZeroArrayInitializer(D->getType(), E))
4826 return false;
4827 } else if (D->isRecord()) {
4828 if (!this->visitZeroRecordInitializer(D->ElemRecord, E))
4829 return false;
4830 } else
4831 return false;
4832
4833 // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the
4834 // object's first non-static named data member is zero-initialized
4835 if (R->isUnion()) {
4836 if (!this->emitFinishInitActivatePop(E))
4837 return false;
4838 break;
4839 }
4840 if (!this->emitFinishInitPop(E))
4841 return false;
4842 }
4843
4844 for (const Record::Base &B : R->bases()) {
4845 if (!this->emitGetPtrBase(B.Offset, E))
4846 return false;
4847 if (!this->visitZeroRecordInitializer(B.R, E))
4848 return false;
4849 if (!this->emitFinishInitPop(E))
4850 return false;
4851 }
4852
4853 // FIXME: Virtual bases.
4854
4855 return true;
4856}
4857
4858template <class Emitter>
4859bool Compiler<Emitter>::visitZeroArrayInitializer(QualType T, const Expr *E) {
4860 assert(T->isArrayType() || T->isAnyComplexType() || T->isVectorType());
4861 const ArrayType *AT = T->getAsArrayTypeUnsafe();
4862 QualType ElemType = AT->getElementType();
4863 size_t NumElems = cast<ConstantArrayType>(AT)->getZExtSize();
4864
4865 if (OptPrimType ElemT = classify(ElemType)) {
4866 for (size_t I = 0; I != NumElems; ++I) {
4867 if (!this->visitZeroInitializer(*ElemT, ElemType, E))
4868 return false;
4869 if (!this->emitInitElem(*ElemT, I, E))
4870 return false;
4871 }
4872 return true;
4873 }
4874 if (ElemType->isRecordType()) {
4875 const Record *R = getRecord(ElemType);
4876 if (!R)
4877 return false;
4878
4879 for (size_t I = 0; I != NumElems; ++I) {
4880 if (!this->emitConstUint32(I, E))
4881 return false;
4882 if (!this->emitArrayElemPtr(PT_Uint32, E))
4883 return false;
4884 if (!this->visitZeroRecordInitializer(R, E))
4885 return false;
4886 if (!this->emitPopPtr(E))
4887 return false;
4888 }
4889 return true;
4890 }
4891 if (ElemType->isArrayType()) {
4892 for (size_t I = 0; I != NumElems; ++I) {
4893 if (!this->emitConstUint32(I, E))
4894 return false;
4895 if (!this->emitArrayElemPtr(PT_Uint32, E))
4896 return false;
4897 if (!this->visitZeroArrayInitializer(ElemType, E))
4898 return false;
4899 if (!this->emitPopPtr(E))
4900 return false;
4901 }
4902 return true;
4903 }
4904
4905 return false;
4906}
4907
4908template <class Emitter>
4909bool Compiler<Emitter>::visitAssignment(const Expr *LHS, const Expr *RHS,
4910 const Expr *E) {
4911 if (!canClassify(E->getType()))
4912 return false;
4913
4914 if (!this->visit(RHS))
4915 return false;
4916 if (!this->visit(LHS))
4917 return false;
4918
4919 if (LHS->getType().isVolatileQualified())
4920 return this->emitInvalidStore(LHS->getType().getTypePtr(), E);
4921
4922 // We don't support assignments in C.
4923 if (!Ctx.getLangOpts().CPlusPlus && !this->emitInvalid(E))
4924 return false;
4925
4926 PrimType RHT = classifyPrim(RHS);
4927 bool Activates = refersToUnion(LHS);
4928 bool BitField = LHS->refersToBitField();
4929
4930 if (!this->emitFlip(PT_Ptr, RHT, E))
4931 return false;
4932
4933 if (DiscardResult) {
4934 if (BitField && Activates)
4935 return this->emitStoreBitFieldActivatePop(RHT, E);
4936 if (BitField)
4937 return this->emitStoreBitFieldPop(RHT, E);
4938 if (Activates)
4939 return this->emitStoreActivatePop(RHT, E);
4940 // Otherwise, regular non-activating store.
4941 return this->emitStorePop(RHT, E);
4942 }
4943
4944 auto maybeLoad = [&](bool Result) -> bool {
4945 if (!Result)
4946 return false;
4947 // Assignments aren't necessarily lvalues in C.
4948 // Load from them in that case.
4949 if (!E->isLValue())
4950 return this->emitLoadPop(RHT, E);
4951 return true;
4952 };
4953
4954 if (BitField && Activates)
4955 return maybeLoad(this->emitStoreBitFieldActivate(RHT, E));
4956 if (BitField)
4957 return maybeLoad(this->emitStoreBitField(RHT, E));
4958 if (Activates)
4959 return maybeLoad(this->emitStoreActivate(RHT, E));
4960 // Otherwise, regular non-activating store.
4961 return maybeLoad(this->emitStore(RHT, E));
4962}
4963
4964template <class Emitter>
4965template <typename T>
4966bool Compiler<Emitter>::emitConst(T Value, PrimType Ty, const Expr *E) {
4967 switch (Ty) {
4968 case PT_Sint8:
4969 return this->emitConstSint8(Value, E);
4970 case PT_Uint8:
4971 return this->emitConstUint8(Value, E);
4972 case PT_Sint16:
4973 return this->emitConstSint16(Value, E);
4974 case PT_Uint16:
4975 return this->emitConstUint16(Value, E);
4976 case PT_Sint32:
4977 return this->emitConstSint32(Value, E);
4978 case PT_Uint32:
4979 return this->emitConstUint32(Value, E);
4980 case PT_Sint64:
4981 return this->emitConstSint64(Value, E);
4982 case PT_Uint64:
4983 return this->emitConstUint64(Value, E);
4984 case PT_Bool:
4985 return this->emitConstBool(Value, E);
4986 case PT_Ptr:
4987 case PT_MemberPtr:
4988 case PT_Float:
4989 case PT_IntAP:
4990 case PT_IntAPS:
4991 case PT_FixedPoint:
4992 llvm_unreachable("Invalid integral type");
4993 break;
4994 }
4995 llvm_unreachable("unknown primitive type");
4996}
4997
4998template <class Emitter>
4999template <typename T>
5000bool Compiler<Emitter>::emitConst(T Value, const Expr *E) {
5001 return this->emitConst(Value, classifyPrim(E->getType()), E);
5002}
5003
5004template <class Emitter>
5005bool Compiler<Emitter>::emitConst(const APSInt &Value, PrimType Ty,
5006 const Expr *E) {
5007 if (Ty == PT_IntAPS)
5008 return this->emitConstIntAPS(Value, E);
5009 if (Ty == PT_IntAP)
5010 return this->emitConstIntAP(Value, E);
5011
5012 if (Value.isSigned())
5013 return this->emitConst(Value.getSExtValue(), Ty, E);
5014 return this->emitConst(Value.getZExtValue(), Ty, E);
5015}
5016
5017template <class Emitter>
5018bool Compiler<Emitter>::emitConst(const APInt &Value, PrimType Ty,
5019 const Expr *E) {
5020 if (Ty == PT_IntAPS)
5021 return this->emitConstIntAPS(Value, E);
5022 if (Ty == PT_IntAP)
5023 return this->emitConstIntAP(Value, E);
5024
5025 if (isSignedType(Ty))
5026 return this->emitConst(Value.getSExtValue(), Ty, E);
5027 return this->emitConst(Value.getZExtValue(), Ty, E);
5028}
5029
5030template <class Emitter>
5031bool Compiler<Emitter>::emitConst(const APSInt &Value, const Expr *E) {
5032 return this->emitConst(Value, classifyPrim(E->getType()), E);
5033}
5034
5035template <class Emitter>
5037 bool IsConst,
5038 bool IsVolatile,
5039 ScopeKind SC) {
5040 // FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
5041 // (int){12} in C. Consider using Expr::isTemporaryObject() instead
5042 // or isa<MaterializeTemporaryExpr>().
5043 Descriptor *D = P.createDescriptor(Src, Ty, nullptr, Descriptor::InlineDescMD,
5044 IsConst, isa<const Expr *>(Src),
5045 /*IsMutable=*/false, IsVolatile);
5047 Scope::Local Local = this->createLocal(D);
5048 if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>()))
5049 Locals.insert({VD, Local});
5050 VarScope->addForScopeKind(Local, SC);
5051 return Local.Offset;
5052}
5053
5054template <class Emitter>
5056 ScopeKind SC) {
5057 const ValueDecl *Key = nullptr;
5058 const Expr *Init = nullptr;
5059 bool IsTemporary = false;
5060 if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
5061 Key = VD;
5062
5063 if (const auto *VarD = dyn_cast<VarDecl>(VD))
5064 Init = VarD->getInit();
5065 }
5066 if (auto *E = Src.dyn_cast<const Expr *>()) {
5067 IsTemporary = true;
5068 if (Ty.isNull())
5069 Ty = E->getType();
5070 }
5071
5072 Descriptor *D = P.createDescriptor(
5074 IsTemporary, /*IsMutable=*/false, /*IsVolatile=*/Ty.isVolatileQualified(),
5075 Init);
5076 if (!D)
5077 return std::nullopt;
5079
5080 Scope::Local Local = this->createLocal(D);
5081 if (Key)
5082 Locals.insert({Key, Local});
5083 VarScope->addForScopeKind(Local, SC);
5084 return Local.Offset;
5085}
5086
5087template <class Emitter>
5089 QualType Ty = E->getType();
5090 assert(!Ty->isRecordType());
5091
5092 Descriptor *D = P.createDescriptor(
5094 /*IsTemporary=*/true);
5095
5096 if (!D)
5097 return std::nullopt;
5098
5099 Scope::Local Local = this->createLocal(D);
5101 assert(S);
5102 // Attach to topmost scope.
5103 while (S->getParent())
5104 S = S->getParent();
5105 assert(S && !S->getParent());
5106 S->addLocal(Local);
5107 return Local.Offset;
5108}
5109
5110template <class Emitter>
5112 if (const PointerType *PT = dyn_cast<PointerType>(Ty))
5113 return PT->getPointeeType()->getAsCanonical<RecordType>();
5114 return Ty->getAsCanonical<RecordType>();
5115}
5116
5117template <class Emitter> Record *Compiler<Emitter>::getRecord(QualType Ty) {
5118 if (const auto *RecordTy = getRecordTy(Ty))
5119 return getRecord(RecordTy->getDecl()->getDefinitionOrSelf());
5120 return nullptr;
5121}
5122
5123template <class Emitter>
5125 return P.getOrCreateRecord(RD);
5126}
5127
5128template <class Emitter>
5130 return Ctx.getOrCreateFunction(FD);
5131}
5132
5133template <class Emitter>
5134bool Compiler<Emitter>::visitExpr(const Expr *E, bool DestroyToplevelScope) {
5136
5137 auto maybeDestroyLocals = [&]() -> bool {
5138 if (DestroyToplevelScope)
5139 return RootScope.destroyLocals() && this->emitCheckAllocations(E);
5140 return this->emitCheckAllocations(E);
5141 };
5142
5143 // Void expressions.
5144 if (E->getType()->isVoidType()) {
5145 if (!visit(E))
5146 return false;
5147 return this->emitRetVoid(E) && maybeDestroyLocals();
5148 }
5149
5150 // Expressions with a primitive return type.
5151 if (OptPrimType T = classify(E)) {
5152 if (!visit(E))
5153 return false;
5154
5155 return this->emitRet(*T, E) && maybeDestroyLocals();
5156 }
5157
5158 // Expressions with a composite return type.
5159 // For us, that means everything we don't
5160 // have a PrimType for.
5161 if (UnsignedOrNone LocalOffset = this->allocateLocal(E)) {
5162 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalOffset));
5163 if (!this->emitGetPtrLocal(*LocalOffset, E))
5164 return false;
5165
5166 if (!visitInitializer(E))
5167 return false;
5168 // We are destroying the locals AFTER the Ret op.
5169 // The Ret op needs to copy the (alive) values, but the
5170 // destructors may still turn the entire expression invalid.
5171 return this->emitRetValue(E) && maybeDestroyLocals();
5172 }
5173
5174 return maybeDestroyLocals() && false;
5175}
5176
5177template <class Emitter>
5179 bool DestroyToplevelScope) {
5180 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
5181 /*NewInitializing=*/false, /*ToLValue=*/true);
5182
5183 return this->visitExpr(E, DestroyToplevelScope);
5184}
5185
5186template <class Emitter>
5188
5189 auto R = this->visitVarDecl(VD, VD->getInit(), /*Toplevel=*/true);
5190
5191 if (R.notCreated())
5192 return R;
5193
5194 if (R)
5195 return true;
5196
5197 if (!R && Context::shouldBeGloballyIndexed(VD)) {
5198 if (auto GlobalIndex = P.getGlobal(VD)) {
5199 Block *GlobalBlock = P.getGlobal(*GlobalIndex);
5200 auto &GD = GlobalBlock->getBlockDesc<GlobalInlineDescriptor>();
5201
5203 GlobalBlock->invokeDtor();
5204 }
5205 }
5206
5207 return R;
5208}
5209
5210/// Toplevel visitDeclAndReturn().
5211/// We get here from evaluateAsInitializer().
5212/// We need to evaluate the initializer and return its value.
5213template <class Emitter>
5215 bool ConstantContext) {
5216 // We only create variables if we're evaluating in a constant context.
5217 // Otherwise, just evaluate the initializer and return it.
5218 if (!ConstantContext) {
5219 DeclScope<Emitter> LS(this, VD);
5220 if (!this->visit(Init))
5221 return false;
5222 return this->emitRet(classify(Init).value_or(PT_Ptr), VD) &&
5223 LS.destroyLocals() && this->emitCheckAllocations(VD);
5224 }
5225
5226 LocalScope<Emitter> VDScope(this);
5227 if (!this->visitVarDecl(VD, Init, /*Toplevel=*/true))
5228 return false;
5229
5230 OptPrimType VarT = classify(VD->getType());
5232 auto GlobalIndex = P.getGlobal(VD);
5233 assert(GlobalIndex); // visitVarDecl() didn't return false.
5234 if (VarT) {
5235 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
5236 return false;
5237 } else {
5238 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
5239 return false;
5240 }
5241 } else {
5242 auto Local = Locals.find(VD);
5243 assert(Local != Locals.end()); // Same here.
5244 if (VarT) {
5245 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
5246 return false;
5247 } else {
5248 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
5249 return false;
5250 }
5251 }
5252
5253 // Return the value.
5254 if (!this->emitRet(VarT.value_or(PT_Ptr), VD)) {
5255 // If the Ret above failed and this is a global variable, mark it as
5256 // uninitialized, even everything else succeeded.
5258 auto GlobalIndex = P.getGlobal(VD);
5259 assert(GlobalIndex);
5260 Block *GlobalBlock = P.getGlobal(*GlobalIndex);
5261 auto &GD = GlobalBlock->getBlockDesc<GlobalInlineDescriptor>();
5262
5264 GlobalBlock->invokeDtor();
5265 }
5266 return false;
5267 }
5268
5269 return VDScope.destroyLocals() && this->emitCheckAllocations(VD);
5270}
5271
5272template <class Emitter>
5274 const Expr *Init,
5275 bool Toplevel) {
5276 QualType VarTy = VD->getType();
5277 // We don't know what to do with these, so just return false.
5278 if (VarTy.isNull())
5279 return false;
5280
5281 // This case is EvalEmitter-only. If we won't create any instructions for the
5282 // initializer anyway, don't bother creating the variable in the first place.
5283 if (!this->isActive())
5285
5286 OptPrimType VarT = classify(VD->getType());
5287
5288 if (Init && Init->isValueDependent())
5289 return false;
5290
5292 auto checkDecl = [&]() -> bool {
5293 bool NeedsOp = !Toplevel && VD->isLocalVarDecl() && VD->isStaticLocal();
5294 return !NeedsOp || this->emitCheckDecl(VD, VD);
5295 };
5296
5298 UnsignedOrNone GlobalIndex = P.getGlobal(VD);
5299 if (GlobalIndex) {
5300 // The global was previously created but the initializer failed.
5301 if (!P.getGlobal(*GlobalIndex)->isInitialized())
5302 return false;
5303 // We've already seen and initialized this global.
5304 if (P.isGlobalInitialized(*GlobalIndex))
5305 return checkDecl();
5306 // The previous attempt at initialization might've been unsuccessful,
5307 // so let's try this one.
5308 } else if ((GlobalIndex =
5309 P.createGlobal(VD, Init, VariablesAreConstexprUnknown))) {
5310 } else {
5311 return false;
5312 }
5313 if (!Init)
5314 return true;
5315
5316 if (!checkDecl())
5317 return false;
5318
5319 if (VarT) {
5320 if (!this->visit(Init))
5321 return false;
5322
5323 return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
5324 }
5325
5326 if (!this->emitGetPtrGlobal(*GlobalIndex, Init))
5327 return false;
5328
5329 if (!this->emitStartInit(Init))
5330 return false;
5331
5332 if (!visitInitializer(Init))
5333 return false;
5334
5335 if (!this->emitEndInit(Init))
5336 return false;
5337
5338 return this->emitFinishInitGlobal(Init);
5339 }
5340 // Local variables.
5342
5343 if (VarT) {
5344 unsigned Offset = this->allocateLocalPrimitive(
5345 VD, *VarT, VarTy.isConstQualified(), VarTy.isVolatileQualified(),
5347
5348 if (!Init || Init->getType()->isVoidType())
5349 return true;
5350
5351 // If this is a toplevel declaration, create a scope for the
5352 // initializer.
5353 if (Toplevel) {
5355 if (!this->visit(Init))
5356 return false;
5357 return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals();
5358 }
5359 if (!this->visit(Init))
5360 return false;
5361
5362 if (VarTy->isReferenceType()) {
5363 // [C++26][decl.ref]
5364 // The object designated by such a glvalue can be outside its lifetime
5365 // Because a null pointer value or a pointer past the end of an object
5366 // does not point to an object, a reference in a well-defined program
5367 // cannot refer to such things;
5368 assert(classifyPrim(VarTy) == PT_Ptr);
5369 if (!this->emitCheckRefInit(Init))
5370 return false;
5371 }
5372
5373 return this->emitSetLocal(*VarT, Offset, VD);
5374 }
5375 // Local composite variables.
5376 if (UnsignedOrNone Offset =
5377 this->allocateLocal(VD, VarTy, ScopeKind::Block)) {
5378 if (!Init)
5379 return true;
5380
5381 if (!this->emitGetPtrLocal(*Offset, Init))
5382 return false;
5383
5384 return visitInitializerPop(Init);
5385 }
5386 return false;
5387}
5388
5389template <class Emitter>
5391 assert(!canClassify(VD->getType()));
5392
5394 // Create a local variable to use as the instance.
5395 QualType Ty = VD->getType();
5396 Descriptor *D = P.createDescriptor(
5397 VD, Ty.getTypePtr(), Descriptor::InlineDescMD, /*IsConst=*/false,
5398 /*IsTemporary=*/false, /*IsMutable=*/false,
5399 /*IsVolatile=*/Ty.isVolatileQualified(), nullptr);
5400 if (!D)
5401 return false;
5402
5403 Scope::Local Local = this->createLocal(D);
5404 Locals.insert({VD, Local});
5405 VarScope->addForScopeKind(Local, ScopeKind::Block);
5406
5407 if (!this->emitGetPtrLocal(Local.Offset, VD))
5408 return false;
5409 if (!this->visitAPValueInitializer(Value, nullptr, Ty))
5410 return false;
5411 return this->emitDestructionPop(D, VD);
5412}
5413
5414template <class Emitter>
5416 const Expr *E) {
5417 assert(!DiscardResult);
5418 if (Val.isInt())
5419 return this->emitConst(Val.getInt(), ValType, E);
5420 if (Val.isFloat()) {
5421 APFloat F = Val.getFloat();
5422 return this->emitFloat(F, E);
5423 }
5424
5425 if (Val.isMemberPointer()) {
5426 if (const ValueDecl *MemberDecl = Val.getMemberPointerDecl()) {
5427 if (!this->emitGetMemberPtr(MemberDecl, E))
5428 return false;
5429
5430 bool IsDerived = Val.isMemberPointerToDerivedMember();
5431 // Apply the member pointer path.
5432 for (const CXXRecordDecl *PathEntry : Val.getMemberPointerPath()) {
5433 if (!this->emitCopyMemberPtrPath(PathEntry, IsDerived, E))
5434 return false;
5435 }
5436
5437 return true;
5438 }
5439 return this->emitNullMemberPtr(0, nullptr, E);
5440 }
5441
5442 if (Val.isLValue()) {
5443 if (Val.isNullPointer())
5444 return this->emitNull(ValType, 0, nullptr, E);
5445
5448
5449 if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>())
5450 return this->visit(BaseExpr);
5451 if (const auto *VD = Base.dyn_cast<const ValueDecl *>()) {
5452 if (!this->visitDeclRef(VD, E))
5453 return false;
5454
5455 QualType EntryType = VD->getType();
5456 for (auto &Entry : Path) {
5457 if (EntryType->isArrayType()) {
5458 uint64_t Index = Entry.getAsArrayIndex();
5459 QualType ElemType =
5460 EntryType->getAsArrayTypeUnsafe()->getElementType();
5461 if (!this->emitConst(Index, PT_Uint64, E))
5462 return false;
5463 if (!this->emitArrayElemPtrPop(PT_Uint64, E))
5464 return false;
5465 EntryType = ElemType;
5466 } else {
5467 assert(EntryType->isRecordType());
5468 const Record *EntryRecord = getRecord(EntryType);
5469 if (!EntryRecord) {
5470 assert(false);
5471
5472 return false;
5473 }
5474
5475 const Decl *BaseOrMember = Entry.getAsBaseOrMember().getPointer();
5476 if (const auto *FD = dyn_cast<FieldDecl>(BaseOrMember)) {
5477 unsigned EntryOffset = EntryRecord->getField(FD)->Offset;
5478 if (!this->emitGetPtrFieldPop(EntryOffset, E))
5479 return false;
5480 EntryType = FD->getType();
5481 } else {
5482 const auto *Base = cast<CXXRecordDecl>(BaseOrMember);
5483 unsigned BaseOffset = EntryRecord->getBase(Base)->Offset;
5484 if (!this->emitGetPtrBasePop(BaseOffset, /*NullOK=*/false, E))
5485 return false;
5486 EntryType = Ctx.getASTContext().getCanonicalTagType(Base);
5487 }
5488 }
5489 }
5490
5491 return true;
5492 }
5493 }
5494
5495 return false;
5496}
5497
5498template <class Emitter>
5500 const Expr *E, QualType T) {
5501 if (Val.isStruct()) {
5502 const Record *R = this->getRecord(T);
5503 assert(R);
5504 for (unsigned I = 0, N = Val.getStructNumFields(); I != N; ++I) {
5505 const APValue &F = Val.getStructField(I);
5506 const Record::Field *RF = R->getField(I);
5507 QualType FieldType = RF->Decl->getType();
5508
5509 // Fields.
5510 if (OptPrimType PT = classify(FieldType)) {
5511 if (!this->visitAPValue(F, *PT, E))
5512 return false;
5513 if (!this->emitInitField(*PT, RF->Offset, E))
5514 return false;
5515 } else {
5516 if (!this->emitGetPtrField(RF->Offset, E))
5517 return false;
5518 if (!this->visitAPValueInitializer(F, E, FieldType))
5519 return false;
5520 if (!this->emitFinishInitPop(E))
5521 return false;
5522 }
5523 }
5524
5525 // Bases.
5526 for (unsigned I = 0, N = Val.getStructNumBases(); I != N; ++I) {
5527 const APValue &B = Val.getStructBase(I);
5528 const Record::Base *RB = R->getBase(I);
5529 QualType BaseType = Ctx.getASTContext().getCanonicalTagType(RB->Decl);
5530
5531 if (!this->emitGetPtrBase(RB->Offset, E))
5532 return false;
5533 if (!this->visitAPValueInitializer(B, E, BaseType))
5534 return false;
5535 if (!this->emitFinishInitPop(E))
5536 return false;
5537 }
5538
5539 return true;
5540 }
5541 if (Val.isUnion()) {
5542 const FieldDecl *UnionField = Val.getUnionField();
5543 if (!UnionField)
5544 return true;
5545 const Record *R = this->getRecord(T);
5546 assert(R);
5547 const APValue &F = Val.getUnionValue();
5548 const Record::Field *RF = R->getField(UnionField);
5549 QualType FieldType = RF->Decl->getType();
5550
5551 if (OptPrimType PT = classify(FieldType)) {
5552 if (!this->visitAPValue(F, *PT, E))
5553 return false;
5554 if (RF->isBitField())
5555 return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(),
5556 E);
5557 return this->emitInitFieldActivate(*PT, RF->Offset, E);
5558 }
5559
5560 if (!this->emitGetPtrField(RF->Offset, E))
5561 return false;
5562 if (!this->emitActivate(E))
5563 return false;
5564 if (!this->visitAPValueInitializer(F, E, FieldType))
5565 return false;
5566 return this->emitPopPtr(E);
5567 }
5568 if (Val.isArray()) {
5569 unsigned InitializedElems = Val.getArrayInitializedElts();
5570 const auto *ArrType = T->getAsArrayTypeUnsafe();
5571 QualType ElemType = ArrType->getElementType();
5572 OptPrimType ElemT = classify(ElemType);
5573
5574 for (unsigned A = 0, AN = Val.getArraySize(); A != AN; ++A) {
5575 const APValue &Elem = A >= InitializedElems
5576 ? Val.getArrayFiller()
5577 : Val.getArrayInitializedElt(A);
5578
5579 if (ElemT) {
5580 if (!this->visitAPValue(Elem, *ElemT, E))
5581 return false;
5582 if (!this->emitInitElem(*ElemT, A, E))
5583 return false;
5584 } else {
5585 if (!this->emitConstUint32(A, E))
5586 return false;
5587 if (!this->emitArrayElemPtrUint32(E))
5588 return false;
5589 if (!this->visitAPValueInitializer(Elem, E, ElemType))
5590 return false;
5591 if (!this->emitPopPtr(E))
5592 return false;
5593 }
5594 }
5595 return true;
5596 }
5597 // TODO: Other types.
5598
5599 return false;
5600}
5601
5602template <class Emitter>
5604 unsigned BuiltinID) {
5605 if (BuiltinID == Builtin::BI__builtin_constant_p) {
5606 // Void argument is always invalid and harder to handle later.
5607 if (E->getArg(0)->getType()->isVoidType()) {
5608 if (DiscardResult)
5609 return true;
5610 return this->emitConst(0, E);
5611 }
5612
5613 if (!this->emitStartSpeculation(E))
5614 return false;
5615 LabelTy EndLabel = this->getLabel();
5616 if (!this->speculate(E, EndLabel))
5617 return false;
5618 if (!this->emitEndSpeculation(E))
5619 return false;
5620 this->fallthrough(EndLabel);
5621 if (DiscardResult)
5622 return this->emitPop(classifyPrim(E), E);
5623 return true;
5624 }
5625
5626 // For these, we're expected to ultimately return an APValue pointing
5627 // to the CallExpr. This is needed to get the correct codegen.
5628 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
5629 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
5630 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
5631 BuiltinID == Builtin::BI__builtin_function_start) {
5632 if (DiscardResult)
5633 return true;
5634 return this->emitDummyPtr(E, E);
5635 }
5636
5638 OptPrimType ReturnT = classify(E);
5639
5640 // Non-primitive return type. Prepare storage.
5641 if (!Initializing && !ReturnT && !ReturnType->isVoidType()) {
5642 UnsignedOrNone LocalIndex = allocateLocal(E);
5643 if (!LocalIndex)
5644 return false;
5645 if (!this->emitGetPtrLocal(*LocalIndex, E))
5646 return false;
5647 }
5648
5649 // Prepare function arguments including special cases.
5650 switch (BuiltinID) {
5651 case Builtin::BI__builtin_object_size:
5652 case Builtin::BI__builtin_dynamic_object_size: {
5653 assert(E->getNumArgs() == 2);
5654 const Expr *Arg0 = E->getArg(0);
5655 if (Arg0->isGLValue()) {
5656 if (!this->visit(Arg0))
5657 return false;
5658
5659 } else {
5660 if (!this->visitAsLValue(Arg0))
5661 return false;
5662 }
5663 if (!this->visit(E->getArg(1)))
5664 return false;
5665
5666 } break;
5667 case Builtin::BI__assume:
5668 case Builtin::BI__builtin_assume:
5669 // Argument is not evaluated.
5670 break;
5671 case Builtin::BI__atomic_is_lock_free:
5672 case Builtin::BI__atomic_always_lock_free: {
5673 assert(E->getNumArgs() == 2);
5674 if (!this->visit(E->getArg(0)))
5675 return false;
5676 if (!this->visitAsLValue(E->getArg(1)))
5677 return false;
5678 } break;
5679
5680 default:
5681 if (!Context::isUnevaluatedBuiltin(BuiltinID)) {
5682 // Put arguments on the stack.
5683 for (const auto *Arg : E->arguments()) {
5684 if (!this->visit(Arg))
5685 return false;
5686 }
5687 }
5688 }
5689
5690 if (!this->emitCallBI(E, BuiltinID, E))
5691 return false;
5692
5693 if (DiscardResult && !ReturnType->isVoidType())
5694 return this->emitPop(ReturnT.value_or(PT_Ptr), E);
5695
5696 return true;
5697}
5698
5699template <class Emitter>
5701 if (E->containsErrors())
5702 return false;
5703 const FunctionDecl *FuncDecl = E->getDirectCallee();
5704
5705 if (FuncDecl) {
5706 if (unsigned BuiltinID = FuncDecl->getBuiltinID())
5707 return VisitBuiltinCallExpr(E, BuiltinID);
5708
5709 // Calls to replaceable operator new/operator delete.
5711 if (FuncDecl->getDeclName().isAnyOperatorNew())
5712 return VisitBuiltinCallExpr(E, Builtin::BI__builtin_operator_new);
5713 assert(FuncDecl->getDeclName().getCXXOverloadedOperator() == OO_Delete);
5714 return VisitBuiltinCallExpr(E, Builtin::BI__builtin_operator_delete);
5715 }
5716
5717 // Explicit calls to trivial destructors
5718 if (const auto *DD = dyn_cast<CXXDestructorDecl>(FuncDecl);
5719 DD && DD->isTrivial()) {
5720 const auto *MemberCall = cast<CXXMemberCallExpr>(E);
5721 if (!this->visit(MemberCall->getImplicitObjectArgument()))
5722 return false;
5723 return this->emitCheckDestruction(E) && this->emitEndLifetime(E) &&
5724 this->emitPopPtr(E);
5725 }
5726 }
5727
5728 LocalScope<Emitter> CallScope(this, ScopeKind::Call);
5729
5730 QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
5732 bool HasRVO = !ReturnType->isVoidType() && !T;
5733
5734 if (HasRVO) {
5735 if (DiscardResult) {
5736 // If we need to discard the return value but the function returns its
5737 // value via an RVO pointer, we need to create one such pointer just
5738 // for this call.
5739 if (UnsignedOrNone LocalIndex = allocateLocal(E)) {
5740 if (!this->emitGetPtrLocal(*LocalIndex, E))
5741 return false;
5742 }
5743 } else {
5744 // We need the result. Prepare a pointer to return or
5745 // dup the current one.
5746 if (!Initializing) {
5747 if (UnsignedOrNone LocalIndex = allocateLocal(E)) {
5748 if (!this->emitGetPtrLocal(*LocalIndex, E))
5749 return false;
5750 }
5751 }
5752 if (!this->emitDupPtr(E))
5753 return false;
5754 }
5755 }
5756
5758
5759 bool IsAssignmentOperatorCall = false;
5760 bool ActivateLHS = false;
5761 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
5762 OCE && OCE->isAssignmentOp()) {
5763 // Just like with regular assignments, we need to special-case assignment
5764 // operators here and evaluate the RHS (the second arg) before the LHS (the
5765 // first arg). We fix this by using a Flip op later.
5766 assert(Args.size() == 2);
5767 const CXXRecordDecl *LHSRecord = Args[0]->getType()->getAsCXXRecordDecl();
5768 ActivateLHS = LHSRecord && LHSRecord->hasTrivialDefaultConstructor();
5769 IsAssignmentOperatorCall = true;
5770 std::reverse(Args.begin(), Args.end());
5771 }
5772 // Calling a static operator will still
5773 // pass the instance, but we don't need it.
5774 // Discard it here.
5775 if (isa<CXXOperatorCallExpr>(E)) {
5776 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
5777 MD && MD->isStatic()) {
5778 if (!this->discard(E->getArg(0)))
5779 return false;
5780 // Drop first arg.
5781 Args.erase(Args.begin());
5782 }
5783 }
5784
5785 bool Devirtualized = false;
5786 UnsignedOrNone CalleeOffset = std::nullopt;
5787 // Add the (optional, implicit) This pointer.
5788 if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
5789 if (!FuncDecl && classifyPrim(E->getCallee()) == PT_MemberPtr) {
5790 // If we end up creating a CallPtr op for this, we need the base of the
5791 // member pointer as the instance pointer, and later extract the function
5792 // decl as the function pointer.
5793 const Expr *Callee = E->getCallee();
5794 CalleeOffset =
5795 this->allocateLocalPrimitive(Callee, PT_MemberPtr, /*IsConst=*/true);
5796 if (!this->visit(Callee))
5797 return false;
5798 if (!this->emitSetLocal(PT_MemberPtr, *CalleeOffset, E))
5799 return false;
5800 if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
5801 return false;
5802 if (!this->emitGetMemberPtrBase(E))
5803 return false;
5804 } else {
5805 const auto *InstancePtr = MC->getImplicitObjectArgument();
5806 if (isa_and_nonnull<CXXDestructorDecl>(CompilingFunction) ||
5807 isa_and_nonnull<CXXConstructorDecl>(CompilingFunction)) {
5808 const auto *Stripped = stripCheckedDerivedToBaseCasts(InstancePtr);
5809 if (isa<CXXThisExpr>(Stripped)) {
5810 FuncDecl =
5811 cast<CXXMethodDecl>(FuncDecl)->getCorrespondingMethodInClass(
5812 Stripped->getType()->getPointeeType()->getAsCXXRecordDecl());
5813 Devirtualized = true;
5814 if (!this->visit(Stripped))
5815 return false;
5816 } else {
5817 if (!this->visit(InstancePtr))
5818 return false;
5819 }
5820 } else {
5821 if (!this->visit(InstancePtr))
5822 return false;
5823 }
5824 }
5825 } else if (const auto *PD =
5826 dyn_cast<CXXPseudoDestructorExpr>(E->getCallee())) {
5827 if (!this->emitCheckPseudoDtor(E))
5828 return false;
5829 const Expr *Base = PD->getBase();
5830 // E.g. `using T = int; 0.~T();`.
5831 if (OptPrimType BaseT = classify(Base); !BaseT || BaseT != PT_Ptr)
5832 return this->discard(Base);
5833 if (!this->visit(Base))
5834 return false;
5835 return this->emitEndLifetimePop(E);
5836 } else if (!FuncDecl) {
5837 const Expr *Callee = E->getCallee();
5838 CalleeOffset =
5839 this->allocateLocalPrimitive(Callee, PT_Ptr, /*IsConst=*/true);
5840 if (!this->visit(Callee))
5841 return false;
5842 if (!this->emitSetLocal(PT_Ptr, *CalleeOffset, E))
5843 return false;
5844 }
5845
5846 if (!this->visitCallArgs(Args, FuncDecl, ActivateLHS,
5848 return false;
5849
5850 // Undo the argument reversal we did earlier.
5851 if (IsAssignmentOperatorCall) {
5852 assert(Args.size() == 2);
5853 PrimType Arg1T = classify(Args[0]).value_or(PT_Ptr);
5854 PrimType Arg2T = classify(Args[1]).value_or(PT_Ptr);
5855 if (!this->emitFlip(Arg2T, Arg1T, E))
5856 return false;
5857 }
5858
5859 if (FuncDecl) {
5860 const Function *Func = getFunction(FuncDecl);
5861 if (!Func)
5862 return false;
5863
5864 // In error cases, the function may be called with fewer arguments than
5865 // parameters.
5866 if (E->getNumArgs() < Func->getNumWrittenParams())
5867 return false;
5868
5869 assert(HasRVO == Func->hasRVO());
5870
5871 bool HasQualifier = false;
5872 if (const auto *ME = dyn_cast<MemberExpr>(E->getCallee()))
5873 HasQualifier = ME->hasQualifier();
5874
5875 bool IsVirtual = false;
5876 if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
5877 IsVirtual = !Devirtualized && MD->isVirtual();
5878
5879 // In any case call the function. The return value will end up on the stack
5880 // and if the function has RVO, we already have the pointer on the stack to
5881 // write the result into.
5882 if (IsVirtual && !HasQualifier) {
5883 uint32_t VarArgSize = 0;
5884 unsigned NumParams =
5885 Func->getNumWrittenParams() +
5886 (isa<CXXOperatorCallExpr>(E) && Func->hasImplicitThisParam());
5887 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
5888 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
5889
5890 if (!this->emitCallVirt(Func, VarArgSize, E))
5891 return false;
5892 } else if (Func->isVariadic()) {
5893 uint32_t VarArgSize = 0;
5894 unsigned NumParams =
5895 Func->getNumWrittenParams() +
5896 (isa<CXXOperatorCallExpr>(E) && Func->hasImplicitThisParam());
5897 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
5898 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
5899 if (!this->emitCallVar(Func, VarArgSize, E))
5900 return false;
5901 } else {
5902 if (!this->emitCall(Func, 0, E))
5903 return false;
5904 }
5905 } else {
5906 // Indirect call. Visit the callee, which will leave a FunctionPointer on
5907 // the stack. Cleanup of the returned value if necessary will be done after
5908 // the function call completed.
5909
5910 // Sum the size of all args from the call expr.
5911 uint32_t ArgSize = 0;
5912 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
5913 ArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
5914
5915 // Get the callee, either from a member pointer or function pointer saved in
5916 // CalleeOffset.
5917 if (isa<CXXMemberCallExpr>(E) && CalleeOffset) {
5918 if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
5919 return false;
5920 if (!this->emitGetMemberPtrDecl(E))
5921 return false;
5922 } else {
5923 if (!this->emitGetLocal(PT_Ptr, *CalleeOffset, E))
5924 return false;
5925 }
5926 if (!this->emitCallPtr(ArgSize, E, E))
5927 return false;
5928 }
5929
5930 // Cleanup for discarded return values.
5931 if (DiscardResult && !ReturnType->isVoidType() && T)
5932 return this->emitPop(*T, E) && CallScope.destroyLocals();
5933
5934 return CallScope.destroyLocals();
5935}
5936
5937template <class Emitter>
5939 SourceLocScope<Emitter> SLS(this, E);
5940
5941 return this->delegate(E->getExpr());
5942}
5943
5944template <class Emitter>
5946 SourceLocScope<Emitter> SLS(this, E);
5947
5948 return this->delegate(E->getExpr());
5949}
5950
5951template <class Emitter>
5953 if (DiscardResult)
5954 return true;
5955
5956 return this->emitConstBool(E->getValue(), E);
5957}
5958
5959template <class Emitter>
5961 const CXXNullPtrLiteralExpr *E) {
5962 if (DiscardResult)
5963 return true;
5964
5965 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(E->getType());
5966 return this->emitNullPtr(Val, nullptr, E);
5967}
5968
5969template <class Emitter>
5971 if (DiscardResult)
5972 return true;
5973
5974 assert(E->getType()->isIntegerType());
5975
5976 PrimType T = classifyPrim(E->getType());
5977 return this->emitZero(T, E);
5978}
5979
5980template <class Emitter>
5982 if (DiscardResult)
5983 return true;
5984
5985 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
5986 if (this->LambdaThisCapture.Offset > 0) {
5987 if (this->LambdaThisCapture.IsPtr)
5988 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
5989 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
5990 }
5991 }
5992
5993 // In some circumstances, the 'this' pointer does not actually refer to the
5994 // instance pointer of the current function frame, but e.g. to the declaration
5995 // currently being initialized. Here we emit the necessary instruction(s) for
5996 // this scenario.
5997 if (!InitStackActive || InitStack.empty())
5998 return this->emitThis(E);
5999
6000 // If our init stack is, for example:
6001 // 0 Stack: 3 (decl)
6002 // 1 Stack: 6 (init list)
6003 // 2 Stack: 1 (field)
6004 // 3 Stack: 6 (init list)
6005 // 4 Stack: 1 (field)
6006 //
6007 // We want to find the LAST element in it that's an init list,
6008 // which is marked with the K_InitList marker. The index right
6009 // before that points to an init list. We need to find the
6010 // elements before the K_InitList element that point to a base
6011 // (e.g. a decl or This), optionally followed by field, elem, etc.
6012 // In the example above, we want to emit elements [0..2].
6013 unsigned StartIndex = 0;
6014 unsigned EndIndex = 0;
6015 // Find the init list.
6016 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
6017 if (InitStack[StartIndex].Kind == InitLink::K_DIE) {
6018 EndIndex = StartIndex;
6019 --StartIndex;
6020 break;
6021 }
6022 }
6023
6024 // Walk backwards to find the base.
6025 for (; StartIndex > 0; --StartIndex) {
6026 if (InitStack[StartIndex].Kind == InitLink::K_InitList)
6027 continue;
6028
6029 if (InitStack[StartIndex].Kind != InitLink::K_Field &&
6030 InitStack[StartIndex].Kind != InitLink::K_Elem &&
6031 InitStack[StartIndex].Kind != InitLink::K_DIE)
6032 break;
6033 }
6034
6035 if (StartIndex == 0 && EndIndex == 0)
6036 EndIndex = InitStack.size() - 1;
6037
6038 assert(StartIndex < EndIndex);
6039
6040 // Emit the instructions.
6041 for (unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
6042 if (InitStack[I].Kind == InitLink::K_InitList ||
6043 InitStack[I].Kind == InitLink::K_DIE)
6044 continue;
6045 if (!InitStack[I].template emit<Emitter>(this, E))
6046 return false;
6047 }
6048 return true;
6049}
6050
6051template <class Emitter> bool Compiler<Emitter>::visitStmt(const Stmt *S) {
6052 switch (S->getStmtClass()) {
6053 case Stmt::CompoundStmtClass:
6055 case Stmt::DeclStmtClass:
6056 return visitDeclStmt(cast<DeclStmt>(S), /*EvaluateConditionDecl=*/true);
6057 case Stmt::ReturnStmtClass:
6059 case Stmt::IfStmtClass:
6060 return visitIfStmt(cast<IfStmt>(S));
6061 case Stmt::WhileStmtClass:
6063 case Stmt::DoStmtClass:
6064 return visitDoStmt(cast<DoStmt>(S));
6065 case Stmt::ForStmtClass:
6066 return visitForStmt(cast<ForStmt>(S));
6067 case Stmt::CXXForRangeStmtClass:
6069 case Stmt::BreakStmtClass:
6071 case Stmt::ContinueStmtClass:
6073 case Stmt::SwitchStmtClass:
6075 case Stmt::CaseStmtClass:
6076 return visitCaseStmt(cast<CaseStmt>(S));
6077 case Stmt::DefaultStmtClass:
6079 case Stmt::AttributedStmtClass:
6081 case Stmt::CXXTryStmtClass:
6083 case Stmt::NullStmtClass:
6084 return true;
6085 // Always invalid statements.
6086 case Stmt::GCCAsmStmtClass:
6087 case Stmt::MSAsmStmtClass:
6088 case Stmt::GotoStmtClass:
6089 return this->emitInvalid(S);
6090 case Stmt::LabelStmtClass:
6091 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
6092 default: {
6093 if (const auto *E = dyn_cast<Expr>(S))
6094 return this->discard(E);
6095 return false;
6096 }
6097 }
6098}
6099
6100template <class Emitter>
6103 for (const auto *InnerStmt : S->body())
6104 if (!visitStmt(InnerStmt))
6105 return false;
6106 return Scope.destroyLocals();
6107}
6108
6109template <class Emitter>
6110bool Compiler<Emitter>::maybeEmitDeferredVarInit(const VarDecl *VD) {
6111 if (auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
6112 for (auto *BD : DD->flat_bindings())
6113 if (auto *KD = BD->getHoldingVar();
6114 KD && !this->visitVarDecl(KD, KD->getInit()))
6115 return false;
6116 }
6117 return true;
6118}
6119
6121 assert(FD);
6122 assert(FD->getParent()->isUnion());
6123 const CXXRecordDecl *CXXRD =
6125 return !CXXRD || CXXRD->hasTrivialDefaultConstructor();
6126}
6127
6128template <class Emitter> bool Compiler<Emitter>::refersToUnion(const Expr *E) {
6129 for (;;) {
6130 if (const auto *ME = dyn_cast<MemberExpr>(E)) {
6131 if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6132 FD && FD->getParent()->isUnion() && hasTrivialDefaultCtorParent(FD))
6133 return true;
6134 E = ME->getBase();
6135 continue;
6136 }
6137
6138 if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6139 E = ASE->getBase()->IgnoreImplicit();
6140 continue;
6141 }
6142
6143 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E);
6144 ICE && (ICE->getCastKind() == CK_NoOp ||
6145 ICE->getCastKind() == CK_DerivedToBase ||
6146 ICE->getCastKind() == CK_UncheckedDerivedToBase)) {
6147 E = ICE->getSubExpr();
6148 continue;
6149 }
6150
6151 if (const auto *This = dyn_cast<CXXThisExpr>(E)) {
6152 const auto *ThisRecord =
6153 This->getType()->getPointeeType()->getAsRecordDecl();
6154 if (!ThisRecord->isUnion())
6155 return false;
6156 // Otherwise, always activate if we're in the ctor.
6157 if (const auto *Ctor =
6158 dyn_cast_if_present<CXXConstructorDecl>(CompilingFunction))
6159 return Ctor->getParent() == ThisRecord;
6160 return false;
6161 }
6162
6163 break;
6164 }
6165 return false;
6166}
6167
6168template <class Emitter>
6170 bool EvaluateConditionDecl) {
6171 for (const auto *D : DS->decls()) {
6174 continue;
6175
6176 const auto *VD = dyn_cast<VarDecl>(D);
6177 if (!VD)
6178 return false;
6179 if (!this->visitVarDecl(VD, VD->getInit()))
6180 return false;
6181
6182 // Register decomposition decl holding vars.
6183 if (EvaluateConditionDecl && !this->maybeEmitDeferredVarInit(VD))
6184 return false;
6185 }
6186
6187 return true;
6188}
6189
6190template <class Emitter>
6192 if (this->InStmtExpr)
6193 return this->emitUnsupported(RS);
6194
6195 if (const Expr *RE = RS->getRetValue()) {
6196 LocalScope<Emitter> RetScope(this);
6197 if (ReturnType) {
6198 // Primitive types are simply returned.
6199 if (!this->visit(RE))
6200 return false;
6201 this->emitCleanup();
6202 return this->emitRet(*ReturnType, RS);
6203 }
6204
6205 if (RE->getType()->isVoidType()) {
6206 if (!this->visit(RE))
6207 return false;
6208 } else {
6209 if (RE->containsErrors())
6210 return false;
6211
6213 // RVO - construct the value in the return location.
6214 if (!this->emitRVOPtr(RE))
6215 return false;
6216 if (!this->visitInitializerPop(RE))
6217 return false;
6218
6219 this->emitCleanup();
6220 return this->emitRetVoid(RS);
6221 }
6222 }
6223
6224 // Void return.
6225 this->emitCleanup();
6226 return this->emitRetVoid(RS);
6227}
6228
6229template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
6230 LocalScope<Emitter> IfScope(this);
6231
6232 auto visitChildStmt = [&](const Stmt *S) -> bool {
6233 LocalScope<Emitter> SScope(this);
6234 if (!visitStmt(S))
6235 return false;
6236 return SScope.destroyLocals();
6237 };
6238
6239 if (auto *CondInit = IS->getInit()) {
6240 if (!visitStmt(CondInit))
6241 return false;
6242 }
6243
6244 if (const DeclStmt *CondDecl = IS->getConditionVariableDeclStmt()) {
6245 if (!visitDeclStmt(CondDecl))
6246 return false;
6247 }
6248
6249 // Save ourselves compiling some code and the jumps, etc. if the condition is
6250 // stataically known to be either true or false. We could look at more cases
6251 // here, but I think all the ones that actually happen are using a
6252 // ConstantExpr.
6253 if (std::optional<bool> BoolValue = getBoolValue(IS->getCond())) {
6254 if (*BoolValue)
6255 return visitChildStmt(IS->getThen());
6256 if (const Stmt *Else = IS->getElse())
6257 return visitChildStmt(Else);
6258 return true;
6259 }
6260
6261 // Otherwise, compile the condition.
6262 if (IS->isNonNegatedConsteval()) {
6263 if (!this->emitIsConstantContext(IS))
6264 return false;
6265 } else if (IS->isNegatedConsteval()) {
6266 if (!this->emitIsConstantContext(IS))
6267 return false;
6268 if (!this->emitInv(IS))
6269 return false;
6270 } else {
6272 if (!this->visitBool(IS->getCond()))
6273 return false;
6274 if (!CondScope.destroyLocals())
6275 return false;
6276 }
6277
6278 if (!this->maybeEmitDeferredVarInit(IS->getConditionVariable()))
6279 return false;
6280
6281 if (const Stmt *Else = IS->getElse()) {
6282 LabelTy LabelElse = this->getLabel();
6283 LabelTy LabelEnd = this->getLabel();
6284 if (!this->jumpFalse(LabelElse, IS))
6285 return false;
6286 if (!visitChildStmt(IS->getThen()))
6287 return false;
6288 if (!this->jump(LabelEnd, IS))
6289 return false;
6290 this->emitLabel(LabelElse);
6291 if (!visitChildStmt(Else))
6292 return false;
6293 this->emitLabel(LabelEnd);
6294 } else {
6295 LabelTy LabelEnd = this->getLabel();
6296 if (!this->jumpFalse(LabelEnd, IS))
6297 return false;
6298 if (!visitChildStmt(IS->getThen()))
6299 return false;
6300 this->emitLabel(LabelEnd);
6301 }
6302
6303 if (!IfScope.destroyLocals())
6304 return false;
6305
6306 return true;
6307}
6308
6309template <class Emitter>
6311 const Expr *Cond = S->getCond();
6312 const Stmt *Body = S->getBody();
6313
6314 LabelTy CondLabel = this->getLabel(); // Label before the condition.
6315 LabelTy EndLabel = this->getLabel(); // Label after the loop.
6316 LocalScope<Emitter> WholeLoopScope(this);
6317 LoopScope<Emitter> LS(this, S, EndLabel, CondLabel);
6318
6319 this->fallthrough(CondLabel);
6320 this->emitLabel(CondLabel);
6321
6322 // Start of the loop body {
6323 LocalScope<Emitter> CondScope(this);
6324
6325 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt()) {
6326 if (!visitDeclStmt(CondDecl))
6327 return false;
6328 }
6329
6330 if (!this->visitBool(Cond))
6331 return false;
6332
6333 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
6334 return false;
6335
6336 if (!this->jumpFalse(EndLabel, S))
6337 return false;
6338
6339 if (!this->visitStmt(Body))
6340 return false;
6341
6342 if (!CondScope.destroyLocals())
6343 return false;
6344 // } End of loop body.
6345
6346 if (!this->jump(CondLabel, S))
6347 return false;
6348 this->fallthrough(EndLabel);
6349 this->emitLabel(EndLabel);
6350
6351 return CondScope.destroyLocals() && WholeLoopScope.destroyLocals();
6352}
6353
6354template <class Emitter> bool Compiler<Emitter>::visitDoStmt(const DoStmt *S) {
6355 const Expr *Cond = S->getCond();
6356 const Stmt *Body = S->getBody();
6357
6358 LabelTy StartLabel = this->getLabel();
6359 LabelTy EndLabel = this->getLabel();
6360 LabelTy CondLabel = this->getLabel();
6361 LocalScope<Emitter> WholeLoopScope(this);
6362 LoopScope<Emitter> LS(this, S, EndLabel, CondLabel);
6363
6364 this->fallthrough(StartLabel);
6365 this->emitLabel(StartLabel);
6366
6367 {
6368 LocalScope<Emitter> CondScope(this);
6369 if (!this->visitStmt(Body))
6370 return false;
6371 this->fallthrough(CondLabel);
6372 this->emitLabel(CondLabel);
6373 if (!this->visitBool(Cond))
6374 return false;
6375
6376 if (!CondScope.destroyLocals())
6377 return false;
6378 }
6379 if (!this->jumpTrue(StartLabel, S))
6380 return false;
6381
6382 this->fallthrough(EndLabel);
6383 this->emitLabel(EndLabel);
6384 return WholeLoopScope.destroyLocals();
6385}
6386
6387template <class Emitter>
6389 // for (Init; Cond; Inc) { Body }
6390 const Stmt *Init = S->getInit();
6391 const Expr *Cond = S->getCond();
6392 const Expr *Inc = S->getInc();
6393 const Stmt *Body = S->getBody();
6394
6395 LabelTy EndLabel = this->getLabel();
6396 LabelTy CondLabel = this->getLabel();
6397 LabelTy IncLabel = this->getLabel();
6398
6399 LocalScope<Emitter> WholeLoopScope(this);
6400 if (Init && !this->visitStmt(Init))
6401 return false;
6402
6403 // Start of the loop body {
6404 this->fallthrough(CondLabel);
6405 this->emitLabel(CondLabel);
6406
6407 LocalScope<Emitter> CondScope(this);
6408 LoopScope<Emitter> LS(this, S, EndLabel, IncLabel);
6409 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt()) {
6410 if (!visitDeclStmt(CondDecl))
6411 return false;
6412 }
6413
6414 if (Cond) {
6415 if (!this->visitBool(Cond))
6416 return false;
6417 if (!this->jumpFalse(EndLabel, S))
6418 return false;
6419 }
6420 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
6421 return false;
6422
6423 if (Body && !this->visitStmt(Body))
6424 return false;
6425
6426 this->fallthrough(IncLabel);
6427 this->emitLabel(IncLabel);
6428 if (Inc && !this->discard(Inc))
6429 return false;
6430
6431 if (!CondScope.destroyLocals())
6432 return false;
6433 if (!this->jump(CondLabel, S))
6434 return false;
6435 // } End of loop body.
6436
6437 this->emitLabel(EndLabel);
6438 // If we jumped out of the loop above, we still need to clean up the condition
6439 // scope.
6440 return CondScope.destroyLocals() && WholeLoopScope.destroyLocals();
6441}
6442
6443template <class Emitter>
6445 const Stmt *Init = S->getInit();
6446 const Expr *Cond = S->getCond();
6447 const Expr *Inc = S->getInc();
6448 const Stmt *Body = S->getBody();
6449 const Stmt *BeginStmt = S->getBeginStmt();
6450 const Stmt *RangeStmt = S->getRangeStmt();
6451 const Stmt *EndStmt = S->getEndStmt();
6452
6453 LabelTy EndLabel = this->getLabel();
6454 LabelTy CondLabel = this->getLabel();
6455 LabelTy IncLabel = this->getLabel();
6456 LocalScope<Emitter> WholeLoopScope(this);
6457 LoopScope<Emitter> LS(this, S, EndLabel, IncLabel);
6458
6459 // Emit declarations needed in the loop.
6460 if (Init && !this->visitStmt(Init))
6461 return false;
6462 if (!this->visitStmt(RangeStmt))
6463 return false;
6464 if (!this->visitStmt(BeginStmt))
6465 return false;
6466 if (!this->visitStmt(EndStmt))
6467 return false;
6468
6469 // Now the condition as well as the loop variable assignment.
6470 this->fallthrough(CondLabel);
6471 this->emitLabel(CondLabel);
6472 if (!this->visitBool(Cond))
6473 return false;
6474 if (!this->jumpFalse(EndLabel, S))
6475 return false;
6476
6477 if (!this->visitDeclStmt(S->getLoopVarStmt(), /*EvaluateConditionDecl=*/true))
6478 return false;
6479
6480 // Body.
6481 {
6482 if (!this->visitStmt(Body))
6483 return false;
6484
6485 this->fallthrough(IncLabel);
6486 this->emitLabel(IncLabel);
6487 if (!this->discard(Inc))
6488 return false;
6489 }
6490
6491 if (!this->jump(CondLabel, S))
6492 return false;
6493
6494 this->fallthrough(EndLabel);
6495 this->emitLabel(EndLabel);
6496 return WholeLoopScope.destroyLocals();
6497}
6498
6499template <class Emitter>
6501 if (LabelInfoStack.empty())
6502 return false;
6503
6504 OptLabelTy TargetLabel = std::nullopt;
6505 const Stmt *TargetLoop = S->getNamedLoopOrSwitch();
6506 const VariableScope<Emitter> *BreakScope = nullptr;
6507
6508 if (!TargetLoop) {
6509 for (const auto &LI : llvm::reverse(LabelInfoStack)) {
6510 if (LI.BreakLabel) {
6511 TargetLabel = *LI.BreakLabel;
6512 BreakScope = LI.BreakOrContinueScope;
6513 break;
6514 }
6515 }
6516 } else {
6517 for (auto LI : LabelInfoStack) {
6518 if (LI.Name == TargetLoop) {
6519 TargetLabel = *LI.BreakLabel;
6520 BreakScope = LI.BreakOrContinueScope;
6521 break;
6522 }
6523 }
6524 }
6525
6526 // Faulty break statement (e.g. label redefined or named loops disabled).
6527 if (!TargetLabel)
6528 return false;
6529
6530 for (VariableScope<Emitter> *C = this->VarScope; C != BreakScope;
6531 C = C->getParent()) {
6532 if (!C->destroyLocals())
6533 return false;
6534 }
6535
6536 return this->jump(*TargetLabel, S);
6537}
6538
6539template <class Emitter>
6541 if (LabelInfoStack.empty())
6542 return false;
6543
6544 OptLabelTy TargetLabel = std::nullopt;
6545 const Stmt *TargetLoop = S->getNamedLoopOrSwitch();
6546 const VariableScope<Emitter> *ContinueScope = nullptr;
6547
6548 if (!TargetLoop) {
6549 for (const auto &LI : llvm::reverse(LabelInfoStack)) {
6550 if (LI.ContinueLabel) {
6551 TargetLabel = *LI.ContinueLabel;
6552 ContinueScope = LI.BreakOrContinueScope;
6553 break;
6554 }
6555 }
6556 } else {
6557 for (auto LI : LabelInfoStack) {
6558 if (LI.Name == TargetLoop) {
6559 TargetLabel = *LI.ContinueLabel;
6560 ContinueScope = LI.BreakOrContinueScope;
6561 break;
6562 }
6563 }
6564 }
6565 assert(TargetLabel);
6566
6567 for (VariableScope<Emitter> *C = VarScope; C != ContinueScope;
6568 C = C->getParent()) {
6569 if (!C->destroyLocals())
6570 return false;
6571 }
6572
6573 return this->jump(*TargetLabel, S);
6574}
6575
6576template <class Emitter>
6578 const Expr *Cond = S->getCond();
6579 if (Cond->containsErrors())
6580 return false;
6581
6582 PrimType CondT = this->classifyPrim(Cond->getType());
6583 LocalScope<Emitter> LS(this);
6584
6585 LabelTy EndLabel = this->getLabel();
6586 UnsignedOrNone DefaultLabel = std::nullopt;
6587 unsigned CondVar =
6588 this->allocateLocalPrimitive(Cond, CondT, /*IsConst=*/true);
6589
6590 if (const auto *CondInit = S->getInit())
6591 if (!visitStmt(CondInit))
6592 return false;
6593
6594 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
6595 if (!visitDeclStmt(CondDecl))
6596 return false;
6597
6598 // Initialize condition variable.
6599 if (!this->visit(Cond))
6600 return false;
6601 if (!this->emitSetLocal(CondT, CondVar, S))
6602 return false;
6603
6604 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
6605 return false;
6606
6608 // Create labels and comparison ops for all case statements.
6609 for (const SwitchCase *SC = S->getSwitchCaseList(); SC;
6610 SC = SC->getNextSwitchCase()) {
6611 if (const auto *CS = dyn_cast<CaseStmt>(SC)) {
6612 CaseLabels[SC] = this->getLabel();
6613
6614 if (CS->caseStmtIsGNURange()) {
6615 LabelTy EndOfRangeCheck = this->getLabel();
6616 const Expr *Low = CS->getLHS();
6617 const Expr *High = CS->getRHS();
6618 if (Low->isValueDependent() || High->isValueDependent())
6619 return false;
6620
6621 if (!this->emitGetLocal(CondT, CondVar, CS))
6622 return false;
6623 if (!this->visit(Low))
6624 return false;
6625 PrimType LT = this->classifyPrim(Low->getType());
6626 if (!this->emitGE(LT, S))
6627 return false;
6628 if (!this->jumpFalse(EndOfRangeCheck, S))
6629 return false;
6630
6631 if (!this->emitGetLocal(CondT, CondVar, CS))
6632 return false;
6633 if (!this->visit(High))
6634 return false;
6635 PrimType HT = this->classifyPrim(High->getType());
6636 if (!this->emitLE(HT, S))
6637 return false;
6638 if (!this->jumpTrue(CaseLabels[CS], S))
6639 return false;
6640 this->emitLabel(EndOfRangeCheck);
6641 continue;
6642 }
6643
6644 const Expr *Value = CS->getLHS();
6645 if (Value->isValueDependent())
6646 return false;
6647 PrimType ValueT = this->classifyPrim(Value->getType());
6648
6649 // Compare the case statement's value to the switch condition.
6650 if (!this->emitGetLocal(CondT, CondVar, CS))
6651 return false;
6652 if (!this->visit(Value))
6653 return false;
6654
6655 // Compare and jump to the case label.
6656 if (!this->emitEQ(ValueT, S))
6657 return false;
6658 if (!this->jumpTrue(CaseLabels[CS], S))
6659 return false;
6660 } else {
6661 assert(!DefaultLabel);
6662 DefaultLabel = this->getLabel();
6663 }
6664 }
6665
6666 // If none of the conditions above were true, fall through to the default
6667 // statement or jump after the switch statement.
6668 if (DefaultLabel) {
6669 if (!this->jump(*DefaultLabel, S))
6670 return false;
6671 } else {
6672 if (!this->jump(EndLabel, S))
6673 return false;
6674 }
6675
6676 SwitchScope<Emitter> SS(this, S, std::move(CaseLabels), EndLabel,
6677 DefaultLabel);
6678 if (!this->visitStmt(S->getBody()))
6679 return false;
6680 this->fallthrough(EndLabel);
6681 this->emitLabel(EndLabel);
6682
6683 return LS.destroyLocals();
6684}
6685
6686template <class Emitter>
6688 this->fallthrough(CaseLabels[S]);
6689 this->emitLabel(CaseLabels[S]);
6690 return this->visitStmt(S->getSubStmt());
6691}
6692
6693template <class Emitter>
6695 if (LabelInfoStack.empty())
6696 return false;
6697
6698 LabelTy DefaultLabel;
6699 for (const LabelInfo &LI : llvm::reverse(LabelInfoStack)) {
6700 if (LI.DefaultLabel) {
6701 DefaultLabel = *LI.DefaultLabel;
6702 break;
6703 }
6704 }
6705
6706 this->emitLabel(DefaultLabel);
6707 return this->visitStmt(S->getSubStmt());
6708}
6709
6710template <class Emitter>
6712 const Stmt *SubStmt = S->getSubStmt();
6713
6714 bool IsMSVCConstexprAttr = isa<ReturnStmt>(SubStmt) &&
6716
6717 if (IsMSVCConstexprAttr && !this->emitPushMSVCCE(S))
6718 return false;
6719
6720 if (this->Ctx.getLangOpts().CXXAssumptions &&
6721 !this->Ctx.getLangOpts().MSVCCompat) {
6722 for (const Attr *A : S->getAttrs()) {
6723 auto *AA = dyn_cast<CXXAssumeAttr>(A);
6724 if (!AA)
6725 continue;
6726
6727 assert(isa<NullStmt>(SubStmt));
6728
6729 const Expr *Assumption = AA->getAssumption();
6730 if (Assumption->isValueDependent())
6731 return false;
6732
6733 if (Assumption->HasSideEffects(this->Ctx.getASTContext()))
6734 continue;
6735
6736 // Evaluate assumption.
6737 if (!this->visitBool(Assumption))
6738 return false;
6739
6740 if (!this->emitAssume(Assumption))
6741 return false;
6742 }
6743 }
6744
6745 // Ignore other attributes.
6746 if (!this->visitStmt(SubStmt))
6747 return false;
6748
6749 if (IsMSVCConstexprAttr)
6750 return this->emitPopMSVCCE(S);
6751 return true;
6752}
6753
6754template <class Emitter>
6756 // Ignore all handlers.
6757 return this->visitStmt(S->getTryBlock());
6758}
6759
6760template <class Emitter>
6761bool Compiler<Emitter>::emitLambdaStaticInvokerBody(const CXXMethodDecl *MD) {
6762 assert(MD->isLambdaStaticInvoker());
6763 assert(MD->hasBody());
6764 assert(cast<CompoundStmt>(MD->getBody())->body_empty());
6765
6766 const CXXRecordDecl *ClosureClass = MD->getParent();
6767 const FunctionDecl *LambdaCallOp;
6768 assert(ClosureClass->captures().empty());
6769 if (ClosureClass->isGenericLambda()) {
6770 LambdaCallOp = ClosureClass->getLambdaCallOperator();
6771 assert(MD->isFunctionTemplateSpecialization() &&
6772 "A generic lambda's static-invoker function must be a "
6773 "template specialization");
6775 FunctionTemplateDecl *CallOpTemplate =
6776 LambdaCallOp->getDescribedFunctionTemplate();
6777 void *InsertPos = nullptr;
6778 const FunctionDecl *CorrespondingCallOpSpecialization =
6779 CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos);
6780 assert(CorrespondingCallOpSpecialization);
6781 LambdaCallOp = CorrespondingCallOpSpecialization;
6782 } else {
6783 LambdaCallOp = ClosureClass->getLambdaCallOperator();
6784 }
6785 assert(ClosureClass->captures().empty());
6786 const Function *Func = this->getFunction(LambdaCallOp);
6787 if (!Func)
6788 return false;
6789 assert(Func->hasThisPointer());
6790 assert(Func->getNumParams() == (MD->getNumParams() + 1 + Func->hasRVO()));
6791
6792 if (Func->hasRVO()) {
6793 if (!this->emitRVOPtr(MD))
6794 return false;
6795 }
6796
6797 // The lambda call operator needs an instance pointer, but we don't have
6798 // one here, and we don't need one either because the lambda cannot have
6799 // any captures, as verified above. Emit a null pointer. This is then
6800 // special-cased when interpreting to not emit any misleading diagnostics.
6801 if (!this->emitNullPtr(0, nullptr, MD))
6802 return false;
6803
6804 // Forward all arguments from the static invoker to the lambda call operator.
6805 for (const ParmVarDecl *PVD : MD->parameters()) {
6806 auto It = this->Params.find(PVD);
6807 assert(It != this->Params.end());
6808
6809 // We do the lvalue-to-rvalue conversion manually here, so no need
6810 // to care about references.
6811 PrimType ParamType = this->classify(PVD->getType()).value_or(PT_Ptr);
6812 if (!this->emitGetParam(ParamType, It->second.Index, MD))
6813 return false;
6814 }
6815
6816 if (!this->emitCall(Func, 0, LambdaCallOp))
6817 return false;
6818
6819 this->emitCleanup();
6820 if (ReturnType)
6821 return this->emitRet(*ReturnType, MD);
6822
6823 // Nothing to do, since we emitted the RVO pointer above.
6824 return this->emitRetVoid(MD);
6825}
6826
6827template <class Emitter>
6828bool Compiler<Emitter>::checkLiteralType(const Expr *E) {
6829 if (Ctx.getLangOpts().CPlusPlus23)
6830 return true;
6831
6832 if (!E->isPRValue() || E->getType()->isLiteralType(Ctx.getASTContext()))
6833 return true;
6834
6835 return this->emitCheckLiteralType(E->getType().getTypePtr(), E);
6836}
6837
6839 const Expr *InitExpr = Init->getInit();
6840
6841 if (!Init->isWritten() && !Init->isInClassMemberInitializer() &&
6842 !isa<CXXConstructExpr>(InitExpr))
6843 return true;
6844
6845 if (const auto *CE = dyn_cast<CXXConstructExpr>(InitExpr)) {
6846 const CXXConstructorDecl *Ctor = CE->getConstructor();
6847 if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&
6848 Ctor->isTrivial())
6849 return true;
6850 }
6851
6852 return false;
6853}
6854
6855template <class Emitter>
6856bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
6857 assert(!ReturnType);
6858
6859 // Only start the lifetime of the instance pointer.
6860 if (!this->emitStartThisLifetime1(Ctor))
6861 return false;
6862
6863 auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
6864 const Expr *InitExpr,
6865 bool Activate = false) -> bool {
6866 // We don't know what to do with these, so just return false.
6867 if (InitExpr->getType().isNull())
6868 return false;
6869
6870 if (OptPrimType T = this->classify(InitExpr)) {
6871 if (Activate && !this->emitActivateThisField(FieldOffset, InitExpr))
6872 return false;
6873
6874 if (!this->visit(InitExpr))
6875 return false;
6876
6877 if (F->isBitField())
6878 return this->emitInitThisBitField(*T, FieldOffset, F->bitWidth(),
6879 InitExpr);
6880 return this->emitInitThisField(*T, FieldOffset, InitExpr);
6881 }
6882 // Non-primitive case. Get a pointer to the field-to-initialize
6883 // on the stack and call visitInitialzer() for it.
6884 InitLinkScope<Emitter> FieldScope(this, InitLink::Field(F->Offset));
6885 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
6886 return false;
6887
6888 if (Activate && !this->emitActivate(InitExpr))
6889 return false;
6890
6891 return this->visitInitializerPop(InitExpr);
6892 };
6893
6894 const RecordDecl *RD = Ctor->getParent();
6895 const Record *R = this->getRecord(RD);
6896 if (!R)
6897 return false;
6898 bool IsUnion = R->isUnion();
6899
6900 // Default union copy and move ctors are special.
6901 if (IsUnion && Ctor->isCopyOrMoveConstructor() && Ctor->isDefaulted()) {
6903
6904 // No special case for NumFields == 0 here, so the Memcpy op
6905 // below also does its checks in those cases.
6906
6907 assert(cast<CompoundStmt>(Ctor->getBody())->body_empty());
6908 if (!this->emitThis(Ctor))
6909 return false;
6910
6911 if (!this->emitGetParam(PT_Ptr, /*ParamIndex=*/0, Ctor))
6912 return false;
6913
6914 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
6915 this->emitRetVoid(Ctor);
6916 }
6917
6918 unsigned FieldInits = 0;
6920 for (const auto *Init : Ctor->inits()) {
6921 // Scope needed for the initializers.
6922 LocalScope<Emitter> Scope(this, ScopeKind::FullExpression);
6923
6924 const Expr *InitExpr = Init->getInit();
6925 if (const FieldDecl *Member = Init->getMember()) {
6926 const Record::Field *F = R->getField(Member);
6927
6930 if (!emitFieldInitializer(F, F->Offset, InitExpr, IsUnion))
6931 return false;
6932 ++FieldInits;
6933 } else if (const Type *Base = Init->getBaseClass()) {
6934 const auto *BaseDecl = Base->getAsCXXRecordDecl();
6935 assert(BaseDecl);
6936
6937 if (Init->isBaseVirtual()) {
6938 assert(R->getVirtualBase(BaseDecl));
6939 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
6940 return false;
6941
6942 } else {
6943 // Base class initializer.
6944 // Get This Base and call initializer on it.
6945 const Record::Base *B = R->getBase(BaseDecl);
6946 assert(B);
6947 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
6948 return false;
6949 }
6950
6951 if (IsUnion && !this->emitActivate(InitExpr))
6952 return false;
6953
6954 if (!this->visitInitializerPop(InitExpr))
6955 return false;
6956 } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {
6959 unsigned ChainSize = IFD->getChainingSize();
6960 assert(ChainSize >= 2);
6961
6962 unsigned NestedFieldOffset = 0;
6963 const Record::Field *NestedField = nullptr;
6964 for (unsigned I = 0; I != ChainSize; ++I) {
6965 const auto *FD = cast<FieldDecl>(IFD->chain()[I]);
6966 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
6967 assert(FieldRecord);
6968
6969 NestedField = FieldRecord->getField(FD);
6970 assert(NestedField);
6971 IsUnion = IsUnion || FieldRecord->isUnion();
6972
6973 NestedFieldOffset += NestedField->Offset;
6974
6975 // Add a new InitChainLink for the record, but not for the final field.
6976 if (I != ChainSize - 1)
6977 InitStack.push_back(InitLink::Field(NestedField->Offset));
6978 }
6979 assert(NestedField);
6980
6982 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
6983 IsUnion))
6984 return false;
6985
6986 // Mark all chain links as initialized.
6987 unsigned InitFieldOffset = 0;
6988 for (const NamedDecl *ND : IFD->chain().drop_back()) {
6989 const auto *FD = cast<FieldDecl>(ND);
6990 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
6991 assert(FieldRecord);
6992 NestedField = FieldRecord->getField(FD);
6993 InitFieldOffset += NestedField->Offset;
6994 assert(NestedField);
6995 if (!this->emitGetPtrThisField(InitFieldOffset, InitExpr))
6996 return false;
6997 if (!this->emitFinishInitPop(InitExpr))
6998 return false;
6999 }
7000
7001 InitStack.pop_back_n(ChainSize - 1);
7002
7003 } else {
7004 assert(Init->isDelegatingInitializer());
7005 if (!this->emitThis(InitExpr))
7006 return false;
7007 if (!this->visitInitializerPop(Init->getInit()))
7008 return false;
7009 }
7010
7011 if (!Scope.destroyLocals())
7012 return false;
7013 }
7014
7015 if (FieldInits != R->getNumFields()) {
7016 assert(FieldInits < R->getNumFields());
7017 // Start the lifetime of all members.
7018 if (!this->emitStartThisLifetime(Ctor))
7019 return false;
7020 }
7021
7022 if (const Stmt *Body = Ctor->getBody()) {
7023 // Only emit the CtorCheck op for non-empty CompoundStmt bodies.
7024 // For non-CompoundStmts, always assume they are non-empty and emit it.
7025 if (const auto *CS = dyn_cast<CompoundStmt>(Body)) {
7026 if (!CS->body_empty() && !this->emitCtorCheck(SourceInfo{}))
7027 return false;
7028 } else {
7029 if (!this->emitCtorCheck(SourceInfo{}))
7030 return false;
7031 }
7032
7033 if (!visitStmt(Body))
7034 return false;
7035 }
7036
7037 return this->emitRetVoid(SourceInfo{});
7038}
7039
7040template <class Emitter>
7041bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) {
7042 const RecordDecl *RD = Dtor->getParent();
7043 const Record *R = this->getRecord(RD);
7044 if (!R)
7045 return false;
7046
7047 if (!Dtor->isTrivial() && Dtor->getBody()) {
7048 if (!this->visitStmt(Dtor->getBody()))
7049 return false;
7050 }
7051
7052 if (!this->emitThis(Dtor))
7053 return false;
7054
7055 if (!this->emitCheckDestruction(Dtor))
7056 return false;
7057
7058 assert(R);
7059 if (!R->isUnion()) {
7060
7062 // First, destroy all fields.
7063 for (const Record::Field &Field : llvm::reverse(R->fields())) {
7064 const Descriptor *D = Field.Desc;
7065 if (D->hasTrivialDtor())
7066 continue;
7067 if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
7068 return false;
7069 if (!this->emitDestructionPop(D, SourceInfo{}))
7070 return false;
7071 }
7072 }
7073
7074 for (const Record::Base &Base : llvm::reverse(R->bases())) {
7075 if (Base.R->hasTrivialDtor())
7076 continue;
7077 if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
7078 return false;
7079 if (!this->emitRecordDestructionPop(Base.R, {}))
7080 return false;
7081 }
7082
7083 if (!this->emitMarkDestroyed(Dtor))
7084 return false;
7085
7086 // FIXME: Virtual bases.
7087 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
7088}
7089
7090template <class Emitter>
7091bool Compiler<Emitter>::compileUnionAssignmentOperator(
7092 const CXXMethodDecl *MD) {
7093 if (!this->emitThis(MD))
7094 return false;
7095
7096 if (!this->emitGetParam(PT_Ptr, /*ParamIndex=*/0, MD))
7097 return false;
7098
7099 return this->emitMemcpy(MD) && this->emitRet(PT_Ptr, MD);
7100}
7101
7102template <class Emitter>
7104 if (F->getReturnType()->isDependentType())
7105 return false;
7106
7107 // Classify the return type.
7108 ReturnType = this->classify(F->getReturnType());
7109
7110 this->CompilingFunction = F;
7111
7112 if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
7113 return this->compileConstructor(Ctor);
7114 if (const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
7115 return this->compileDestructor(Dtor);
7116
7117 // Emit custom code if this is a lambda static invoker.
7118 if (const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
7119 const RecordDecl *RD = MD->getParent();
7120
7121 if (RD->isUnion() &&
7123 return this->compileUnionAssignmentOperator(MD);
7124
7125 if (MD->isLambdaStaticInvoker())
7126 return this->emitLambdaStaticInvokerBody(MD);
7127 }
7128
7129 // Regular functions.
7130 if (const auto *Body = F->getBody())
7131 if (!visitStmt(Body))
7132 return false;
7133
7134 // Emit a guard return to protect against a code path missing one.
7135 if (F->getReturnType()->isVoidType())
7136 return this->emitRetVoid(SourceInfo{});
7137 return this->emitNoRet(SourceInfo{});
7138}
7139
7140static uint32_t getBitWidth(const Expr *E) {
7141 assert(E->refersToBitField());
7142 const auto *ME = cast<MemberExpr>(E);
7143 const auto *FD = cast<FieldDecl>(ME->getMemberDecl());
7144 return FD->getBitWidthValue();
7145}
7146
7147template <class Emitter>
7149 const Expr *SubExpr = E->getSubExpr();
7150 if (SubExpr->getType()->isAnyComplexType())
7151 return this->VisitComplexUnaryOperator(E);
7152 if (SubExpr->getType()->isVectorType())
7153 return this->VisitVectorUnaryOperator(E);
7154 if (SubExpr->getType()->isFixedPointType())
7155 return this->VisitFixedPointUnaryOperator(E);
7156 OptPrimType T = classify(SubExpr->getType());
7157
7158 switch (E->getOpcode()) {
7159 case UO_PostInc: { // x++
7160 if (!Ctx.getLangOpts().CPlusPlus14)
7161 return this->emitInvalid(E);
7162 if (!T)
7163 return this->emitError(E);
7164
7165 if (!this->visit(SubExpr))
7166 return false;
7167
7168 if (T == PT_Ptr) {
7169 if (!this->emitIncPtr(E))
7170 return false;
7171
7172 return DiscardResult ? this->emitPopPtr(E) : true;
7173 }
7174
7175 if (T == PT_Float)
7176 return DiscardResult ? this->emitIncfPop(getFPOptions(E), E)
7177 : this->emitIncf(getFPOptions(E), E);
7178
7179 if (SubExpr->refersToBitField())
7180 return DiscardResult ? this->emitIncPopBitfield(*T, E->canOverflow(),
7181 getBitWidth(SubExpr), E)
7182 : this->emitIncBitfield(*T, E->canOverflow(),
7183 getBitWidth(SubExpr), E);
7184
7185 return DiscardResult ? this->emitIncPop(*T, E->canOverflow(), E)
7186 : this->emitInc(*T, E->canOverflow(), E);
7187 }
7188 case UO_PostDec: { // x--
7189 if (!Ctx.getLangOpts().CPlusPlus14)
7190 return this->emitInvalid(E);
7191 if (!T)
7192 return this->emitError(E);
7193
7194 if (!this->visit(SubExpr))
7195 return false;
7196
7197 if (T == PT_Ptr) {
7198 if (!this->emitDecPtr(E))
7199 return false;
7200
7201 return DiscardResult ? this->emitPopPtr(E) : true;
7202 }
7203
7204 if (T == PT_Float)
7205 return DiscardResult ? this->emitDecfPop(getFPOptions(E), E)
7206 : this->emitDecf(getFPOptions(E), E);
7207
7208 if (SubExpr->refersToBitField()) {
7209 return DiscardResult ? this->emitDecPopBitfield(*T, E->canOverflow(),
7210 getBitWidth(SubExpr), E)
7211 : this->emitDecBitfield(*T, E->canOverflow(),
7212 getBitWidth(SubExpr), E);
7213 }
7214
7215 return DiscardResult ? this->emitDecPop(*T, E->canOverflow(), E)
7216 : this->emitDec(*T, E->canOverflow(), E);
7217 }
7218 case UO_PreInc: { // ++x
7219 if (!Ctx.getLangOpts().CPlusPlus14)
7220 return this->emitInvalid(E);
7221 if (!T)
7222 return this->emitError(E);
7223
7224 if (!this->visit(SubExpr))
7225 return false;
7226
7227 if (T == PT_Ptr) {
7228 if (!this->emitLoadPtr(E))
7229 return false;
7230 if (!this->emitConstUint8(1, E))
7231 return false;
7232 if (!this->emitAddOffsetUint8(E))
7233 return false;
7234 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7235 }
7236
7237 // Post-inc and pre-inc are the same if the value is to be discarded.
7238 if (DiscardResult) {
7239 if (T == PT_Float)
7240 return this->emitIncfPop(getFPOptions(E), E);
7241 if (SubExpr->refersToBitField())
7242 return DiscardResult ? this->emitIncPopBitfield(*T, E->canOverflow(),
7243 getBitWidth(SubExpr), E)
7244 : this->emitIncBitfield(*T, E->canOverflow(),
7245 getBitWidth(SubExpr), E);
7246 return this->emitIncPop(*T, E->canOverflow(), E);
7247 }
7248
7249 if (T == PT_Float) {
7250 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
7251 if (!this->emitLoadFloat(E))
7252 return false;
7253 APFloat F(TargetSemantics, 1);
7254 if (!this->emitFloat(F, E))
7255 return false;
7256
7257 if (!this->emitAddf(getFPOptions(E), E))
7258 return false;
7259 if (!this->emitStoreFloat(E))
7260 return false;
7261 } else if (SubExpr->refersToBitField()) {
7262 assert(isIntegerOrBoolType(*T));
7263 if (!this->emitPreIncBitfield(*T, E->canOverflow(), getBitWidth(SubExpr),
7264 E))
7265 return false;
7266 } else {
7267 assert(isIntegerOrBoolType(*T));
7268 if (!this->emitPreInc(*T, E->canOverflow(), E))
7269 return false;
7270 }
7271 return E->isGLValue() || this->emitLoadPop(*T, E);
7272 }
7273 case UO_PreDec: { // --x
7274 if (!Ctx.getLangOpts().CPlusPlus14)
7275 return this->emitInvalid(E);
7276 if (!T)
7277 return this->emitError(E);
7278
7279 if (!this->visit(SubExpr))
7280 return false;
7281
7282 if (T == PT_Ptr) {
7283 if (!this->emitLoadPtr(E))
7284 return false;
7285 if (!this->emitConstUint8(1, E))
7286 return false;
7287 if (!this->emitSubOffsetUint8(E))
7288 return false;
7289 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7290 }
7291
7292 // Post-dec and pre-dec are the same if the value is to be discarded.
7293 if (DiscardResult) {
7294 if (T == PT_Float)
7295 return this->emitDecfPop(getFPOptions(E), E);
7296 if (SubExpr->refersToBitField())
7297 return DiscardResult ? this->emitDecPopBitfield(*T, E->canOverflow(),
7298 getBitWidth(SubExpr), E)
7299 : this->emitDecBitfield(*T, E->canOverflow(),
7300 getBitWidth(SubExpr), E);
7301 return this->emitDecPop(*T, E->canOverflow(), E);
7302 }
7303
7304 if (T == PT_Float) {
7305 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
7306 if (!this->emitLoadFloat(E))
7307 return false;
7308 APFloat F(TargetSemantics, 1);
7309 if (!this->emitFloat(F, E))
7310 return false;
7311
7312 if (!this->emitSubf(getFPOptions(E), E))
7313 return false;
7314 if (!this->emitStoreFloat(E))
7315 return false;
7316 } else if (SubExpr->refersToBitField()) {
7317 assert(isIntegerOrBoolType(*T));
7318 if (!this->emitPreDecBitfield(*T, E->canOverflow(), getBitWidth(SubExpr),
7319 E))
7320 return false;
7321 } else {
7322 assert(isIntegerOrBoolType(*T));
7323 if (!this->emitPreDec(*T, E->canOverflow(), E))
7324 return false;
7325 }
7326 return E->isGLValue() || this->emitLoadPop(*T, E);
7327 }
7328 case UO_LNot: // !x
7329 if (!T)
7330 return this->emitError(E);
7331
7332 if (DiscardResult)
7333 return this->discard(SubExpr);
7334
7335 if (!this->visitBool(SubExpr))
7336 return false;
7337
7338 if (!this->emitInv(E))
7339 return false;
7340
7341 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
7342 return this->emitCast(PT_Bool, ET, E);
7343 return true;
7344 case UO_Minus: // -x
7345 if (!T)
7346 return this->emitError(E);
7347
7348 if (!this->visit(SubExpr))
7349 return false;
7350 return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
7351 case UO_Plus: // +x
7352 if (!T)
7353 return this->emitError(E);
7354
7355 if (!this->visit(SubExpr)) // noop
7356 return false;
7357 return DiscardResult ? this->emitPop(*T, E) : true;
7358 case UO_AddrOf: // &x
7359 if (E->getType()->isMemberPointerType()) {
7360 // C++11 [expr.unary.op]p3 has very strict rules on how the address of a
7361 // member can be formed.
7362 if (DiscardResult)
7363 return true;
7364 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(), E);
7365 }
7366 // We should already have a pointer when we get here.
7367 return this->delegate(SubExpr);
7368 case UO_Deref: // *x
7369 if (DiscardResult)
7370 return this->discard(SubExpr);
7371
7372 if (!this->visit(SubExpr))
7373 return false;
7374
7375 if (!SubExpr->getType()->isFunctionPointerType() && !this->emitCheckNull(E))
7376 return false;
7377
7378 if (classifyPrim(SubExpr) == PT_Ptr)
7379 return this->emitNarrowPtr(E);
7380 return true;
7381
7382 case UO_Not: // ~x
7383 if (!T)
7384 return this->emitError(E);
7385
7386 if (!this->visit(SubExpr))
7387 return false;
7388 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
7389 case UO_Real: // __real x
7390 if (!T)
7391 return false;
7392 return this->delegate(SubExpr);
7393 case UO_Imag: { // __imag x
7394 if (!T)
7395 return false;
7396 if (!this->discard(SubExpr))
7397 return false;
7398 return DiscardResult
7399 ? true
7400 : this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);
7401 }
7402 case UO_Extension:
7403 return this->delegate(SubExpr);
7404 case UO_Coawait:
7405 assert(false && "Unhandled opcode");
7406 }
7407
7408 return false;
7409}
7410
7411template <class Emitter>
7413 const Expr *SubExpr = E->getSubExpr();
7414 assert(SubExpr->getType()->isAnyComplexType());
7415
7416 if (DiscardResult)
7417 return this->discard(SubExpr);
7418
7419 OptPrimType ResT = classify(E);
7420 auto prepareResult = [=]() -> bool {
7421 if (!ResT && !Initializing) {
7422 UnsignedOrNone LocalIndex = allocateLocal(SubExpr);
7423 if (!LocalIndex)
7424 return false;
7425 return this->emitGetPtrLocal(*LocalIndex, E);
7426 }
7427
7428 return true;
7429 };
7430
7431 // The offset of the temporary, if we created one.
7432 unsigned SubExprOffset = ~0u;
7433 auto createTemp = [=, &SubExprOffset]() -> bool {
7434 SubExprOffset =
7435 this->allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
7436 if (!this->visit(SubExpr))
7437 return false;
7438 return this->emitSetLocal(PT_Ptr, SubExprOffset, E);
7439 };
7440
7441 PrimType ElemT = classifyComplexElementType(SubExpr->getType());
7442 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
7443 if (!this->emitGetLocal(PT_Ptr, Offset, E))
7444 return false;
7445 return this->emitArrayElemPop(ElemT, Index, E);
7446 };
7447
7448 switch (E->getOpcode()) {
7449 case UO_Minus: // -x
7450 if (!prepareResult())
7451 return false;
7452 if (!createTemp())
7453 return false;
7454 for (unsigned I = 0; I != 2; ++I) {
7455 if (!getElem(SubExprOffset, I))
7456 return false;
7457 if (!this->emitNeg(ElemT, E))
7458 return false;
7459 if (!this->emitInitElem(ElemT, I, E))
7460 return false;
7461 }
7462 break;
7463
7464 case UO_Plus: // +x
7465 case UO_AddrOf: // &x
7466 case UO_Deref: // *x
7467 return this->delegate(SubExpr);
7468
7469 case UO_LNot:
7470 if (!this->visit(SubExpr))
7471 return false;
7472 if (!this->emitComplexBoolCast(SubExpr))
7473 return false;
7474 if (!this->emitInv(E))
7475 return false;
7476 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
7477 return this->emitCast(PT_Bool, ET, E);
7478 return true;
7479
7480 case UO_Real:
7481 return this->emitComplexReal(SubExpr);
7482
7483 case UO_Imag:
7484 if (!this->visit(SubExpr))
7485 return false;
7486
7487 if (SubExpr->isLValue()) {
7488 if (!this->emitConstUint8(1, E))
7489 return false;
7490 return this->emitArrayElemPtrPopUint8(E);
7491 }
7492
7493 // Since our _Complex implementation does not map to a primitive type,
7494 // we sometimes have to do the lvalue-to-rvalue conversion here manually.
7495 return this->emitArrayElemPop(classifyPrim(E->getType()), 1, E);
7496
7497 case UO_Not: // ~x
7498 if (!this->delegate(SubExpr))
7499 return false;
7500 // Negate the imaginary component.
7501 if (!this->emitArrayElem(ElemT, 1, E))
7502 return false;
7503 if (!this->emitNeg(ElemT, E))
7504 return false;
7505 if (!this->emitInitElem(ElemT, 1, E))
7506 return false;
7507 return DiscardResult ? this->emitPopPtr(E) : true;
7508
7509 case UO_Extension:
7510 return this->delegate(SubExpr);
7511
7512 default:
7513 return this->emitInvalid(E);
7514 }
7515
7516 return true;
7517}
7518
7519template <class Emitter>
7521 const Expr *SubExpr = E->getSubExpr();
7522 assert(SubExpr->getType()->isVectorType());
7523
7524 if (DiscardResult)
7525 return this->discard(SubExpr);
7526
7527 auto UnaryOp = E->getOpcode();
7528 if (UnaryOp == UO_Extension)
7529 return this->delegate(SubExpr);
7530
7531 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
7532 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
7533 return this->emitInvalid(E);
7534
7535 // Nothing to do here.
7536 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
7537 return this->delegate(SubExpr);
7538
7539 if (!Initializing) {
7540 UnsignedOrNone LocalIndex = allocateLocal(SubExpr);
7541 if (!LocalIndex)
7542 return false;
7543 if (!this->emitGetPtrLocal(*LocalIndex, E))
7544 return false;
7545 }
7546
7547 // The offset of the temporary, if we created one.
7548 unsigned SubExprOffset =
7549 this->allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
7550 if (!this->visit(SubExpr))
7551 return false;
7552 if (!this->emitSetLocal(PT_Ptr, SubExprOffset, E))
7553 return false;
7554
7555 const auto *VecTy = SubExpr->getType()->getAs<VectorType>();
7556 PrimType ElemT = classifyVectorElementType(SubExpr->getType());
7557 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
7558 if (!this->emitGetLocal(PT_Ptr, Offset, E))
7559 return false;
7560 return this->emitArrayElemPop(ElemT, Index, E);
7561 };
7562
7563 switch (UnaryOp) {
7564 case UO_Minus:
7565 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
7566 if (!getElem(SubExprOffset, I))
7567 return false;
7568 if (!this->emitNeg(ElemT, E))
7569 return false;
7570 if (!this->emitInitElem(ElemT, I, E))
7571 return false;
7572 }
7573 break;
7574 case UO_LNot: { // !x
7575 // In C++, the logic operators !, &&, || are available for vectors. !v is
7576 // equivalent to v == 0.
7577 //
7578 // The result of the comparison is a vector of the same width and number of
7579 // elements as the comparison operands with a signed integral element type.
7580 //
7581 // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
7582 QualType ResultVecTy = E->getType();
7583 PrimType ResultVecElemT =
7584 classifyPrim(ResultVecTy->getAs<VectorType>()->getElementType());
7585 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
7586 if (!getElem(SubExprOffset, I))
7587 return false;
7588 // operator ! on vectors returns -1 for 'truth', so negate it.
7589 if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E))
7590 return false;
7591 if (!this->emitInv(E))
7592 return false;
7593 if (!this->emitPrimCast(PT_Bool, ElemT, VecTy->getElementType(), E))
7594 return false;
7595 if (!this->emitNeg(ElemT, E))
7596 return false;
7597 if (ElemT != ResultVecElemT &&
7598 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy, E))
7599 return false;
7600 if (!this->emitInitElem(ResultVecElemT, I, E))
7601 return false;
7602 }
7603 break;
7604 }
7605 case UO_Not: // ~x
7606 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
7607 if (!getElem(SubExprOffset, I))
7608 return false;
7609 if (ElemT == PT_Bool) {
7610 if (!this->emitInv(E))
7611 return false;
7612 } else {
7613 if (!this->emitComp(ElemT, E))
7614 return false;
7615 }
7616 if (!this->emitInitElem(ElemT, I, E))
7617 return false;
7618 }
7619 break;
7620 default:
7621 llvm_unreachable("Unsupported unary operators should be handled up front");
7622 }
7623 return true;
7624}
7625
7626template <class Emitter>
7628 if (DiscardResult)
7629 return true;
7630
7631 if (const auto *ECD = dyn_cast<EnumConstantDecl>(D))
7632 return this->emitConst(ECD->getInitVal(), E);
7633 if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
7634 const Function *F = getFunction(FuncDecl);
7635 return F && this->emitGetFnPtr(F, E);
7636 }
7637 if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
7638 if (UnsignedOrNone Index = P.getOrCreateGlobal(D)) {
7639 if (OptPrimType T = classify(D->getType())) {
7640 if (!this->visitAPValue(TPOD->getValue(), *T, E))
7641 return false;
7642 return this->emitInitGlobal(*T, *Index, E);
7643 }
7644
7645 if (!this->emitGetPtrGlobal(*Index, E))
7646 return false;
7647 if (!this->visitAPValueInitializer(TPOD->getValue(), E, TPOD->getType()))
7648 return false;
7649 return this->emitFinishInit(E);
7650 }
7651 return false;
7652 }
7653
7654 // References are implemented via pointers, so when we see a DeclRefExpr
7655 // pointing to a reference, we need to get its value directly (i.e. the
7656 // pointer to the actual value) instead of a pointer to the pointer to the
7657 // value.
7658 QualType DeclType = D->getType();
7659 bool IsReference = DeclType->isReferenceType();
7660
7661 // Function parameters.
7662 // Note that it's important to check them first since we might have a local
7663 // variable created for a ParmVarDecl as well.
7664 if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
7665 if (Ctx.getLangOpts().CPlusPlus && !Ctx.getLangOpts().CPlusPlus11 &&
7666 !DeclType->isIntegralOrEnumerationType()) {
7667 return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
7668 /*InitializerFailed=*/false, E);
7669 }
7670 if (auto It = this->Params.find(PVD); It != this->Params.end()) {
7671 if (IsReference || !It->second.IsPtr)
7672 return this->emitGetParam(classifyPrim(E), It->second.Index, E);
7673
7674 return this->emitGetPtrParam(It->second.Index, E);
7675 }
7676
7677 if (!Ctx.getLangOpts().CPlusPlus23 && IsReference)
7678 return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
7679 /*InitializerFailed=*/false, E);
7680 }
7681 // Local variables.
7682 if (auto It = Locals.find(D); It != Locals.end()) {
7683 const unsigned Offset = It->second.Offset;
7684 if (IsReference) {
7685 assert(classifyPrim(E) == PT_Ptr);
7686 return this->emitGetRefLocal(Offset, E);
7687 }
7688 return this->emitGetPtrLocal(Offset, E);
7689 }
7690 // Global variables.
7691 if (auto GlobalIndex = P.getGlobal(D)) {
7692 if (IsReference) {
7693 if (!Ctx.getLangOpts().CPlusPlus11)
7694 return this->emitGetGlobal(classifyPrim(E), *GlobalIndex, E);
7695 if (!Ctx.getLangOpts().CPlusPlus23)
7696 return this->emitGetGlobalUnchecked(classifyPrim(E), *GlobalIndex, E);
7697 return this->emitGetRefGlobal(*GlobalIndex, E);
7698 }
7699
7700 return this->emitGetPtrGlobal(*GlobalIndex, E);
7701 }
7702
7703 // In case we need to re-visit a declaration.
7704 auto revisit = [&](const VarDecl *VD,
7705 bool IsConstexprUnknown = true) -> bool {
7707 IsConstexprUnknown);
7708 if (!this->emitPushCC(VD->hasConstantInitialization(), E))
7709 return false;
7710 auto VarState = this->visitDecl(VD);
7711
7712 if (!this->emitPopCC(E))
7713 return false;
7714
7715 if (VarState.notCreated())
7716 return true;
7717 if (!VarState)
7718 return false;
7719 // Retry.
7720 return this->visitDeclRef(D, E);
7721 };
7722
7723 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
7724 // Lambda captures.
7725 if (auto It = this->LambdaCaptures.find(D);
7726 It != this->LambdaCaptures.end()) {
7727 auto [Offset, IsPtr] = It->second;
7728
7729 if (IsPtr)
7730 return this->emitGetThisFieldPtr(Offset, E);
7731 return this->emitGetPtrThisField(Offset, E);
7732 }
7733 }
7734
7735 if (const auto *DRE = dyn_cast<DeclRefExpr>(E);
7736 DRE && DRE->refersToEnclosingVariableOrCapture()) {
7737 if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture())
7738 return revisit(VD);
7739 }
7740
7741 if (const auto *BD = dyn_cast<BindingDecl>(D))
7742 return this->visit(BD->getBinding());
7743
7744 // Avoid infinite recursion.
7745 if (D == InitializingDecl)
7746 return this->emitDummyPtr(D, E);
7747
7748 // Try to lazily visit (or emit dummy pointers for) declarations
7749 // we haven't seen yet.
7750 const auto *VD = dyn_cast<VarDecl>(D);
7751 if (!VD)
7752 return this->emitError(E);
7753
7754 // For C.
7755 if (!Ctx.getLangOpts().CPlusPlus) {
7756 if (VD->getInit() && !VD->getInit()->isValueDependent() &&
7757 DeclType.isConstant(Ctx.getASTContext()) && !VD->isWeak() &&
7758 VD->evaluateValue())
7759 return revisit(VD, /*IsConstexprUnknown=*/false);
7760 return this->emitDummyPtr(D, E);
7761 }
7762
7763 // ... and C++.
7764 const auto typeShouldBeVisited = [&](QualType T) -> bool {
7765 if (T.isConstant(Ctx.getASTContext()))
7766 return true;
7767 return T->isReferenceType();
7768 };
7769
7770 if ((VD->hasGlobalStorage() || VD->isStaticDataMember()) &&
7771 typeShouldBeVisited(DeclType)) {
7772 if (const Expr *Init = VD->getAnyInitializer();
7773 Init && !Init->isValueDependent()) {
7774 // Whether or not the evaluation is successul doesn't really matter
7775 // here -- we will create a global variable in any case, and that
7776 // will have the state of initializer evaluation attached.
7777 APValue V;
7779 (void)Init->EvaluateAsInitializer(V, Ctx.getASTContext(), VD, Notes,
7780 true);
7781 return this->visitDeclRef(D, E);
7782 }
7783 return revisit(VD, !VD->isConstexpr() && DeclType->isReferenceType());
7784 }
7785
7786 // FIXME: The evaluateValue() check here is a little ridiculous, since
7787 // it will ultimately call into Context::evaluateAsInitializer(). In
7788 // other words, we're evaluating the initializer, just to know if we can
7789 // evaluate the initializer.
7790 if (VD->isLocalVarDecl() && typeShouldBeVisited(DeclType) && VD->getInit() &&
7791 !VD->getInit()->isValueDependent()) {
7792 if (VD->evaluateValue()) {
7793 bool IsConstexprUnknown = !DeclType.isConstant(Ctx.getASTContext()) &&
7794 !DeclType->isReferenceType();
7795 // Revisit the variable declaration, but make sure it's associated with a
7796 // different evaluation, so e.g. mutable reads don't work on it.
7797 EvalIDScope _(Ctx);
7798 return revisit(VD, IsConstexprUnknown);
7799 } else if (Ctx.getLangOpts().CPlusPlus23 && IsReference)
7800 return revisit(VD, /*IsConstexprUnknown=*/true);
7801
7802 if (IsReference)
7803 return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
7804 /*InitializerFailed=*/true, E);
7805 }
7806
7807 return this->emitDummyPtr(
7808 D, E, Ctx.getLangOpts().CPlusPlus23 && DeclType->isReferenceType());
7809}
7810
7811template <class Emitter>
7813 const auto *D = E->getDecl();
7814 return this->visitDeclRef(D, E);
7815}
7816
7817template <class Emitter>
7819 const DesignatedInitUpdateExpr *E) {
7820 assert(E->getType()->isRecordType());
7821 if (!this->visitInitializer(E->getBase()))
7822 return false;
7823 return this->visitInitializer(E->getUpdater());
7824}
7825
7826template <class Emitter> bool Compiler<Emitter>::emitCleanup() {
7827 for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent()) {
7828 if (!C->destroyLocals())
7829 return false;
7830 }
7831 return true;
7832}
7833
7834template <class Emitter>
7835unsigned Compiler<Emitter>::collectBaseOffset(const QualType BaseType,
7836 const QualType DerivedType) {
7837 const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
7838 if (const auto *R = Ty->getPointeeCXXRecordDecl())
7839 return R;
7840 return Ty->getAsCXXRecordDecl();
7841 };
7842 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
7843 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
7844
7845 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
7846}
7847
7848/// Emit casts from a PrimType to another PrimType.
7849template <class Emitter>
7850bool Compiler<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT,
7851 QualType ToQT, const Expr *E) {
7852
7853 if (FromT == PT_Float) {
7854 // Floating to floating.
7855 if (ToT == PT_Float) {
7856 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
7857 return this->emitCastFP(ToSem, getRoundingMode(E), E);
7858 }
7859
7860 if (ToT == PT_IntAP)
7861 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
7862 getFPOptions(E), E);
7863 if (ToT == PT_IntAPS)
7864 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
7865 getFPOptions(E), E);
7866
7867 // Float to integral.
7868 if (isIntegerOrBoolType(ToT) || ToT == PT_Bool)
7869 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
7870 }
7871
7872 if (isIntegerOrBoolType(FromT) || FromT == PT_Bool) {
7873 if (ToT == PT_IntAP)
7874 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
7875 if (ToT == PT_IntAPS)
7876 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
7877
7878 // Integral to integral.
7879 if (isIntegerOrBoolType(ToT) || ToT == PT_Bool)
7880 return FromT != ToT ? this->emitCast(FromT, ToT, E) : true;
7881
7882 if (ToT == PT_Float) {
7883 // Integral to floating.
7884 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
7885 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E);
7886 }
7887 }
7888
7889 return false;
7890}
7891
7892template <class Emitter>
7893bool Compiler<Emitter>::emitIntegralCast(PrimType FromT, PrimType ToT,
7894 QualType ToQT, const Expr *E) {
7895 assert(FromT != ToT);
7896
7897 if (ToT == PT_IntAP)
7898 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
7899 if (ToT == PT_IntAPS)
7900 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
7901
7902 return this->emitCast(FromT, ToT, E);
7903}
7904
7905/// Emits __real(SubExpr)
7906template <class Emitter>
7907bool Compiler<Emitter>::emitComplexReal(const Expr *SubExpr) {
7908 assert(SubExpr->getType()->isAnyComplexType());
7909
7910 if (DiscardResult)
7911 return this->discard(SubExpr);
7912
7913 if (!this->visit(SubExpr))
7914 return false;
7915 if (SubExpr->isLValue()) {
7916 if (!this->emitConstUint8(0, SubExpr))
7917 return false;
7918 return this->emitArrayElemPtrPopUint8(SubExpr);
7919 }
7920
7921 // Rvalue, load the actual element.
7922 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->getType()),
7923 0, SubExpr);
7924}
7925
7926template <class Emitter>
7927bool Compiler<Emitter>::emitComplexBoolCast(const Expr *E) {
7928 assert(!DiscardResult);
7929 PrimType ElemT = classifyComplexElementType(E->getType());
7930 // We emit the expression (__real(E) != 0 || __imag(E) != 0)
7931 // for us, that means (bool)E[0] || (bool)E[1]
7932 if (!this->emitArrayElem(ElemT, 0, E))
7933 return false;
7934 if (ElemT == PT_Float) {
7935 if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
7936 return false;
7937 } else {
7938 if (!this->emitCast(ElemT, PT_Bool, E))
7939 return false;
7940 }
7941
7942 // We now have the bool value of E[0] on the stack.
7943 LabelTy LabelTrue = this->getLabel();
7944 if (!this->jumpTrue(LabelTrue, E))
7945 return false;
7946
7947 if (!this->emitArrayElemPop(ElemT, 1, E))
7948 return false;
7949 if (ElemT == PT_Float) {
7950 if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
7951 return false;
7952 } else {
7953 if (!this->emitCast(ElemT, PT_Bool, E))
7954 return false;
7955 }
7956 // Leave the boolean value of E[1] on the stack.
7957 LabelTy EndLabel = this->getLabel();
7958 this->jump(EndLabel, E);
7959
7960 this->emitLabel(LabelTrue);
7961 if (!this->emitPopPtr(E))
7962 return false;
7963 if (!this->emitConstBool(true, E))
7964 return false;
7965
7966 this->fallthrough(EndLabel);
7967 this->emitLabel(EndLabel);
7968
7969 return true;
7970}
7971
7972template <class Emitter>
7973bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS,
7974 const BinaryOperator *E) {
7975 assert(E->isComparisonOp());
7976 assert(!Initializing);
7977 if (DiscardResult)
7978 return this->discard(LHS) && this->discard(RHS);
7979
7980 PrimType ElemT;
7981 bool LHSIsComplex;
7982 unsigned LHSOffset;
7983 if (LHS->getType()->isAnyComplexType()) {
7984 LHSIsComplex = true;
7985 ElemT = classifyComplexElementType(LHS->getType());
7986 LHSOffset = allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true);
7987 if (!this->visit(LHS))
7988 return false;
7989 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
7990 return false;
7991 } else {
7992 LHSIsComplex = false;
7993 PrimType LHST = classifyPrim(LHS->getType());
7994 LHSOffset = this->allocateLocalPrimitive(LHS, LHST, /*IsConst=*/true);
7995 if (!this->visit(LHS))
7996 return false;
7997 if (!this->emitSetLocal(LHST, LHSOffset, E))
7998 return false;
7999 }
8000
8001 bool RHSIsComplex;
8002 unsigned RHSOffset;
8003 if (RHS->getType()->isAnyComplexType()) {
8004 RHSIsComplex = true;
8005 ElemT = classifyComplexElementType(RHS->getType());
8006 RHSOffset = allocateLocalPrimitive(RHS, PT_Ptr, /*IsConst=*/true);
8007 if (!this->visit(RHS))
8008 return false;
8009 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
8010 return false;
8011 } else {
8012 RHSIsComplex = false;
8013 PrimType RHST = classifyPrim(RHS->getType());
8014 RHSOffset = this->allocateLocalPrimitive(RHS, RHST, /*IsConst=*/true);
8015 if (!this->visit(RHS))
8016 return false;
8017 if (!this->emitSetLocal(RHST, RHSOffset, E))
8018 return false;
8019 }
8020
8021 auto getElem = [&](unsigned LocalOffset, unsigned Index,
8022 bool IsComplex) -> bool {
8023 if (IsComplex) {
8024 if (!this->emitGetLocal(PT_Ptr, LocalOffset, E))
8025 return false;
8026 return this->emitArrayElemPop(ElemT, Index, E);
8027 }
8028 return this->emitGetLocal(ElemT, LocalOffset, E);
8029 };
8030
8031 for (unsigned I = 0; I != 2; ++I) {
8032 // Get both values.
8033 if (!getElem(LHSOffset, I, LHSIsComplex))
8034 return false;
8035 if (!getElem(RHSOffset, I, RHSIsComplex))
8036 return false;
8037 // And compare them.
8038 if (!this->emitEQ(ElemT, E))
8039 return false;
8040
8041 if (!this->emitCastBoolUint8(E))
8042 return false;
8043 }
8044
8045 // We now have two bool values on the stack. Compare those.
8046 if (!this->emitAddUint8(E))
8047 return false;
8048 if (!this->emitConstUint8(2, E))
8049 return false;
8050
8051 if (E->getOpcode() == BO_EQ) {
8052 if (!this->emitEQUint8(E))
8053 return false;
8054 } else if (E->getOpcode() == BO_NE) {
8055 if (!this->emitNEUint8(E))
8056 return false;
8057 } else
8058 return false;
8059
8060 // In C, this returns an int.
8061 if (PrimType ResT = classifyPrim(E->getType()); ResT != PT_Bool)
8062 return this->emitCast(PT_Bool, ResT, E);
8063 return true;
8064}
8065
8066/// When calling this, we have a pointer of the local-to-destroy
8067/// on the stack.
8068/// Emit destruction of record types (or arrays of record types).
8069template <class Emitter>
8070bool Compiler<Emitter>::emitRecordDestructionPop(const Record *R,
8071 SourceInfo Loc) {
8072 assert(R);
8073 assert(!R->hasTrivialDtor());
8074 const CXXDestructorDecl *Dtor = R->getDestructor();
8075 assert(Dtor);
8076 const Function *DtorFunc = getFunction(Dtor);
8077 if (!DtorFunc)
8078 return false;
8079 assert(DtorFunc->hasThisPointer());
8080 assert(DtorFunc->getNumParams() == 1);
8081 return this->emitCall(DtorFunc, 0, Loc);
8082}
8083/// When calling this, we have a pointer of the local-to-destroy
8084/// on the stack.
8085/// Emit destruction of record types (or arrays of record types).
8086template <class Emitter>
8087bool Compiler<Emitter>::emitDestructionPop(const Descriptor *Desc,
8088 SourceInfo Loc) {
8089 assert(Desc);
8090 assert(!Desc->hasTrivialDtor());
8091
8092 // Arrays.
8093 if (Desc->isArray()) {
8094 const Descriptor *ElemDesc = Desc->ElemDesc;
8095 assert(ElemDesc);
8096
8097 unsigned N = Desc->getNumElems();
8098 if (N == 0)
8099 return this->emitPopPtr(Loc);
8100
8101 for (ssize_t I = N - 1; I >= 1; --I) {
8102 if (!this->emitConstUint64(I, Loc))
8103 return false;
8104 if (!this->emitArrayElemPtrUint64(Loc))
8105 return false;
8106 if (!this->emitDestructionPop(ElemDesc, Loc))
8107 return false;
8108 }
8109 // Last iteration, removes the instance pointer from the stack.
8110 if (!this->emitConstUint64(0, Loc))
8111 return false;
8112 if (!this->emitArrayElemPtrPopUint64(Loc))
8113 return false;
8114 return this->emitDestructionPop(ElemDesc, Loc);
8115 }
8116
8117 assert(Desc->ElemRecord);
8118 assert(!Desc->ElemRecord->hasTrivialDtor());
8119 return this->emitRecordDestructionPop(Desc->ElemRecord, Loc);
8120}
8121
8122/// Create a dummy pointer for the given decl (or expr) and
8123/// push a pointer to it on the stack.
8124template <class Emitter>
8125bool Compiler<Emitter>::emitDummyPtr(const DeclTy &D, const Expr *E, bool CU) {
8126 assert(!DiscardResult && "Should've been checked before");
8127 unsigned DummyID = P.getOrCreateDummy(D, CU);
8128
8129 if (!this->emitGetPtrGlobal(DummyID, E))
8130 return false;
8131 if (E->getType()->isVoidType())
8132 return true;
8133
8134 // Convert the dummy pointer to another pointer type if we have to.
8135 if (PrimType PT = classifyPrim(E); PT != PT_Ptr) {
8136 if (isPtrType(PT))
8137 return this->emitDecayPtr(PT_Ptr, PT, E);
8138 return false;
8139 }
8140 return true;
8141}
8142
8143template <class Emitter>
8144bool Compiler<Emitter>::emitFloat(const APFloat &F, const Expr *E) {
8145 if (Floating::singleWord(F.getSemantics()))
8146 return this->emitConstFloat(Floating(F), E);
8147
8148 APInt I = F.bitcastToAPInt();
8149 return this->emitConstFloat(
8150 Floating(const_cast<uint64_t *>(I.getRawData()),
8151 llvm::APFloatBase::SemanticsToEnum(F.getSemantics())),
8152 E);
8153}
8154
8155// This function is constexpr if and only if To, From, and the types of
8156// all subobjects of To and From are types T such that...
8157// (3.1) - is_union_v<T> is false;
8158// (3.2) - is_pointer_v<T> is false;
8159// (3.3) - is_member_pointer_v<T> is false;
8160// (3.4) - is_volatile_v<T> is false; and
8161// (3.5) - T has no non-static data members of reference type
8162template <class Emitter>
8163bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) {
8164 const Expr *SubExpr = E->getSubExpr();
8165 QualType FromType = SubExpr->getType();
8166 QualType ToType = E->getType();
8167 OptPrimType ToT = classify(ToType);
8168
8169 assert(!ToType->isReferenceType());
8170
8171 // Prepare storage for the result in case we discard.
8172 if (DiscardResult && !Initializing && !ToT) {
8173 UnsignedOrNone LocalIndex = allocateLocal(E);
8174 if (!LocalIndex)
8175 return false;
8176 if (!this->emitGetPtrLocal(*LocalIndex, E))
8177 return false;
8178 }
8179
8180 // Get a pointer to the value-to-cast on the stack.
8181 // For CK_LValueToRValueBitCast, this is always an lvalue and
8182 // we later assume it to be one (i.e. a PT_Ptr). However,
8183 // we call this function for other utility methods where
8184 // a bitcast might be useful, so convert it to a PT_Ptr in that case.
8185 if (SubExpr->isGLValue() || FromType->isVectorType()) {
8186 if (!this->visit(SubExpr))
8187 return false;
8188 } else if (OptPrimType FromT = classify(SubExpr)) {
8189 unsigned TempOffset =
8190 allocateLocalPrimitive(SubExpr, *FromT, /*IsConst=*/true);
8191 if (!this->visit(SubExpr))
8192 return false;
8193 if (!this->emitSetLocal(*FromT, TempOffset, E))
8194 return false;
8195 if (!this->emitGetPtrLocal(TempOffset, E))
8196 return false;
8197 } else {
8198 return false;
8199 }
8200
8201 if (!ToT) {
8202 if (!this->emitBitCast(E))
8203 return false;
8204 return DiscardResult ? this->emitPopPtr(E) : true;
8205 }
8206 assert(ToT);
8207
8208 const llvm::fltSemantics *TargetSemantics = nullptr;
8209 if (ToT == PT_Float)
8210 TargetSemantics = &Ctx.getFloatSemantics(ToType);
8211
8212 // Conversion to a primitive type. FromType can be another
8213 // primitive type, or a record/array.
8214 bool ToTypeIsUChar = (ToType->isSpecificBuiltinType(BuiltinType::UChar) ||
8215 ToType->isSpecificBuiltinType(BuiltinType::Char_U));
8216 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
8217
8218 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->isStdByteType(),
8219 ResultBitWidth, TargetSemantics,
8220 ToType.getTypePtr(), E))
8221 return false;
8222
8223 if (DiscardResult)
8224 return this->emitPop(*ToT, E);
8225
8226 return true;
8227}
8228
8229/// Replicate a scalar value into every scalar element of an aggregate.
8230/// The scalar is stored in a local at \p SrcOffset and a pointer to the
8231/// destination must be on top of the interpreter stack. Each element receives
8232/// the scalar, cast to its own type.
8233template <class Emitter>
8234bool Compiler<Emitter>::emitHLSLAggregateSplat(PrimType SrcT,
8235 unsigned SrcOffset,
8236 QualType DestType,
8237 const Expr *E) {
8238 // Vectors and matrices are treated as flat sequences of elements.
8239 unsigned NumElems = 0;
8240 QualType ElemType;
8241 if (const auto *VT = DestType->getAs<VectorType>()) {
8242 NumElems = VT->getNumElements();
8243 ElemType = VT->getElementType();
8244 } else if (const auto *MT = DestType->getAs<ConstantMatrixType>()) {
8245 NumElems = MT->getNumElementsFlattened();
8246 ElemType = MT->getElementType();
8247 }
8248 if (NumElems > 0) {
8249 PrimType ElemT = classifyPrim(ElemType);
8250 for (unsigned I = 0; I != NumElems; ++I) {
8251 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8252 return false;
8253 if (!this->emitPrimCast(SrcT, ElemT, ElemType, E))
8254 return false;
8255 if (!this->emitInitElem(ElemT, I, E))
8256 return false;
8257 }
8258 return true;
8259 }
8260
8261 // Arrays: primitive elements are filled directly; composite elements
8262 // require recursion into each sub-aggregate.
8263 if (const auto *AT = DestType->getAsArrayTypeUnsafe()) {
8264 const auto *CAT = cast<ConstantArrayType>(AT);
8265 QualType ArrElemType = CAT->getElementType();
8266 unsigned ArrSize = CAT->getZExtSize();
8267
8268 if (OptPrimType ElemT = classify(ArrElemType)) {
8269 for (unsigned I = 0; I != ArrSize; ++I) {
8270 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8271 return false;
8272 if (!this->emitPrimCast(SrcT, *ElemT, ArrElemType, E))
8273 return false;
8274 if (!this->emitInitElem(*ElemT, I, E))
8275 return false;
8276 }
8277 } else {
8278 for (unsigned I = 0; I != ArrSize; ++I) {
8279 if (!this->emitConstUint32(I, E))
8280 return false;
8281 if (!this->emitArrayElemPtrUint32(E))
8282 return false;
8283 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, ArrElemType, E))
8284 return false;
8285 if (!this->emitFinishInitPop(E))
8286 return false;
8287 }
8288 }
8289 return true;
8290 }
8291
8292 // Records: fill base classes first, then named fields in declaration
8293 // order.
8294 if (DestType->isRecordType()) {
8295 const Record *R = getRecord(DestType);
8296 if (!R)
8297 return false;
8298
8299 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
8300 for (const CXXBaseSpecifier &BS : CXXRD->bases()) {
8301 const Record::Base *B = R->getBase(BS.getType());
8302 assert(B);
8303 if (!this->emitGetPtrBase(B->Offset, E))
8304 return false;
8305 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, BS.getType(), E))
8306 return false;
8307 if (!this->emitFinishInitPop(E))
8308 return false;
8309 }
8310 }
8311
8312 for (const Record::Field &F : R->fields()) {
8313 if (F.isUnnamedBitField())
8314 continue;
8315
8316 QualType FieldType = F.Decl->getType();
8317 if (OptPrimType FieldT = classify(FieldType)) {
8318 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8319 return false;
8320 if (!this->emitPrimCast(SrcT, *FieldT, FieldType, E))
8321 return false;
8322 if (F.isBitField()) {
8323 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
8324 return false;
8325 } else {
8326 if (!this->emitInitField(*FieldT, F.Offset, E))
8327 return false;
8328 }
8329 } else {
8330 if (!this->emitGetPtrField(F.Offset, E))
8331 return false;
8332 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, FieldType, E))
8333 return false;
8334 if (!this->emitPopPtr(E))
8335 return false;
8336 }
8337 }
8338 return true;
8339 }
8340
8341 return false;
8342}
8343
8344/// Return the total number of scalar elements in a type. This is used
8345/// to cap how many source elements are extracted during an elementwise cast,
8346/// so we never flatten more than the destination can hold.
8347template <class Emitter>
8348unsigned Compiler<Emitter>::countHLSLFlatElements(QualType Ty) {
8349 // Vector and matrix types are treated as flat sequences of elements.
8350 if (const auto *VT = Ty->getAs<VectorType>())
8351 return VT->getNumElements();
8352 if (const auto *MT = Ty->getAs<ConstantMatrixType>())
8353 return MT->getNumElementsFlattened();
8354 // Arrays: total count is array size * scalar elements per element.
8355 if (const auto *AT = Ty->getAsArrayTypeUnsafe()) {
8356 const auto *CAT = cast<ConstantArrayType>(AT);
8357 return CAT->getZExtSize() * countHLSLFlatElements(CAT->getElementType());
8358 }
8359 // Records: sum scalar element counts of base classes and named fields.
8360 if (Ty->isRecordType()) {
8361 const Record *R = getRecord(Ty);
8362 if (!R)
8363 return 0;
8364 unsigned Count = 0;
8365 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
8366 for (const CXXBaseSpecifier &BS : CXXRD->bases())
8367 Count += countHLSLFlatElements(BS.getType());
8368 }
8369 for (const Record::Field &F : R->fields()) {
8370 if (F.isUnnamedBitField())
8371 continue;
8372 Count += countHLSLFlatElements(F.Decl->getType());
8373 }
8374 return Count;
8375 }
8376 // Scalar primitive types contribute one element.
8377 if (canClassify(Ty))
8378 return 1;
8379 return 0;
8380}
8381
8382/// Walk a source aggregate and extract every scalar element into its own local
8383/// variable. The results are appended to \p Elements in declaration order,
8384/// stopping once \p MaxElements have been collected. A pointer to the
8385/// source aggregate must be stored in the local at \p SrcOffset.
8386template <class Emitter>
8387bool Compiler<Emitter>::emitHLSLFlattenAggregate(
8388 QualType SrcType, unsigned SrcOffset,
8389 SmallVectorImpl<HLSLFlatElement> &Elements, unsigned MaxElements,
8390 const Expr *E) {
8391
8392 // Save a scalar value from the stack into a new local and record it.
8393 auto saveToLocal = [&](PrimType T) -> bool {
8394 unsigned Offset = allocateLocalPrimitive(E, T, /*IsConst=*/true);
8395 if (!this->emitSetLocal(T, Offset, E))
8396 return false;
8397 Elements.push_back({Offset, T});
8398 return true;
8399 };
8400
8401 // Save a pointer from the stack into a new local for later use.
8402 auto savePtrToLocal = [&]() -> UnsignedOrNone {
8403 unsigned Offset = allocateLocalPrimitive(E, PT_Ptr, /*IsConst=*/true);
8404 if (!this->emitSetLocal(PT_Ptr, Offset, E))
8405 return std::nullopt;
8406 return Offset;
8407 };
8408
8409 // Vectors and matrices are flat sequences of elements.
8410 unsigned NumElems = 0;
8411 QualType ElemType;
8412 if (const auto *VT = SrcType->getAs<VectorType>()) {
8413 NumElems = VT->getNumElements();
8414 ElemType = VT->getElementType();
8415 } else if (const auto *MT = SrcType->getAs<ConstantMatrixType>()) {
8416 NumElems = MT->getNumElementsFlattened();
8417 ElemType = MT->getElementType();
8418 }
8419 if (NumElems > 0) {
8420 PrimType ElemT = classifyPrim(ElemType);
8421 for (unsigned I = 0; I != NumElems && Elements.size() < MaxElements; ++I) {
8422 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
8423 return false;
8424 if (!this->emitArrayElemPop(ElemT, I, E))
8425 return false;
8426 if (!saveToLocal(ElemT))
8427 return false;
8428 }
8429 return true;
8430 }
8431
8432 // Arrays: primitive elements are extracted directly; composite elements
8433 // require recursion into each sub-aggregate.
8434 if (const auto *AT = SrcType->getAsArrayTypeUnsafe()) {
8435 const auto *CAT = cast<ConstantArrayType>(AT);
8436 QualType ArrElemType = CAT->getElementType();
8437 unsigned ArrSize = CAT->getZExtSize();
8438
8439 if (OptPrimType ElemT = classify(ArrElemType)) {
8440 for (unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
8441 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
8442 return false;
8443 if (!this->emitArrayElemPop(*ElemT, I, E))
8444 return false;
8445 if (!saveToLocal(*ElemT))
8446 return false;
8447 }
8448 } else {
8449 for (unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
8450 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
8451 return false;
8452 if (!this->emitConstUint32(I, E))
8453 return false;
8454 if (!this->emitArrayElemPtrPopUint32(E))
8455 return false;
8456 UnsignedOrNone ElemPtrOffset = savePtrToLocal();
8457 if (!ElemPtrOffset)
8458 return false;
8459 if (!emitHLSLFlattenAggregate(ArrElemType, *ElemPtrOffset, Elements,
8460 MaxElements, E))
8461 return false;
8462 }
8463 }
8464 return true;
8465 }
8466
8467 // Records: base classes come first, then named fields in declaration
8468 // order.
8469 if (SrcType->isRecordType()) {
8470 const Record *R = getRecord(SrcType);
8471 if (!R)
8472 return false;
8473
8474 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
8475 for (const CXXBaseSpecifier &BS : CXXRD->bases()) {
8476 if (Elements.size() >= MaxElements)
8477 break;
8478 const Record::Base *B = R->getBase(BS.getType());
8479 assert(B);
8480 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
8481 return false;
8482 if (!this->emitGetPtrBasePop(B->Offset, /*NullOK=*/false, E))
8483 return false;
8484 UnsignedOrNone BasePtrOffset = savePtrToLocal();
8485 if (!BasePtrOffset)
8486 return false;
8487 if (!emitHLSLFlattenAggregate(BS.getType(), *BasePtrOffset, Elements,
8488 MaxElements, E))
8489 return false;
8490 }
8491 }
8492
8493 for (const Record::Field &F : R->fields()) {
8494 if (Elements.size() >= MaxElements)
8495 break;
8496 if (F.isUnnamedBitField())
8497 continue;
8498
8499 QualType FieldType = F.Decl->getType();
8500 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
8501 return false;
8502 if (!this->emitGetPtrFieldPop(F.Offset, E))
8503 return false;
8504
8505 if (OptPrimType FieldT = classify(FieldType)) {
8506 if (!this->emitLoadPop(*FieldT, E))
8507 return false;
8508 if (!saveToLocal(*FieldT))
8509 return false;
8510 } else {
8511 UnsignedOrNone FieldPtrOffset = savePtrToLocal();
8512 if (!FieldPtrOffset)
8513 return false;
8514 if (!emitHLSLFlattenAggregate(FieldType, *FieldPtrOffset, Elements,
8515 MaxElements, E))
8516 return false;
8517 }
8518 }
8519 return true;
8520 }
8521
8522 return false;
8523}
8524
8525/// Populate an HLSL aggregate from a flat list of previously extracted source
8526/// elements, casting each to the corresponding destination element type.
8527/// \p ElemIdx tracks the current position in \p Elements and is advanced as
8528/// elements are consumed. A pointer to the destination must be on top of the
8529/// interpreter stack.
8530template <class Emitter>
8531bool Compiler<Emitter>::emitHLSLConstructAggregate(
8532 QualType DestType, ArrayRef<HLSLFlatElement> Elements, unsigned &ElemIdx,
8533 const Expr *E) {
8534
8535 // Consume the next source element, cast it, and leave it on the stack.
8536 auto loadAndCast = [&](PrimType DestT, QualType DestQT) -> bool {
8537 const auto &Src = Elements[ElemIdx++];
8538 if (!this->emitGetLocal(Src.Type, Src.LocalOffset, E))
8539 return false;
8540 return this->emitPrimCast(Src.Type, DestT, DestQT, E);
8541 };
8542
8543 // Vectors and matrices are flat sequences of elements.
8544 unsigned NumElems = 0;
8545 QualType ElemType;
8546 if (const auto *VT = DestType->getAs<VectorType>()) {
8547 NumElems = VT->getNumElements();
8548 ElemType = VT->getElementType();
8549 } else if (const auto *MT = DestType->getAs<ConstantMatrixType>()) {
8550 NumElems = MT->getNumElementsFlattened();
8551 ElemType = MT->getElementType();
8552 }
8553 if (NumElems > 0) {
8554 PrimType DestElemT = classifyPrim(ElemType);
8555 for (unsigned I = 0; I != NumElems; ++I) {
8556 if (!loadAndCast(DestElemT, ElemType))
8557 return false;
8558 if (!this->emitInitElem(DestElemT, I, E))
8559 return false;
8560 }
8561 return true;
8562 }
8563
8564 // Arrays: primitive elements are filled directly; composite elements
8565 // require recursion into each sub-aggregate.
8566 if (const auto *AT = DestType->getAsArrayTypeUnsafe()) {
8567 const auto *CAT = cast<ConstantArrayType>(AT);
8568 QualType ArrElemType = CAT->getElementType();
8569 unsigned ArrSize = CAT->getZExtSize();
8570
8571 if (OptPrimType ElemT = classify(ArrElemType)) {
8572 for (unsigned I = 0; I != ArrSize; ++I) {
8573 if (!loadAndCast(*ElemT, ArrElemType))
8574 return false;
8575 if (!this->emitInitElem(*ElemT, I, E))
8576 return false;
8577 }
8578 } else {
8579 for (unsigned I = 0; I != ArrSize; ++I) {
8580 if (!this->emitConstUint32(I, E))
8581 return false;
8582 if (!this->emitArrayElemPtrUint32(E))
8583 return false;
8584 if (!emitHLSLConstructAggregate(ArrElemType, Elements, ElemIdx, E))
8585 return false;
8586 if (!this->emitFinishInitPop(E))
8587 return false;
8588 }
8589 }
8590 return true;
8591 }
8592
8593 // Records: base classes come first, then named fields in declaration
8594 // order.
8595 if (DestType->isRecordType()) {
8596 const Record *R = getRecord(DestType);
8597 if (!R)
8598 return false;
8599
8600 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
8601 for (const CXXBaseSpecifier &BS : CXXRD->bases()) {
8602 const Record::Base *B = R->getBase(BS.getType());
8603 assert(B);
8604 if (!this->emitGetPtrBase(B->Offset, E))
8605 return false;
8606 if (!emitHLSLConstructAggregate(BS.getType(), Elements, ElemIdx, E))
8607 return false;
8608 if (!this->emitFinishInitPop(E))
8609 return false;
8610 }
8611 }
8612
8613 for (const Record::Field &F : R->fields()) {
8614 if (F.isUnnamedBitField())
8615 continue;
8616
8617 QualType FieldType = F.Decl->getType();
8618 if (OptPrimType FieldT = classify(FieldType)) {
8619 if (!loadAndCast(*FieldT, FieldType))
8620 return false;
8621 if (F.isBitField()) {
8622 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
8623 return false;
8624 } else {
8625 if (!this->emitInitField(*FieldT, F.Offset, E))
8626 return false;
8627 }
8628 } else {
8629 if (!this->emitGetPtrField(F.Offset, E))
8630 return false;
8631 if (!emitHLSLConstructAggregate(FieldType, Elements, ElemIdx, E))
8632 return false;
8633 if (!this->emitPopPtr(E))
8634 return false;
8635 }
8636 }
8637 return true;
8638 }
8639
8640 return false;
8641}
8642
8643namespace clang {
8644namespace interp {
8645
8646template class Compiler<ByteCodeEmitter>;
8647template class Compiler<EvalEmitter>;
8648
8649} // namespace interp
8650} // namespace clang
#define V(N, I)
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static void emitCleanup(CIRGenFunction &cgf, cir::CleanupScopeOp cleanupScope, EHScopeStack::Cleanup *cleanup, EHScopeStack::Cleanup::Flags flags, Address activeFlag)
static uint32_t getBitWidth(const Expr *E)
#define EMIT_ARITH_OP(OP)
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
static const Expr * stripDerivedToBaseCasts(const Expr *E)
static const Expr * stripCheckedDerivedToBaseCasts(const Expr *E)
static bool hasTrivialDefaultCtorParent(const FieldDecl *FD)
static bool initNeedsOverridenLoc(const CXXCtorInitializer *Init)
llvm::APSInt APSInt
Definition Compiler.cpp:24
Result
Implement __builtin_bit_cast and related operations.
a trap message and trap category.
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
const LValueBase getLValueBase() const
Definition APValue.cpp:1015
APValue & getArrayInitializedElt(unsigned I)
Definition APValue.h:626
ArrayRef< LValuePathEntry > getLValuePath() const
Definition APValue.cpp:1035
APSInt & getInt()
Definition APValue.h:508
APValue & getStructField(unsigned i)
Definition APValue.h:667
const FieldDecl * getUnionField() const
Definition APValue.h:679
unsigned getStructNumFields() const
Definition APValue.h:658
bool isArray() const
Definition APValue.h:493
bool isMemberPointerToDerivedMember() const
Definition APValue.cpp:1105
unsigned getArrayInitializedElts() const
Definition APValue.h:645
bool isFloat() const
Definition APValue.h:486
unsigned getStructNumBases() const
Definition APValue.h:654
const ValueDecl * getMemberPointerDecl() const
Definition APValue.cpp:1098
APValue & getUnionValue()
Definition APValue.h:683
APValue & getArrayFiller()
Definition APValue.h:637
bool isLValue() const
Definition APValue.h:490
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
Definition APValue.cpp:1112
bool isMemberPointer() const
Definition APValue.h:496
bool isInt() const
Definition APValue.h:485
unsigned getArraySize() const
Definition APValue.h:649
bool isUnion() const
Definition APValue.h:495
@ None
There is no such object (it's outside its lifetime).
Definition APValue.h:129
bool isStruct() const
Definition APValue.h:494
bool isNullPointer() const
Definition APValue.cpp:1051
APFloat & getFloat()
Definition APValue.h:522
APValue & getStructBase(unsigned i)
Definition APValue.h:662
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:229
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.
const LangOptions & getLangOpts() const
Definition ASTContext.h:961
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
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.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const VariableArrayType * getAsVariableArrayType(QualType T) const
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:4356
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Definition Expr.h:4534
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Definition Expr.h:4540
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Definition Expr.h:4546
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition Expr.h:4553
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition Expr.h:6021
Represents a loop initializing the elements of an array.
Definition Expr.h:5968
llvm::APInt getArraySize() const
Definition Expr.h:5990
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Definition Expr.h:5983
Expr * getSubExpr() const
Get the initializer to use for each array element.
Definition Expr.h:5988
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition Expr.h:2724
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Definition Expr.h:2753
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition ExprCXX.h:3000
uint64_t getValue() const
Definition ExprCXX.h:3048
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3784
QualType getElementType() const
Definition TypeBase.h:3796
Attr - This represents one attribute.
Definition Attr.h:46
Represents an attribute applied to a statement.
Definition Stmt.h:2213
Stmt * getSubStmt()
Definition Stmt.h:2249
ArrayRef< const Attr * > getAttrs() const
Definition Stmt.h:2245
Represents a C++ declaration that introduces decls from somewhere else.
Definition DeclCXX.h:3501
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4041
static bool isLogicalOp(Opcode Opc)
Definition Expr.h:4174
Expr * getLHS() const
Definition Expr.h:4091
static bool isComparisonOp(Opcode Opc)
Definition Expr.h:4141
static bool isShiftOp(Opcode Opc)
Definition Expr.h:4129
static bool isCommaOp(Opcode Opc)
Definition Expr.h:4144
static Opcode getOpForCompoundAssignment(Opcode Opc)
Definition Expr.h:4188
Expr * getRHS() const
Definition Expr.h:4093
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
Definition Expr.h:4118
static bool isAssignmentOp(Opcode Opc)
Definition Expr.h:4177
static bool isCompoundAssignmentOp(Opcode Opc)
Definition Expr.h:4182
Opcode getOpcode() const
Definition Expr.h:4086
static bool isBitwiseOp(Opcode Opc)
Definition Expr.h:4132
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6672
BreakStmt - This represents a break.
Definition Stmt.h:3145
Represents a C++2a __builtin_bit_cast(T, v) expression.
Definition ExprCXX.h:5472
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents binding an expression to a temporary.
Definition ExprCXX.h:1497
const Expr * getSubExpr() const
Definition ExprCXX.h:1519
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition ExprCXX.h:727
bool getValue() const
Definition ExprCXX.h:744
Represents a call to a C++ constructor.
Definition ExprCXX.h:1552
bool isElidable() const
Whether this construction is elidable.
Definition ExprCXX.h:1621
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition ExprCXX.h:1695
arg_range arguments()
Definition ExprCXX.h:1676
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
Definition ExprCXX.h:1654
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition ExprCXX.h:1615
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Definition ExprCXX.h:1692
Represents a C++ constructor within a class.
Definition DeclCXX.h:2620
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
Definition DeclCXX.cpp:3067
Represents a C++ base or member initializer.
Definition DeclCXX.h:2385
A default argument (C++ [dcl.fct.default]).
Definition ExprCXX.h:1274
A use of a default initializer in a constructor or in aggregate initialization.
Definition ExprCXX.h:1381
Expr * getExpr()
Get the initialization expression that will be used.
Definition ExprCXX.cpp:1112
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition ExprCXX.h:2630
FunctionDecl * getOperatorDelete() const
Definition ExprCXX.h:2669
bool isArrayForm() const
Definition ExprCXX.h:2656
bool isGlobalDelete() const
Definition ExprCXX.h:2655
Represents a C++ destructor within a class.
Definition DeclCXX.h:2882
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Definition ExprCXX.h:485
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Definition StmtCXX.h:135
DeclStmt * getBeginStmt()
Definition StmtCXX.h:163
DeclStmt * getLoopVarStmt()
Definition StmtCXX.h:169
DeclStmt * getEndStmt()
Definition StmtCXX.h:166
DeclStmt * getRangeStmt()
Definition StmtCXX.h:162
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition ExprCXX.h:1755
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Definition ExprCXX.h:1792
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2132
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition DeclCXX.h:2271
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
Definition DeclCXX.cpp:2749
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Definition DeclCXX.cpp:2728
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
Definition DeclCXX.cpp:2893
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2359
bool isArray() const
Definition ExprCXX.h:2468
QualType getAllocatedType() const
Definition ExprCXX.h:2438
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Definition ExprCXX.h:2473
Expr * getPlacementArg(unsigned I)
Definition ExprCXX.h:2507
unsigned getNumPlacementArgs() const
Definition ExprCXX.h:2498
FunctionDecl * getOperatorNew() const
Definition ExprCXX.h:2463
Expr * getInitializer()
The initializer of this new-expression.
Definition ExprCXX.h:2537
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition ExprCXX.h:4309
bool getValue() const
Definition ExprCXX.h:4332
The null pointer literal (C++11 [lex.nullptr])
Definition ExprCXX.h:772
Represents a list-initialization with parenthesis.
Definition ExprCXX.h:5141
MutableArrayRef< Expr * > getInitExprs()
Definition ExprCXX.h:5181
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
Definition DeclCXX.h:1246
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
Definition DeclCXX.cpp:1679
capture_const_range captures() const
Definition DeclCXX.h:1097
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
Definition DeclCXX.cpp:1742
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
Definition ExprCXX.h:530
A rewritten comparison expression that was originally written using operator syntax.
Definition ExprCXX.h:290
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
Definition ExprCXX.h:308
An expression "T()" which creates an rvalue of a non-class type T.
Definition ExprCXX.h:2200
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Definition ExprCXX.h:804
Represents the this expression in C++.
Definition ExprCXX.h:1158
A C++ throw-expression (C++ [except.throw]).
Definition ExprCXX.h:1212
const Expr * getSubExpr() const
Definition ExprCXX.h:1232
CXXTryStmt - A C++ try block, including all handlers.
Definition StmtCXX.h:69
CompoundStmt * getTryBlock()
Definition StmtCXX.h:100
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition ExprCXX.h:852
bool isTypeOperand() const
Definition ExprCXX.h:888
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Definition ExprCXX.cpp:166
Expr * getExprOperand() const
Definition ExprCXX.h:899
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
Definition ExprCXX.cpp:134
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Definition ExprCXX.h:1072
MSGuidDecl * getGuidDecl() const
Definition ExprCXX.h:1118
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2946
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3150
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3129
Expr * getCallee()
Definition Expr.h:3093
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition Expr.h:3137
Expr ** getArgs()
Retrieve the call arguments.
Definition Expr.h:3140
arg_range arguments()
Definition Expr.h:3198
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition Expr.cpp:1608
CaseStmt - Represent a case statement.
Definition Stmt.h:1930
Stmt * getSubStmt()
Definition Stmt.h:2043
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition Expr.h:3679
path_iterator path_begin()
Definition Expr.h:3749
CastKind getCastKind() const
Definition Expr.h:3723
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
Definition Expr.h:3766
const FieldDecl * getTargetUnionField() const
Definition Expr.h:3773
path_iterator path_end()
Definition Expr.h:3750
Expr * getSubExpr()
Definition Expr.h:3729
CharUnits - This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition CharUnits.h:122
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
static CharUnits One()
One - Construct a CharUnits quantity of one.
Definition CharUnits.h:58
unsigned getValue() const
Definition Expr.h:1632
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition Expr.h:4851
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Definition Expr.h:4887
Complex values, per C99 6.2.5p11.
Definition TypeBase.h:3337
QualType getElementType() const
Definition TypeBase.h:3347
CompoundAssignOperator - For compound assignments (e.g.
Definition Expr.h:4303
QualType getComputationLHSType() const
Definition Expr.h:4337
QualType getComputationResultType() const
Definition Expr.h:4340
CompoundLiteralExpr - [C99 6.5.2.5].
Definition Expr.h:3608
bool isFileScope() const
Definition Expr.h:3640
const Expr * getInitializer() const
Definition Expr.h:3636
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition Stmt.h:1750
body_range body()
Definition Stmt.h:1813
Stmt * body_back()
Definition Stmt.h:1818
Represents the specialization of a concept - evaluates to a prvalue of type bool.
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3822
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
Definition TypeBase.h:3898
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition Expr.h:1085
APValue getAPValueResult() const
Definition Expr.cpp:418
bool hasAPValueResult() const
Definition Expr.h:1160
Represents a concrete matrix type with constant number of rows and columns.
Definition TypeBase.h:4449
ContinueStmt - This represents a continue.
Definition Stmt.h:3129
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition Expr.h:4722
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Definition Expr.h:4812
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2122
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1273
ValueDecl * getDecl()
Definition Expr.h:1341
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition Stmt.h:1641
decl_range decls()
Definition Stmt.h:1689
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool isInvalidDecl() const
Definition DeclBase.h:596
bool hasAttr() const
Definition DeclBase.h:585
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
Stmt * getSubStmt()
Definition Stmt.h:2091
InitListExpr * getUpdater() const
Definition Expr.h:5936
DoStmt - This represents a 'do/while' stmt.
Definition Stmt.h:2842
Stmt * getBody()
Definition Stmt.h:2867
Expr * getCond()
Definition Stmt.h:2860
const Expr * getBase() const
Definition Expr.h:6581
Represents a reference to emded data.
Definition Expr.h:5129
ChildElementIter< false > begin()
Definition Expr.h:5235
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition ExprCXX.h:3661
This represents one expression.
Definition Expr.h:112
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:84
bool isGLValue() const
Definition Expr.h:287
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition Expr.h:177
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3085
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
Definition Expr.h:246
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3093
bool isPRValue() const
Definition Expr.h:285
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
Definition Expr.h:284
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
Definition Expr.cpp:3695
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
Definition Expr.cpp:3260
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
Definition Expr.h:479
QualType getType() const
Definition Expr.h:144
An expression trait intrinsic.
Definition ExprCXX.h:3073
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Definition Expr.h:6610
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
Definition Expr.cpp:4556
Represents a member of a struct/union/class.
Definition Decl.h:3182
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Definition Decl.h:3418
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
Definition Expr.h:1578
llvm::APFloat getValue() const
Definition Expr.h:1669
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition Stmt.h:2898
Stmt * getInit()
Definition Stmt.h:2913
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
Definition Stmt.cpp:1120
Stmt * getBody()
Definition Stmt.h:2942
Expr * getInc()
Definition Stmt.h:2941
Expr * getCond()
Definition Stmt.h:2940
DeclStmt * getConditionVariableDeclStmt()
If this ForStmt has a condition variable, return the faux DeclStmt associated with the creation of th...
Definition Stmt.h:2928
const Expr * getSubExpr() const
Definition Expr.h:1065
Represents a function declaration or definition.
Definition Decl.h:2018
const ParmVarDecl * getParamDecl(unsigned i) const
Definition Decl.h:2815
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition Decl.cpp:3253
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition Decl.cpp:4179
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition Decl.cpp:4167
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3736
QualType getReturnType() const
Definition Decl.h:2863
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:2792
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2395
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition Decl.cpp:4303
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
Definition Decl.cpp:3400
bool isDefaulted() const
Whether this function is defaulted.
Definition Decl.h:2403
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition Decl.cpp:3800
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Definition Decl.cpp:3173
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition Expr.h:4926
Represents a C11 generic selection.
Definition Expr.h:6182
Expr * getResultExpr()
Return the result expression of this controlling expression.
Definition Expr.h:6468
IfStmt - This represents an if/then/else.
Definition Stmt.h:2269
Stmt * getThen()
Definition Stmt.h:2358
Stmt * getInit()
Definition Stmt.h:2419
bool isNonNegatedConsteval() const
Definition Stmt.h:2454
Expr * getCond()
Definition Stmt.h:2346
bool isNegatedConsteval() const
Definition Stmt.h:2458
Stmt * getElse()
Definition Stmt.h:2367
DeclStmt * getConditionVariableDeclStmt()
If this IfStmt has a condition variable, return the faux DeclStmt associated with the creation of tha...
Definition Stmt.h:2402
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
Definition Stmt.cpp:1068
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition Expr.h:1734
const Expr * getSubExpr() const
Definition Expr.h:1746
Represents an implicitly-generated value initialization of an object of a given type.
Definition Expr.h:6057
Represents a field injected from an anonymous union/struct into the parent scope.
Definition Decl.h:3489
Describes an C or C++ initializer list.
Definition Expr.h:5302
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
Definition Expr.h:5405
ArrayRef< Expr * > inits() const
Definition Expr.h:5355
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition ExprCXX.h:1972
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
Definition ExprCXX.h:2098
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Definition ExprCXX.cpp:1407
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
Definition DeclCXX.h:3313
const Stmt * getNamedLoopOrSwitch() const
If this is a named break/continue, get the loop or switch statement that this targets.
Definition Stmt.cpp:1535
A global _GUID constant.
Definition DeclCXX.h:4403
APValue & getAsAPValue() const
Get the value of this MSGuidDecl as an APValue.
Definition DeclCXX.cpp:3862
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition ExprCXX.h:4920
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Definition ExprCXX.h:4945
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition ExprCXX.h:4937
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
Definition ExprCXX.h:4970
LifetimeExtendedTemporaryDecl * getLifetimeExtendedTemporaryDecl()
Definition ExprCXX.h:4960
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition Expr.h:3367
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition Expr.h:3450
Expr * getBase() const
Definition Expr.h:3444
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3715
This represents a decl that may have a name.
Definition Decl.h:274
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
Represents a C++ namespace alias.
Definition DeclCXX.h:3206
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Definition ExprObjC.h:220
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition ExprObjC.h:119
ObjCBoxedExpr - used for generalized expression boxing.
Definition ExprObjC.h:159
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition ExprObjC.h:342
ObjCEncodeExpr, used for @encode in Objective-C.
Definition ExprObjC.h:441
QualType getEncodedType() const
Definition ExprObjC.h:460
SourceLocation getAtLoc() const
Definition ExprObjC.h:455
bool isExpressibleAsConstantInitializer() const
Definition ExprObjC.h:68
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition ExprObjC.h:84
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition Expr.h:2530
Expr * getIndexExpr(unsigned Idx)
Definition Expr.h:2589
const OffsetOfNode & getComponent(unsigned Idx) const
Definition Expr.h:2577
unsigned getNumComponents() const
Definition Expr.h:2585
Helper class for OffsetOfExpr.
Definition Expr.h:2424
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
Definition Expr.h:2482
@ Array
An index into an array.
Definition Expr.h:2429
Kind getKind() const
Determine what kind of offsetof node this is.
Definition Expr.h:2478
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1181
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition Expr.h:1231
Expr * getSelectedExpr() const
Definition ExprCXX.h:4639
ParenExpr - This represents a parenthesized expression, e.g.
Definition Expr.h:2185
const Expr * getSubExpr() const
Definition Expr.h:2202
Represents a parameter to a function.
Definition Decl.h:1808
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3390
QualType getPointeeType() const
Definition TypeBase.h:3400
[C99 6.4.2.2] - A predefined identifier such as func.
Definition Expr.h:2008
StringLiteral * getFunctionName()
Definition Expr.h:2052
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition Expr.h:6804
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
Definition Expr.h:6852
ArrayRef< Expr * > semantics()
Definition Expr.h:6876
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
Definition TypeBase.h:8529
QualType withConst() const
Definition TypeBase.h:1174
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8445
bool isConstant(const ASTContext &Ctx) const
Definition TypeBase.h:1097
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition TypeBase.h:8518
Represents a struct/union/class.
Definition Decl.h:4347
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Definition Expr.h:7503
Base for LValueReferenceType and RValueReferenceType.
Definition TypeBase.h:3635
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
bool isSatisfied() const
Whether or not the requires clause is satisfied.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition Stmt.h:3170
Expr * getRetValue()
Definition Stmt.h:3197
SourceLocation getLocation() const
Definition Expr.h:2158
std::string ComputeName(ASTContext &Context) const
Definition Expr.cpp:592
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Definition Expr.h:4646
llvm::APSInt getShuffleMaskIdx(unsigned N) const
Definition Expr.h:4698
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Definition Expr.h:4679
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Definition Expr.h:4685
Represents an expression that computes the length of a parameter pack.
Definition ExprCXX.h:4441
unsigned getPackLength() const
Retrieve the length of the parameter pack.
Definition ExprCXX.h:4515
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition Expr.h:5020
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:2287
Represents a C++11 static_assert declaration.
Definition DeclCXX.h:4141
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition Expr.h:4598
CompoundStmt * getSubStmt()
Definition Expr.h:4615
Stmt - This represents one statement.
Definition Stmt.h:86
StmtClass getStmtClass() const
Definition Stmt.h:1503
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1802
unsigned getLength() const
Definition Expr.h:1912
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, ArrayRef< SourceLocation > Locs)
This is the "fully general" constructor that allows representation of strings formed from one or more...
Definition Expr.cpp:1193
uint32_t getCodeUnit(size_t i) const
Definition Expr.h:1885
unsigned getCharByteWidth() const
Definition Expr.h:1913
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition ExprCXX.h:4664
const SwitchCase * getNextSwitchCase() const
Definition Stmt.h:1903
SwitchStmt - This represents a 'switch' stmt.
Definition Stmt.h:2519
Expr * getCond()
Definition Stmt.h:2582
Stmt * getBody()
Definition Stmt.h:2594
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
Definition Stmt.cpp:1186
Stmt * getInit()
Definition Stmt.h:2599
SwitchCase * getSwitchCaseList()
Definition Stmt.h:2650
DeclStmt * getConditionVariableDeclStmt()
If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...
Definition Stmt.h:2633
Represents the declaration of a struct/union/class/enum.
Definition Decl.h:3739
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition Decl.h:3840
bool isUnion() const
Definition Decl.h:3950
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition ExprCXX.h:2900
bool getBoolValue() const
Definition ExprCXX.h:2951
const APValue & getAPValue() const
Definition ExprCXX.h:2956
bool isStoredAsBoolean() const
Definition ExprCXX.h:2947
The base class of the type hierarchy.
Definition TypeBase.h:1875
bool isVoidType() const
Definition TypeBase.h:9048
bool isBooleanType() const
Definition TypeBase.h:9185
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
Definition Type.cpp:3109
bool isIncompleteArrayType() const
Definition TypeBase.h:8789
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
bool isNothrowT() const
Definition Type.cpp:3293
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
bool isVoidPointerType() const
Definition Type.cpp:749
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
Definition Type.cpp:2517
bool isArrayType() const
Definition TypeBase.h:8781
bool isFunctionPointerType() const
Definition TypeBase.h:8749
bool isConstantMatrixType() const
Definition TypeBase.h:8849
bool isPointerType() const
Definition TypeBase.h:8682
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition TypeBase.h:9092
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9342
bool isReferenceType() const
Definition TypeBase.h:8706
bool isEnumeralType() const
Definition TypeBase.h:8813
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:789
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition TypeBase.h:9170
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Definition TypeBase.h:9017
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2844
bool isAnyComplexType() const
Definition TypeBase.h:8817
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
Definition TypeBase.h:9108
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
Definition TypeBase.h:9228
bool isMemberPointerType() const
Definition TypeBase.h:8763
bool isAtomicType() const
Definition TypeBase.h:8874
EnumDecl * castAsEnumDecl() const
Definition Type.h:59
bool isStdByteType() const
Definition Type.cpp:3312
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition TypeBase.h:9328
bool isPointerOrReferenceType() const
Definition TypeBase.h:8686
bool isFunctionType() const
Definition TypeBase.h:8678
bool isVectorType() const
Definition TypeBase.h:8821
bool isRealFloatingType() const
Floating point categories.
Definition Type.cpp:2405
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2983
bool isFloatingType() const
Definition Type.cpp:2389
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9275
bool isRecordType() const
Definition TypeBase.h:8809
bool isSizelessVectorType() const
Returns true for all scalable vector types.
Definition Type.cpp:2663
Base class for declarations which introduce a typedef-name.
Definition Decl.h:3584
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition Expr.h:2628
QualType getArgumentType() const
Definition Expr.h:2671
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
Definition Expr.h:2697
UnaryExprOrTypeTrait getKind() const
Definition Expr.h:2660
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2247
Expr * getSubExpr() const
Definition Expr.h:2288
Opcode getOpcode() const
Definition Expr.h:2283
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Definition Expr.h:2301
Represents C++ using-directive.
Definition DeclCXX.h:3101
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
QualType getType() const
Definition Decl.h:723
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Definition Decl.cpp:5575
QualType getType() const
Definition Value.cpp:237
Represents a variable declaration or definition.
Definition Decl.h:924
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition Decl.h:1582
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
Definition Decl.h:1591
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
Definition Decl.cpp:2554
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition Decl.h:1296
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition Decl.h:1239
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
Definition Decl.cpp:2627
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition Decl.h:1206
const Expr * getInit() const
Definition Decl.h:1381
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
Definition Decl.h:1266
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Definition Decl.h:1371
Represents a GCC generic vector type.
Definition TypeBase.h:4237
unsigned getNumElements() const
Definition TypeBase.h:4252
QualType getElementType() const
Definition TypeBase.h:4251
WhileStmt - This represents a 'while' stmt.
Definition Stmt.h:2707
Expr * getCond()
Definition Stmt.h:2759
DeclStmt * getConditionVariableDeclStmt()
If this WhileStmt has a condition variable, return the faux DeclStmt associated with the creation of ...
Definition Stmt.h:2795
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
Definition Stmt.cpp:1247
Stmt * getBody()
Definition Stmt.h:2771
A memory block, either on the stack or in the heap.
Definition InterpBlock.h:44
void invokeDtor()
Invokes the Destructor.
Compilation context for expressions.
Definition Compiler.h:112
llvm::SmallVector< InitLink > InitStack
Definition Compiler.h:490
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E)
bool VisitCXXDeleteExpr(const CXXDeleteExpr *E)
bool VisitOffsetOfExpr(const OffsetOfExpr *E)
bool visitContinueStmt(const ContinueStmt *S)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init, OptPrimType InitT)
Pointer to the array(not the element!) must be on the stack when calling this.
UnsignedOrNone allocateLocal(DeclTy &&Decl, QualType Ty=QualType(), ScopeKind=ScopeKind::Block)
Allocates a space storing a local given its type.
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E)
bool visitInitializerPop(const Expr *E)
Similar, but will also pop the pointer.
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
PrimType classifyPrim(QualType Ty) const
Classifies a known primitive type.
Definition Compiler.h:285
bool VisitTypeTraitExpr(const TypeTraitExpr *E)
bool VisitLambdaExpr(const LambdaExpr *E)
bool VisitMemberExpr(const MemberExpr *E)
llvm::DenseMap< const OpaqueValueExpr *, unsigned > OpaqueExprs
OpaqueValueExpr to location mapping.
Definition Compiler.h:466
bool VisitBinaryOperator(const BinaryOperator *E)
bool visitAttributedStmt(const AttributedStmt *S)
bool VisitPackIndexingExpr(const PackIndexingExpr *E)
bool visitAPValueInitializer(const APValue &Val, const Expr *E, QualType T)
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
bool VisitCallExpr(const CallExpr *E)
std::optional< uint64_t > ArrayIndex
Current argument index. Needed to emit ArrayInitIndexExpr.
Definition Compiler.h:472
bool VisitPseudoObjectExpr(const PseudoObjectExpr *E)
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E)
const Function * getFunction(const FunctionDecl *FD)
Returns a function for the given FunctionDecl.
bool VisitFixedPointBinOp(const BinaryOperator *E)
bool VisitCastExpr(const CastExpr *E)
Definition Compiler.cpp:213
bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E)
bool VisitFixedPointUnaryOperator(const UnaryOperator *E)
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsVolatile=false, ScopeKind SC=ScopeKind::Block)
Creates a local primitive value.
bool VisitComplexUnaryOperator(const UnaryOperator *E)
llvm::DenseMap< const SwitchCase *, LabelTy > CaseMap
Definition Compiler.h:118
bool VisitBlockExpr(const BlockExpr *E)
bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E)
Visit an APValue.
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
bool VisitLogicalBinOp(const BinaryOperator *E)
bool visitCompoundStmt(const CompoundStmt *S)
Context & Ctx
Current compilation context.
Definition Compiler.h:135
bool visitDeclRef(const ValueDecl *D, const Expr *E)
Visit the given decl as if we have a reference to it.
bool visitBreakStmt(const BreakStmt *S)
bool visitExpr(const Expr *E, bool DestroyToplevelScope) override
bool visitForStmt(const ForStmt *S)
bool VisitDeclRefExpr(const DeclRefExpr *E)
bool VisitOpaqueValueExpr(const OpaqueValueExpr *E)
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E)
bool VisitStmtExpr(const StmtExpr *E)
bool VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *E)
bool VisitFixedPointLiteral(const FixedPointLiteral *E)
const FunctionDecl * CompilingFunction
Definition Compiler.h:501
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
VarCreationState visitVarDecl(const VarDecl *VD, const Expr *Init, bool Toplevel=false)
Creates and initializes a variable from the given decl.
VariableScope< Emitter > * VarScope
Current scope.
Definition Compiler.h:469
bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init, bool ConstantContext) override
Toplevel visitDeclAndReturn().
bool VisitCXXNewExpr(const CXXNewExpr *E)
const ValueDecl * InitializingDecl
Definition Compiler.h:488
bool VisitCompoundAssignOperator(const CompoundAssignOperator *E)
bool visit(const Expr *E) override
Evaluates an expression and places the result on the stack.
bool delegate(const Expr *E)
Just pass evaluation on to E.
bool visitLValueExpr(const Expr *E, bool DestroyToplevelScope) override
bool discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
CaseMap CaseLabels
Switch case mapping.
Definition Compiler.h:497
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
const RecordType * getRecordTy(QualType Ty)
Returns a record type from a record or pointer type.
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E)
bool visitInitList(ArrayRef< const Expr * > Inits, const Expr *ArrayFiller, const Expr *E)
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E)
bool VisitPredefinedExpr(const PredefinedExpr *E)
bool VisitSourceLocExpr(const SourceLocExpr *E)
bool visitDeclStmt(const DeclStmt *DS, bool EvaluateConditionDecl=false)
bool emitCleanup()
Emits scope cleanup instructions.
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E)
bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E)
bool visitInitializer(const Expr *E)
Compiles an initializer.
bool visitDtorCall(const VarDecl *VD, const APValue &Value) override
const Expr * SourceLocDefaultExpr
DefaultInit- or DefaultArgExpr, needed for SourceLocExpr.
Definition Compiler.h:475
bool VisitObjCArrayLiteral(const ObjCArrayLiteral *E)
UnsignedOrNone OptLabelTy
Definition Compiler.h:117
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E)
bool VisitPointerArithBinOp(const BinaryOperator *E)
Perform addition/subtraction of a pointer and an integer or subtraction of two pointers.
bool visitCallArgs(ArrayRef< const Expr * > Args, const FunctionDecl *FuncDecl, bool Activate, bool IsOperatorCall)
bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E)
bool visitDefaultStmt(const DefaultStmt *S)
bool VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
typename Emitter::LabelTy LabelTy
Definition Compiler.h:115
VarCreationState visitDecl(const VarDecl *VD)
bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E)
bool visitStmt(const Stmt *S)
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
bool VisitVectorUnaryOperator(const UnaryOperator *E)
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
bool VisitDesignatedInitUpdateExpr(const DesignatedInitUpdateExpr *E)
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
bool VisitRecoveryExpr(const RecoveryExpr *E)
bool VisitRequiresExpr(const RequiresExpr *E)
bool Initializing
Flag inidicating if we're initializing an already created variable.
Definition Compiler.h:487
bool visitReturnStmt(const ReturnStmt *RS)
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitChooseExpr(const ChooseExpr *E)
bool visitFunc(const FunctionDecl *F) override
bool visitCXXForRangeStmt(const CXXForRangeStmt *S)
bool visitCaseStmt(const CaseStmt *S)
bool VisitComplexBinOp(const BinaryOperator *E)
llvm::DenseMap< const ValueDecl *, Scope::Local > Locals
Variable to storage mapping.
Definition Compiler.h:463
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
bool VisitCXXTypeidExpr(const CXXTypeidExpr *E)
UnsignedOrNone allocateTemporary(const Expr *E)
bool VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinID)
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
OptPrimType ReturnType
Type of the expression returned by the function.
Definition Compiler.h:494
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
OptPrimType classify(const Expr *E) const
Definition Compiler.h:279
llvm::SmallVector< LabelInfo > LabelInfoStack
Stack of label information for loops and switch statements.
Definition Compiler.h:499
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
bool visitDoStmt(const DoStmt *S)
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitInitListExpr(const InitListExpr *E)
bool VisitVectorBinOp(const BinaryOperator *E)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
bool DiscardResult
Flag indicating if return value is to be discarded.
Definition Compiler.h:478
bool VisitEmbedExpr(const EmbedExpr *E)
bool VisitConvertVectorExpr(const ConvertVectorExpr *E)
bool VisitCXXThisExpr(const CXXThisExpr *E)
bool VisitConstantExpr(const ConstantExpr *E)
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool visitSwitchStmt(const SwitchStmt *S)
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E)
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool visitAsLValue(const Expr *E)
bool visitWhileStmt(const WhileStmt *S)
bool visitIfStmt(const IfStmt *IS)
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
bool canClassify(const Expr *E) const
Definition Compiler.h:281
bool VisitFloatingLiteral(const FloatingLiteral *E)
Program & P
Program to link to.
Definition Compiler.h:137
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
bool VisitGNUNullExpr(const GNUNullExpr *E)
bool VisitImaginaryLiteral(const ImaginaryLiteral *E)
bool VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E)
bool visitCXXTryStmt(const CXXTryStmt *S)
static bool isUnevaluatedBuiltin(unsigned ID)
Unevaluated builtins don't get their arguments put on the stack automatically.
Definition Context.cpp:739
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Definition Context.h:154
Scope used to handle temporaries in toplevel variable declarations.
Definition Compiler.cpp:40
DeclScope(Compiler< Emitter > *Ctx, const ValueDecl *VD)
Definition Compiler.cpp:42
Wrapper around fixed point types.
Definition FixedPoint.h:23
static FixedPoint zero(llvm::FixedPointSemantics Sem)
Definition FixedPoint.h:36
If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY.
Definition Floating.h:35
bool singleWord() const
Definition Floating.h:107
Bytecode function.
Definition Function.h:99
bool hasThisPointer() const
Definition Function.h:226
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Definition Function.h:156
When generating code for e.g.
Definition Compiler.cpp:188
LocOverrideScope(Compiler< Emitter > *Ctx, SourceInfo NewValue, bool Enabled=true)
Definition Compiler.cpp:190
Generic scope for local variables.
Definition Compiler.h:566
bool destroyLocals(const Expr *E=nullptr) override
Explicit destruction of local variables.
Definition Compiler.h:579
LocalScope(Compiler< Emitter > *Ctx, ScopeKind Kind=ScopeKind::Block)
Definition Compiler.h:568
Sets the context for break/continue statements.
Definition Compiler.cpp:114
typename Compiler< Emitter >::LabelTy LabelTy
Definition Compiler.cpp:116
typename Compiler< Emitter >::OptLabelTy OptLabelTy
Definition Compiler.cpp:117
typename Compiler< Emitter >::LabelInfo LabelInfo
Definition Compiler.cpp:118
LoopScope(Compiler< Emitter > *Ctx, const Stmt *Name, LabelTy BreakLabel, LabelTy ContinueLabel)
Definition Compiler.cpp:120
PrimType value_or(PrimType PT) const
Definition PrimType.h:88
Scope used to handle initialization methods.
Definition Compiler.cpp:60
OptionScope(Compiler< Emitter > *Ctx, bool NewDiscardResult, bool NewInitializing, bool NewToLValue)
Root constructor, compiling or discarding primitives.
Definition Compiler.cpp:63
Context to manage declaration lifetimes.
Definition Program.h:148
Structure/Class descriptor.
Definition Record.h:25
bool isUnion() const
Checks if the record is a union.
Definition Record.h:69
const Field * getField(unsigned I) const
Definition Record.h:95
const Base * getBase(unsigned I) const
Definition Record.h:107
bool hasTrivialDtor() const
Returns true for anonymous unions and records with no destructor or for those with a trivial destruct...
Definition Record.cpp:45
Describes a scope block.
Definition Function.h:36
Describes the statement/declaration an opcode was generated from.
Definition Source.h:74
StmtExprScope(Compiler< Emitter > *Ctx)
Definition Compiler.cpp:173
typename Compiler< Emitter >::LabelTy LabelTy
Definition Compiler.cpp:142
typename Compiler< Emitter >::OptLabelTy OptLabelTy
Definition Compiler.cpp:143
typename Compiler< Emitter >::LabelInfo LabelInfo
Definition Compiler.cpp:145
typename Compiler< Emitter >::CaseMap CaseMap
Definition Compiler.cpp:144
SwitchScope(Compiler< Emitter > *Ctx, const Stmt *Name, CaseMap &&CaseLabels, LabelTy BreakLabel, OptLabelTy DefaultLabel)
Definition Compiler.cpp:147
Scope chain managing the variable lifetimes.
Definition Compiler.h:508
Compiler< Emitter > * Ctx
Compiler instance.
Definition Compiler.h:559
virtual void addLocal(Scope::Local Local)
Definition Compiler.h:519
VariableScope * getParent() const
Definition Compiler.h:549
bool Sub(InterpState &S, CodePtr OpPC)
Definition Interp.h:411
bool LT(InterpState &S, CodePtr OpPC)
Definition Interp.h:1476
static llvm::RoundingMode getRoundingMode(FPOptions FPO)
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
Definition Descriptor.h:29
constexpr bool isSignedType(PrimType T)
Definition PrimType.h:59
bool Div(InterpState &S, CodePtr OpPC)
1) Pops the RHS from the stack.
Definition Interp.h:756
static bool Activate(InterpState &S, CodePtr OpPC)
Definition Interp.h:2206
constexpr bool isPtrType(PrimType T)
Definition PrimType.h:55
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition PrimType.h:201
bool InitScope(InterpState &S, CodePtr OpPC, uint32_t I)
Definition Interp.h:2713
constexpr bool isIntegerOrBoolType(PrimType T)
Definition PrimType.h:52
llvm::APFloat APFloat
Definition Floating.h:27
static void discard(InterpStack &Stk, PrimType T)
llvm::APInt APInt
Definition FixedPoint.h:19
bool LE(InterpState &S, CodePtr OpPC)
Definition Interp.h:1483
PrimType
Enumeration of the primitive types of the VM.
Definition PrimType.h:34
static std::optional< bool > getBoolValue(const Expr *E)
Definition Compiler.cpp:29
bool Init(InterpState &S, CodePtr OpPC)
Definition Interp.h:2323
bool Mul(InterpState &S, CodePtr OpPC)
Definition Interp.h:465
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
Definition PrimType.cpp:24
bool Inc(InterpState &S, CodePtr OpPC, bool CanOverflow)
1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...
Definition Interp.h:950
bool Add(InterpState &S, CodePtr OpPC)
Definition Interp.h:382
llvm::BitVector collectNonNullArgs(const FunctionDecl *F, ArrayRef< const Expr * > Args)
llvm::APSInt APSInt
Definition FixedPoint.h:20
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
bool hasSpecificAttr(const Container &container)
@ Success
Annotation was successful.
Definition Parser.h:65
Expr * Cond
};
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
Definition TypeTraits.h:51
@ SD_Static
Static storage duration.
Definition Specifiers.h:344
@ SD_FullExpression
Full-expression storage duration (for temporaries).
Definition Specifiers.h:341
@ Result
The result type of a method or function.
Definition TypeBase.h:905
OptionalUnsigned< unsigned > UnsignedOrNone
U cast(CodeGen::Address addr)
Definition Address.h:327
int const char * function
Definition c++config.h:31
#define true
Definition stdbool.h:25
A quantity in bits.
Describes a memory block created by an allocation site.
Definition Descriptor.h:123
unsigned getNumElems() const
Returns the number of elements stored in the block.
Definition Descriptor.h:260
bool isPrimitive() const
Checks if the descriptor is of a primitive.
Definition Descriptor.h:274
QualType getElemQualType() const
bool hasTrivialDtor() const
Whether variables of this descriptor need their destructor called or not.
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
Definition Descriptor.h:267
QualType getType() const
const Descriptor *const ElemDesc
Descriptor of the array element.
Definition Descriptor.h:156
static constexpr MetadataSize InlineDescMD
Definition Descriptor.h:145
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
Definition Descriptor.h:265
PrimType getPrimType() const
Definition Descriptor.h:242
bool isRecord() const
Checks if the descriptor is of a record.
Definition Descriptor.h:279
const Record *const ElemRecord
Pointer to the record, if block contains records.
Definition Descriptor.h:154
bool isArray() const
Checks if the descriptor is of an array.
Definition Descriptor.h:277
Descriptor used for global variables.
Definition Descriptor.h:50
Information about a local's storage.
Definition Function.h:39
State encapsulating if a the variable creation has been successful, unsuccessful, or no variable has ...
Definition Compiler.h:97
static VarCreationState NotCreated()
Definition Compiler.h:101