Thanks to visit codestin.com
Credit goes to clang.llvm.org

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