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