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