Path: blob/main/contrib/llvm-project/clang/lib/AST/Interp/Compiler.cpp
35291 views
//===--- Compiler.cpp - Code generator for expressions ---*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "Compiler.h"9#include "ByteCodeEmitter.h"10#include "Context.h"11#include "Floating.h"12#include "Function.h"13#include "InterpShared.h"14#include "PrimType.h"15#include "Program.h"16#include "clang/AST/Attr.h"1718using namespace clang;19using namespace clang::interp;2021using APSInt = llvm::APSInt;2223namespace clang {24namespace interp {2526/// Scope used to handle temporaries in toplevel variable declarations.27template <class Emitter> class DeclScope final : public LocalScope<Emitter> {28public:29DeclScope(Compiler<Emitter> *Ctx, const ValueDecl *VD)30: LocalScope<Emitter>(Ctx, VD), Scope(Ctx->P, VD),31OldGlobalDecl(Ctx->GlobalDecl),32OldInitializingDecl(Ctx->InitializingDecl) {33Ctx->GlobalDecl = Context::shouldBeGloballyIndexed(VD);34Ctx->InitializingDecl = VD;35Ctx->InitStack.push_back(InitLink::Decl(VD));36}3738void addExtended(const Scope::Local &Local) override {39return this->addLocal(Local);40}4142~DeclScope() {43this->Ctx->GlobalDecl = OldGlobalDecl;44this->Ctx->InitializingDecl = OldInitializingDecl;45this->Ctx->InitStack.pop_back();46}4748private:49Program::DeclScope Scope;50bool OldGlobalDecl;51const ValueDecl *OldInitializingDecl;52};5354/// Scope used to handle initialization methods.55template <class Emitter> class OptionScope final {56public:57/// Root constructor, compiling or discarding primitives.58OptionScope(Compiler<Emitter> *Ctx, bool NewDiscardResult,59bool NewInitializing)60: Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),61OldInitializing(Ctx->Initializing) {62Ctx->DiscardResult = NewDiscardResult;63Ctx->Initializing = NewInitializing;64}6566~OptionScope() {67Ctx->DiscardResult = OldDiscardResult;68Ctx->Initializing = OldInitializing;69}7071private:72/// Parent context.73Compiler<Emitter> *Ctx;74/// Old discard flag to restore.75bool OldDiscardResult;76bool OldInitializing;77};7879template <class Emitter>80bool InitLink::emit(Compiler<Emitter> *Ctx, const Expr *E) const {81switch (Kind) {82case K_This:83return Ctx->emitThis(E);84case K_Field:85// We're assuming there's a base pointer on the stack already.86return Ctx->emitGetPtrFieldPop(Offset, E);87case K_Temp:88return Ctx->emitGetPtrLocal(Offset, E);89case K_Decl:90return Ctx->visitDeclRef(D, E);91default:92llvm_unreachable("Unhandled InitLink kind");93}94return true;95}9697/// Scope managing label targets.98template <class Emitter> class LabelScope {99public:100virtual ~LabelScope() {}101102protected:103LabelScope(Compiler<Emitter> *Ctx) : Ctx(Ctx) {}104/// Compiler instance.105Compiler<Emitter> *Ctx;106};107108/// Sets the context for break/continue statements.109template <class Emitter> class LoopScope final : public LabelScope<Emitter> {110public:111using LabelTy = typename Compiler<Emitter>::LabelTy;112using OptLabelTy = typename Compiler<Emitter>::OptLabelTy;113114LoopScope(Compiler<Emitter> *Ctx, LabelTy BreakLabel, LabelTy ContinueLabel)115: LabelScope<Emitter>(Ctx), OldBreakLabel(Ctx->BreakLabel),116OldContinueLabel(Ctx->ContinueLabel) {117this->Ctx->BreakLabel = BreakLabel;118this->Ctx->ContinueLabel = ContinueLabel;119}120121~LoopScope() {122this->Ctx->BreakLabel = OldBreakLabel;123this->Ctx->ContinueLabel = OldContinueLabel;124}125126private:127OptLabelTy OldBreakLabel;128OptLabelTy OldContinueLabel;129};130131// Sets the context for a switch scope, mapping labels.132template <class Emitter> class SwitchScope final : public LabelScope<Emitter> {133public:134using LabelTy = typename Compiler<Emitter>::LabelTy;135using OptLabelTy = typename Compiler<Emitter>::OptLabelTy;136using CaseMap = typename Compiler<Emitter>::CaseMap;137138SwitchScope(Compiler<Emitter> *Ctx, CaseMap &&CaseLabels, LabelTy BreakLabel,139OptLabelTy DefaultLabel)140: LabelScope<Emitter>(Ctx), OldBreakLabel(Ctx->BreakLabel),141OldDefaultLabel(this->Ctx->DefaultLabel),142OldCaseLabels(std::move(this->Ctx->CaseLabels)) {143this->Ctx->BreakLabel = BreakLabel;144this->Ctx->DefaultLabel = DefaultLabel;145this->Ctx->CaseLabels = std::move(CaseLabels);146}147148~SwitchScope() {149this->Ctx->BreakLabel = OldBreakLabel;150this->Ctx->DefaultLabel = OldDefaultLabel;151this->Ctx->CaseLabels = std::move(OldCaseLabels);152}153154private:155OptLabelTy OldBreakLabel;156OptLabelTy OldDefaultLabel;157CaseMap OldCaseLabels;158};159160template <class Emitter> class StmtExprScope final {161public:162StmtExprScope(Compiler<Emitter> *Ctx) : Ctx(Ctx), OldFlag(Ctx->InStmtExpr) {163Ctx->InStmtExpr = true;164}165166~StmtExprScope() { Ctx->InStmtExpr = OldFlag; }167168private:169Compiler<Emitter> *Ctx;170bool OldFlag;171};172173} // namespace interp174} // namespace clang175176template <class Emitter>177bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {178const Expr *SubExpr = CE->getSubExpr();179switch (CE->getCastKind()) {180181case CK_LValueToRValue: {182if (DiscardResult)183return this->discard(SubExpr);184185std::optional<PrimType> SubExprT = classify(SubExpr->getType());186// Prepare storage for the result.187if (!Initializing && !SubExprT) {188std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);189if (!LocalIndex)190return false;191if (!this->emitGetPtrLocal(*LocalIndex, CE))192return false;193}194195if (!this->visit(SubExpr))196return false;197198if (SubExprT)199return this->emitLoadPop(*SubExprT, CE);200201// If the subexpr type is not primitive, we need to perform a copy here.202// This happens for example in C when dereferencing a pointer of struct203// type.204return this->emitMemcpy(CE);205}206207case CK_DerivedToBaseMemberPointer: {208assert(classifyPrim(CE->getType()) == PT_MemberPtr);209assert(classifyPrim(SubExpr->getType()) == PT_MemberPtr);210const auto *FromMP = SubExpr->getType()->getAs<MemberPointerType>();211const auto *ToMP = CE->getType()->getAs<MemberPointerType>();212213unsigned DerivedOffset = collectBaseOffset(QualType(ToMP->getClass(), 0),214QualType(FromMP->getClass(), 0));215216if (!this->visit(SubExpr))217return false;218219return this->emitGetMemberPtrBasePop(DerivedOffset, CE);220}221222case CK_BaseToDerivedMemberPointer: {223assert(classifyPrim(CE) == PT_MemberPtr);224assert(classifyPrim(SubExpr) == PT_MemberPtr);225const auto *FromMP = SubExpr->getType()->getAs<MemberPointerType>();226const auto *ToMP = CE->getType()->getAs<MemberPointerType>();227228unsigned DerivedOffset = collectBaseOffset(QualType(FromMP->getClass(), 0),229QualType(ToMP->getClass(), 0));230231if (!this->visit(SubExpr))232return false;233return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);234}235236case CK_UncheckedDerivedToBase:237case CK_DerivedToBase: {238if (!this->visit(SubExpr))239return false;240241const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {242if (const auto *PT = dyn_cast<PointerType>(Ty))243return PT->getPointeeType()->getAsCXXRecordDecl();244return Ty->getAsCXXRecordDecl();245};246247// FIXME: We can express a series of non-virtual casts as a single248// GetPtrBasePop op.249QualType CurType = SubExpr->getType();250for (const CXXBaseSpecifier *B : CE->path()) {251if (B->isVirtual()) {252if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))253return false;254CurType = B->getType();255} else {256unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);257if (!this->emitGetPtrBasePop(DerivedOffset, CE))258return false;259CurType = B->getType();260}261}262263return true;264}265266case CK_BaseToDerived: {267if (!this->visit(SubExpr))268return false;269270unsigned DerivedOffset =271collectBaseOffset(SubExpr->getType(), CE->getType());272273return this->emitGetPtrDerivedPop(DerivedOffset, CE);274}275276case CK_FloatingCast: {277// HLSL uses CK_FloatingCast to cast between vectors.278if (!SubExpr->getType()->isFloatingType() ||279!CE->getType()->isFloatingType())280return false;281if (DiscardResult)282return this->discard(SubExpr);283if (!this->visit(SubExpr))284return false;285const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());286return this->emitCastFP(TargetSemantics, getRoundingMode(CE), CE);287}288289case CK_IntegralToFloating: {290if (DiscardResult)291return this->discard(SubExpr);292std::optional<PrimType> FromT = classify(SubExpr->getType());293if (!FromT)294return false;295296if (!this->visit(SubExpr))297return false;298299const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());300llvm::RoundingMode RM = getRoundingMode(CE);301return this->emitCastIntegralFloating(*FromT, TargetSemantics, RM, CE);302}303304case CK_FloatingToBoolean:305case CK_FloatingToIntegral: {306if (DiscardResult)307return this->discard(SubExpr);308309std::optional<PrimType> ToT = classify(CE->getType());310311if (!ToT)312return false;313314if (!this->visit(SubExpr))315return false;316317if (ToT == PT_IntAP)318return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->getType()),319CE);320if (ToT == PT_IntAPS)321return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->getType()),322CE);323324return this->emitCastFloatingIntegral(*ToT, CE);325}326327case CK_NullToPointer:328case CK_NullToMemberPointer: {329if (DiscardResult)330return true;331332const Descriptor *Desc = nullptr;333const QualType PointeeType = CE->getType()->getPointeeType();334if (!PointeeType.isNull()) {335if (std::optional<PrimType> T = classify(PointeeType))336Desc = P.createDescriptor(SubExpr, *T);337}338return this->emitNull(classifyPrim(CE->getType()), Desc, CE);339}340341case CK_PointerToIntegral: {342if (DiscardResult)343return this->discard(SubExpr);344345if (!this->visit(SubExpr))346return false;347348// If SubExpr doesn't result in a pointer, make it one.349if (PrimType FromT = classifyPrim(SubExpr->getType()); FromT != PT_Ptr) {350assert(isPtrType(FromT));351if (!this->emitDecayPtr(FromT, PT_Ptr, CE))352return false;353}354355PrimType T = classifyPrim(CE->getType());356if (T == PT_IntAP)357return this->emitCastPointerIntegralAP(Ctx.getBitWidth(CE->getType()),358CE);359if (T == PT_IntAPS)360return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(CE->getType()),361CE);362return this->emitCastPointerIntegral(T, CE);363}364365case CK_ArrayToPointerDecay: {366if (!this->visit(SubExpr))367return false;368if (!this->emitArrayDecay(CE))369return false;370if (DiscardResult)371return this->emitPopPtr(CE);372return true;373}374375case CK_IntegralToPointer: {376QualType IntType = SubExpr->getType();377assert(IntType->isIntegralOrEnumerationType());378if (!this->visit(SubExpr))379return false;380// FIXME: I think the discard is wrong since the int->ptr cast might cause a381// diagnostic.382PrimType T = classifyPrim(IntType);383if (DiscardResult)384return this->emitPop(T, CE);385386QualType PtrType = CE->getType();387assert(PtrType->isPointerType());388389const Descriptor *Desc;390if (std::optional<PrimType> T = classify(PtrType->getPointeeType()))391Desc = P.createDescriptor(SubExpr, *T);392else if (PtrType->getPointeeType()->isVoidType())393Desc = nullptr;394else395Desc = P.createDescriptor(CE, PtrType->getPointeeType().getTypePtr(),396Descriptor::InlineDescMD, true, false,397/*IsMutable=*/false, nullptr);398399if (!this->emitGetIntPtr(T, Desc, CE))400return false;401402PrimType DestPtrT = classifyPrim(PtrType);403if (DestPtrT == PT_Ptr)404return true;405406// In case we're converting the integer to a non-Pointer.407return this->emitDecayPtr(PT_Ptr, DestPtrT, CE);408}409410case CK_AtomicToNonAtomic:411case CK_ConstructorConversion:412case CK_FunctionToPointerDecay:413case CK_NonAtomicToAtomic:414case CK_NoOp:415case CK_UserDefinedConversion:416case CK_AddressSpaceConversion:417return this->delegate(SubExpr);418419case CK_BitCast: {420// Reject bitcasts to atomic types.421if (CE->getType()->isAtomicType()) {422if (!this->discard(SubExpr))423return false;424return this->emitInvalidCast(CastKind::Reinterpret, CE);425}426427if (DiscardResult)428return this->discard(SubExpr);429430QualType SubExprTy = SubExpr->getType();431std::optional<PrimType> FromT = classify(SubExprTy);432std::optional<PrimType> ToT = classify(CE->getType());433if (!FromT || !ToT)434return false;435436assert(isPtrType(*FromT));437assert(isPtrType(*ToT));438if (FromT == ToT) {439if (CE->getType()->isVoidPointerType())440return this->delegate(SubExpr);441442if (!this->visit(SubExpr))443return false;444if (FromT == PT_Ptr)445return this->emitPtrPtrCast(SubExprTy->isVoidPointerType(), CE);446return true;447}448449if (!this->visit(SubExpr))450return false;451return this->emitDecayPtr(*FromT, *ToT, CE);452}453454case CK_IntegralToBoolean:455case CK_BooleanToSignedIntegral:456case CK_IntegralCast: {457if (DiscardResult)458return this->discard(SubExpr);459std::optional<PrimType> FromT = classify(SubExpr->getType());460std::optional<PrimType> ToT = classify(CE->getType());461462if (!FromT || !ToT)463return false;464465if (!this->visit(SubExpr))466return false;467468// Possibly diagnose casts to enum types if the target type does not469// have a fixed size.470if (Ctx.getLangOpts().CPlusPlus && CE->getType()->isEnumeralType()) {471if (const auto *ET = CE->getType().getCanonicalType()->getAs<EnumType>();472ET && !ET->getDecl()->isFixed()) {473if (!this->emitCheckEnumValue(*FromT, ET->getDecl(), CE))474return false;475}476}477478if (ToT == PT_IntAP)479return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->getType()), CE);480if (ToT == PT_IntAPS)481return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->getType()), CE);482483if (FromT == ToT)484return true;485if (!this->emitCast(*FromT, *ToT, CE))486return false;487488if (CE->getCastKind() == CK_BooleanToSignedIntegral)489return this->emitNeg(*ToT, CE);490return true;491}492493case CK_PointerToBoolean:494case CK_MemberPointerToBoolean: {495PrimType PtrT = classifyPrim(SubExpr->getType());496497// Just emit p != nullptr for this.498if (!this->visit(SubExpr))499return false;500501if (!this->emitNull(PtrT, nullptr, CE))502return false;503504return this->emitNE(PtrT, CE);505}506507case CK_IntegralComplexToBoolean:508case CK_FloatingComplexToBoolean: {509if (DiscardResult)510return this->discard(SubExpr);511if (!this->visit(SubExpr))512return false;513return this->emitComplexBoolCast(SubExpr);514}515516case CK_IntegralComplexToReal:517case CK_FloatingComplexToReal:518return this->emitComplexReal(SubExpr);519520case CK_IntegralRealToComplex:521case CK_FloatingRealToComplex: {522// We're creating a complex value here, so we need to523// allocate storage for it.524if (!Initializing) {525std::optional<unsigned> LocalIndex = allocateLocal(CE);526if (!LocalIndex)527return false;528if (!this->emitGetPtrLocal(*LocalIndex, CE))529return false;530}531532// Init the complex value to {SubExpr, 0}.533if (!this->visitArrayElemInit(0, SubExpr))534return false;535// Zero-init the second element.536PrimType T = classifyPrim(SubExpr->getType());537if (!this->visitZeroInitializer(T, SubExpr->getType(), SubExpr))538return false;539return this->emitInitElem(T, 1, SubExpr);540}541542case CK_IntegralComplexCast:543case CK_FloatingComplexCast:544case CK_IntegralComplexToFloatingComplex:545case CK_FloatingComplexToIntegralComplex: {546assert(CE->getType()->isAnyComplexType());547assert(SubExpr->getType()->isAnyComplexType());548if (DiscardResult)549return this->discard(SubExpr);550551if (!Initializing) {552std::optional<unsigned> LocalIndex = allocateLocal(CE);553if (!LocalIndex)554return false;555if (!this->emitGetPtrLocal(*LocalIndex, CE))556return false;557}558559// Location for the SubExpr.560// Since SubExpr is of complex type, visiting it results in a pointer561// anyway, so we just create a temporary pointer variable.562unsigned SubExprOffset = allocateLocalPrimitive(563SubExpr, PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false);564if (!this->visit(SubExpr))565return false;566if (!this->emitSetLocal(PT_Ptr, SubExprOffset, CE))567return false;568569PrimType SourceElemT = classifyComplexElementType(SubExpr->getType());570QualType DestElemType =571CE->getType()->getAs<ComplexType>()->getElementType();572PrimType DestElemT = classifyPrim(DestElemType);573// Cast both elements individually.574for (unsigned I = 0; I != 2; ++I) {575if (!this->emitGetLocal(PT_Ptr, SubExprOffset, CE))576return false;577if (!this->emitArrayElemPop(SourceElemT, I, CE))578return false;579580// Do the cast.581if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))582return false;583584// Save the value.585if (!this->emitInitElem(DestElemT, I, CE))586return false;587}588return true;589}590591case CK_VectorSplat: {592assert(!classify(CE->getType()));593assert(classify(SubExpr->getType()));594assert(CE->getType()->isVectorType());595596if (DiscardResult)597return this->discard(SubExpr);598599if (!Initializing) {600std::optional<unsigned> LocalIndex = allocateLocal(CE);601if (!LocalIndex)602return false;603if (!this->emitGetPtrLocal(*LocalIndex, CE))604return false;605}606607const auto *VT = CE->getType()->getAs<VectorType>();608PrimType ElemT = classifyPrim(SubExpr->getType());609unsigned ElemOffset = allocateLocalPrimitive(610SubExpr, ElemT, /*IsConst=*/true, /*IsExtended=*/false);611612// Prepare a local variable for the scalar value.613if (!this->visit(SubExpr))614return false;615if (classifyPrim(SubExpr) == PT_Ptr && !this->emitLoadPop(ElemT, CE))616return false;617618if (!this->emitSetLocal(ElemT, ElemOffset, CE))619return false;620621for (unsigned I = 0; I != VT->getNumElements(); ++I) {622if (!this->emitGetLocal(ElemT, ElemOffset, CE))623return false;624if (!this->emitInitElem(ElemT, I, CE))625return false;626}627628return true;629}630631case CK_ToVoid:632return discard(SubExpr);633634default:635return this->emitInvalid(CE);636}637llvm_unreachable("Unhandled clang::CastKind enum");638}639640template <class Emitter>641bool Compiler<Emitter>::VisitIntegerLiteral(const IntegerLiteral *LE) {642if (DiscardResult)643return true;644645return this->emitConst(LE->getValue(), LE);646}647648template <class Emitter>649bool Compiler<Emitter>::VisitFloatingLiteral(const FloatingLiteral *E) {650if (DiscardResult)651return true;652653return this->emitConstFloat(E->getValue(), E);654}655656template <class Emitter>657bool Compiler<Emitter>::VisitImaginaryLiteral(const ImaginaryLiteral *E) {658assert(E->getType()->isAnyComplexType());659if (DiscardResult)660return true;661662if (!Initializing) {663std::optional<unsigned> LocalIndex = allocateLocal(E);664if (!LocalIndex)665return false;666if (!this->emitGetPtrLocal(*LocalIndex, E))667return false;668}669670const Expr *SubExpr = E->getSubExpr();671PrimType SubExprT = classifyPrim(SubExpr->getType());672673if (!this->visitZeroInitializer(SubExprT, SubExpr->getType(), SubExpr))674return false;675if (!this->emitInitElem(SubExprT, 0, SubExpr))676return false;677return this->visitArrayElemInit(1, SubExpr);678}679680template <class Emitter>681bool Compiler<Emitter>::VisitParenExpr(const ParenExpr *E) {682return this->delegate(E->getSubExpr());683}684685template <class Emitter>686bool Compiler<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {687// Need short-circuiting for these.688if (BO->isLogicalOp())689return this->VisitLogicalBinOp(BO);690691const Expr *LHS = BO->getLHS();692const Expr *RHS = BO->getRHS();693694// Handle comma operators. Just discard the LHS695// and delegate to RHS.696if (BO->isCommaOp()) {697if (!this->discard(LHS))698return false;699if (RHS->getType()->isVoidType())700return this->discard(RHS);701702return this->delegate(RHS);703}704705if (BO->getType()->isAnyComplexType())706return this->VisitComplexBinOp(BO);707if ((LHS->getType()->isAnyComplexType() ||708RHS->getType()->isAnyComplexType()) &&709BO->isComparisonOp())710return this->emitComplexComparison(LHS, RHS, BO);711712if (BO->isPtrMemOp()) {713if (!this->visit(LHS))714return false;715716if (!this->visit(RHS))717return false;718719if (!this->emitToMemberPtr(BO))720return false;721722if (classifyPrim(BO) == PT_MemberPtr)723return true;724725if (!this->emitCastMemberPtrPtr(BO))726return false;727return DiscardResult ? this->emitPopPtr(BO) : true;728}729730// Typecheck the args.731std::optional<PrimType> LT = classify(LHS->getType());732std::optional<PrimType> RT = classify(RHS->getType());733std::optional<PrimType> T = classify(BO->getType());734735// Special case for C++'s three-way/spaceship operator <=>, which736// returns a std::{strong,weak,partial}_ordering (which is a class, so doesn't737// have a PrimType).738if (!T && BO->getOpcode() == BO_Cmp) {739if (DiscardResult)740return true;741const ComparisonCategoryInfo *CmpInfo =742Ctx.getASTContext().CompCategories.lookupInfoForType(BO->getType());743assert(CmpInfo);744745// We need a temporary variable holding our return value.746if (!Initializing) {747std::optional<unsigned> ResultIndex = this->allocateLocal(BO);748if (!this->emitGetPtrLocal(*ResultIndex, BO))749return false;750}751752if (!visit(LHS) || !visit(RHS))753return false;754755return this->emitCMP3(*LT, CmpInfo, BO);756}757758if (!LT || !RT || !T)759return false;760761// Pointer arithmetic special case.762if (BO->getOpcode() == BO_Add || BO->getOpcode() == BO_Sub) {763if (isPtrType(*T) || (isPtrType(*LT) && isPtrType(*RT)))764return this->VisitPointerArithBinOp(BO);765}766767if (!visit(LHS) || !visit(RHS))768return false;769770// For languages such as C, cast the result of one771// of our comparision opcodes to T (which is usually int).772auto MaybeCastToBool = [this, T, BO](bool Result) {773if (!Result)774return false;775if (DiscardResult)776return this->emitPop(*T, BO);777if (T != PT_Bool)778return this->emitCast(PT_Bool, *T, BO);779return true;780};781782auto Discard = [this, T, BO](bool Result) {783if (!Result)784return false;785return DiscardResult ? this->emitPop(*T, BO) : true;786};787788switch (BO->getOpcode()) {789case BO_EQ:790return MaybeCastToBool(this->emitEQ(*LT, BO));791case BO_NE:792return MaybeCastToBool(this->emitNE(*LT, BO));793case BO_LT:794return MaybeCastToBool(this->emitLT(*LT, BO));795case BO_LE:796return MaybeCastToBool(this->emitLE(*LT, BO));797case BO_GT:798return MaybeCastToBool(this->emitGT(*LT, BO));799case BO_GE:800return MaybeCastToBool(this->emitGE(*LT, BO));801case BO_Sub:802if (BO->getType()->isFloatingType())803return Discard(this->emitSubf(getRoundingMode(BO), BO));804return Discard(this->emitSub(*T, BO));805case BO_Add:806if (BO->getType()->isFloatingType())807return Discard(this->emitAddf(getRoundingMode(BO), BO));808return Discard(this->emitAdd(*T, BO));809case BO_Mul:810if (BO->getType()->isFloatingType())811return Discard(this->emitMulf(getRoundingMode(BO), BO));812return Discard(this->emitMul(*T, BO));813case BO_Rem:814return Discard(this->emitRem(*T, BO));815case BO_Div:816if (BO->getType()->isFloatingType())817return Discard(this->emitDivf(getRoundingMode(BO), BO));818return Discard(this->emitDiv(*T, BO));819case BO_Assign:820if (DiscardResult)821return LHS->refersToBitField() ? this->emitStoreBitFieldPop(*T, BO)822: this->emitStorePop(*T, BO);823if (LHS->refersToBitField()) {824if (!this->emitStoreBitField(*T, BO))825return false;826} else {827if (!this->emitStore(*T, BO))828return false;829}830// Assignments aren't necessarily lvalues in C.831// Load from them in that case.832if (!BO->isLValue())833return this->emitLoadPop(*T, BO);834return true;835case BO_And:836return Discard(this->emitBitAnd(*T, BO));837case BO_Or:838return Discard(this->emitBitOr(*T, BO));839case BO_Shl:840return Discard(this->emitShl(*LT, *RT, BO));841case BO_Shr:842return Discard(this->emitShr(*LT, *RT, BO));843case BO_Xor:844return Discard(this->emitBitXor(*T, BO));845case BO_LOr:846case BO_LAnd:847llvm_unreachable("Already handled earlier");848default:849return false;850}851852llvm_unreachable("Unhandled binary op");853}854855/// Perform addition/subtraction of a pointer and an integer or856/// subtraction of two pointers.857template <class Emitter>858bool Compiler<Emitter>::VisitPointerArithBinOp(const BinaryOperator *E) {859BinaryOperatorKind Op = E->getOpcode();860const Expr *LHS = E->getLHS();861const Expr *RHS = E->getRHS();862863if ((Op != BO_Add && Op != BO_Sub) ||864(!LHS->getType()->isPointerType() && !RHS->getType()->isPointerType()))865return false;866867std::optional<PrimType> LT = classify(LHS);868std::optional<PrimType> RT = classify(RHS);869870if (!LT || !RT)871return false;872873if (LHS->getType()->isPointerType() && RHS->getType()->isPointerType()) {874if (Op != BO_Sub)875return false;876877assert(E->getType()->isIntegerType());878if (!visit(RHS) || !visit(LHS))879return false;880881return this->emitSubPtr(classifyPrim(E->getType()), E);882}883884PrimType OffsetType;885if (LHS->getType()->isIntegerType()) {886if (!visit(RHS) || !visit(LHS))887return false;888OffsetType = *LT;889} else if (RHS->getType()->isIntegerType()) {890if (!visit(LHS) || !visit(RHS))891return false;892OffsetType = *RT;893} else {894return false;895}896897if (Op == BO_Add)898return this->emitAddOffset(OffsetType, E);899else if (Op == BO_Sub)900return this->emitSubOffset(OffsetType, E);901902return false;903}904905template <class Emitter>906bool Compiler<Emitter>::VisitLogicalBinOp(const BinaryOperator *E) {907assert(E->isLogicalOp());908BinaryOperatorKind Op = E->getOpcode();909const Expr *LHS = E->getLHS();910const Expr *RHS = E->getRHS();911std::optional<PrimType> T = classify(E->getType());912913if (Op == BO_LOr) {914// Logical OR. Visit LHS and only evaluate RHS if LHS was FALSE.915LabelTy LabelTrue = this->getLabel();916LabelTy LabelEnd = this->getLabel();917918if (!this->visitBool(LHS))919return false;920if (!this->jumpTrue(LabelTrue))921return false;922923if (!this->visitBool(RHS))924return false;925if (!this->jump(LabelEnd))926return false;927928this->emitLabel(LabelTrue);929this->emitConstBool(true, E);930this->fallthrough(LabelEnd);931this->emitLabel(LabelEnd);932933} else {934assert(Op == BO_LAnd);935// Logical AND.936// Visit LHS. Only visit RHS if LHS was TRUE.937LabelTy LabelFalse = this->getLabel();938LabelTy LabelEnd = this->getLabel();939940if (!this->visitBool(LHS))941return false;942if (!this->jumpFalse(LabelFalse))943return false;944945if (!this->visitBool(RHS))946return false;947if (!this->jump(LabelEnd))948return false;949950this->emitLabel(LabelFalse);951this->emitConstBool(false, E);952this->fallthrough(LabelEnd);953this->emitLabel(LabelEnd);954}955956if (DiscardResult)957return this->emitPopBool(E);958959// For C, cast back to integer type.960assert(T);961if (T != PT_Bool)962return this->emitCast(PT_Bool, *T, E);963return true;964}965966template <class Emitter>967bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {968// Prepare storage for result.969if (!Initializing) {970std::optional<unsigned> LocalIndex = allocateLocal(E);971if (!LocalIndex)972return false;973if (!this->emitGetPtrLocal(*LocalIndex, E))974return false;975}976977// Both LHS and RHS might _not_ be of complex type, but one of them978// needs to be.979const Expr *LHS = E->getLHS();980const Expr *RHS = E->getRHS();981982PrimType ResultElemT = this->classifyComplexElementType(E->getType());983unsigned ResultOffset = ~0u;984if (!DiscardResult)985ResultOffset = this->allocateLocalPrimitive(E, PT_Ptr, true, false);986987// Save result pointer in ResultOffset988if (!this->DiscardResult) {989if (!this->emitDupPtr(E))990return false;991if (!this->emitSetLocal(PT_Ptr, ResultOffset, E))992return false;993}994QualType LHSType = LHS->getType();995if (const auto *AT = LHSType->getAs<AtomicType>())996LHSType = AT->getValueType();997QualType RHSType = RHS->getType();998if (const auto *AT = RHSType->getAs<AtomicType>())999RHSType = AT->getValueType();10001001bool LHSIsComplex = LHSType->isAnyComplexType();1002unsigned LHSOffset;1003bool RHSIsComplex = RHSType->isAnyComplexType();10041005// For ComplexComplex Mul, we have special ops to make their implementation1006// easier.1007BinaryOperatorKind Op = E->getOpcode();1008if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {1009assert(classifyPrim(LHSType->getAs<ComplexType>()->getElementType()) ==1010classifyPrim(RHSType->getAs<ComplexType>()->getElementType()));1011PrimType ElemT =1012classifyPrim(LHSType->getAs<ComplexType>()->getElementType());1013if (!this->visit(LHS))1014return false;1015if (!this->visit(RHS))1016return false;1017return this->emitMulc(ElemT, E);1018}10191020if (Op == BO_Div && RHSIsComplex) {1021QualType ElemQT = RHSType->getAs<ComplexType>()->getElementType();1022PrimType ElemT = classifyPrim(ElemQT);1023// If the LHS is not complex, we still need to do the full complex1024// division, so just stub create a complex value and stub it out with1025// the LHS and a zero.10261027if (!LHSIsComplex) {1028// This is using the RHS type for the fake-complex LHS.1029if (auto LHSO = allocateLocal(RHS))1030LHSOffset = *LHSO;1031else1032return false;10331034if (!this->emitGetPtrLocal(LHSOffset, E))1035return false;10361037if (!this->visit(LHS))1038return false;1039// real is LHS1040if (!this->emitInitElem(ElemT, 0, E))1041return false;1042// imag is zero1043if (!this->visitZeroInitializer(ElemT, ElemQT, E))1044return false;1045if (!this->emitInitElem(ElemT, 1, E))1046return false;1047} else {1048if (!this->visit(LHS))1049return false;1050}10511052if (!this->visit(RHS))1053return false;1054return this->emitDivc(ElemT, E);1055}10561057// Evaluate LHS and save value to LHSOffset.1058if (LHSType->isAnyComplexType()) {1059LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false);1060if (!this->visit(LHS))1061return false;1062if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))1063return false;1064} else {1065PrimType LHST = classifyPrim(LHSType);1066LHSOffset = this->allocateLocalPrimitive(LHS, LHST, true, false);1067if (!this->visit(LHS))1068return false;1069if (!this->emitSetLocal(LHST, LHSOffset, E))1070return false;1071}10721073// Same with RHS.1074unsigned RHSOffset;1075if (RHSType->isAnyComplexType()) {1076RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false);1077if (!this->visit(RHS))1078return false;1079if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))1080return false;1081} else {1082PrimType RHST = classifyPrim(RHSType);1083RHSOffset = this->allocateLocalPrimitive(RHS, RHST, true, false);1084if (!this->visit(RHS))1085return false;1086if (!this->emitSetLocal(RHST, RHSOffset, E))1087return false;1088}10891090// For both LHS and RHS, either load the value from the complex pointer, or1091// directly from the local variable. For index 1 (i.e. the imaginary part),1092// just load 0 and do the operation anyway.1093auto loadComplexValue = [this](bool IsComplex, bool LoadZero,1094unsigned ElemIndex, unsigned Offset,1095const Expr *E) -> bool {1096if (IsComplex) {1097if (!this->emitGetLocal(PT_Ptr, Offset, E))1098return false;1099return this->emitArrayElemPop(classifyComplexElementType(E->getType()),1100ElemIndex, E);1101}1102if (ElemIndex == 0 || !LoadZero)1103return this->emitGetLocal(classifyPrim(E->getType()), Offset, E);1104return this->visitZeroInitializer(classifyPrim(E->getType()), E->getType(),1105E);1106};11071108// Now we can get pointers to the LHS and RHS from the offsets above.1109for (unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {1110// Result pointer for the store later.1111if (!this->DiscardResult) {1112if (!this->emitGetLocal(PT_Ptr, ResultOffset, E))1113return false;1114}11151116// The actual operation.1117switch (Op) {1118case BO_Add:1119if (!loadComplexValue(LHSIsComplex, true, ElemIndex, LHSOffset, LHS))1120return false;11211122if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))1123return false;1124if (ResultElemT == PT_Float) {1125if (!this->emitAddf(getRoundingMode(E), E))1126return false;1127} else {1128if (!this->emitAdd(ResultElemT, E))1129return false;1130}1131break;1132case BO_Sub:1133if (!loadComplexValue(LHSIsComplex, true, ElemIndex, LHSOffset, LHS))1134return false;11351136if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))1137return false;1138if (ResultElemT == PT_Float) {1139if (!this->emitSubf(getRoundingMode(E), E))1140return false;1141} else {1142if (!this->emitSub(ResultElemT, E))1143return false;1144}1145break;1146case BO_Mul:1147if (!loadComplexValue(LHSIsComplex, false, ElemIndex, LHSOffset, LHS))1148return false;11491150if (!loadComplexValue(RHSIsComplex, false, ElemIndex, RHSOffset, RHS))1151return false;11521153if (ResultElemT == PT_Float) {1154if (!this->emitMulf(getRoundingMode(E), E))1155return false;1156} else {1157if (!this->emitMul(ResultElemT, E))1158return false;1159}1160break;1161case BO_Div:1162assert(!RHSIsComplex);1163if (!loadComplexValue(LHSIsComplex, false, ElemIndex, LHSOffset, LHS))1164return false;11651166if (!loadComplexValue(RHSIsComplex, false, ElemIndex, RHSOffset, RHS))1167return false;11681169if (ResultElemT == PT_Float) {1170if (!this->emitDivf(getRoundingMode(E), E))1171return false;1172} else {1173if (!this->emitDiv(ResultElemT, E))1174return false;1175}1176break;11771178default:1179return false;1180}11811182if (!this->DiscardResult) {1183// Initialize array element with the value we just computed.1184if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))1185return false;1186} else {1187if (!this->emitPop(ResultElemT, E))1188return false;1189}1190}1191return true;1192}11931194template <class Emitter>1195bool Compiler<Emitter>::VisitImplicitValueInitExpr(1196const ImplicitValueInitExpr *E) {1197QualType QT = E->getType();11981199if (std::optional<PrimType> T = classify(QT))1200return this->visitZeroInitializer(*T, QT, E);12011202if (QT->isRecordType()) {1203const RecordDecl *RD = QT->getAsRecordDecl();1204assert(RD);1205if (RD->isInvalidDecl())1206return false;1207if (RD->isUnion()) {1208// C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the1209// object's first non-static named data member is zero-initialized1210// FIXME1211return false;1212}12131214if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);1215CXXRD && CXXRD->getNumVBases() > 0) {1216// TODO: Diagnose.1217return false;1218}12191220const Record *R = getRecord(QT);1221if (!R)1222return false;12231224assert(Initializing);1225return this->visitZeroRecordInitializer(R, E);1226}12271228if (QT->isIncompleteArrayType())1229return true;12301231if (QT->isArrayType()) {1232const ArrayType *AT = QT->getAsArrayTypeUnsafe();1233assert(AT);1234const auto *CAT = cast<ConstantArrayType>(AT);1235size_t NumElems = CAT->getZExtSize();1236PrimType ElemT = classifyPrim(CAT->getElementType());12371238for (size_t I = 0; I != NumElems; ++I) {1239if (!this->visitZeroInitializer(ElemT, CAT->getElementType(), E))1240return false;1241if (!this->emitInitElem(ElemT, I, E))1242return false;1243}12441245return true;1246}12471248if (const auto *ComplexTy = E->getType()->getAs<ComplexType>()) {1249assert(Initializing);1250QualType ElemQT = ComplexTy->getElementType();1251PrimType ElemT = classifyPrim(ElemQT);1252for (unsigned I = 0; I < 2; ++I) {1253if (!this->visitZeroInitializer(ElemT, ElemQT, E))1254return false;1255if (!this->emitInitElem(ElemT, I, E))1256return false;1257}1258return true;1259}12601261if (const auto *VecT = E->getType()->getAs<VectorType>()) {1262unsigned NumVecElements = VecT->getNumElements();1263QualType ElemQT = VecT->getElementType();1264PrimType ElemT = classifyPrim(ElemQT);12651266for (unsigned I = 0; I < NumVecElements; ++I) {1267if (!this->visitZeroInitializer(ElemT, ElemQT, E))1268return false;1269if (!this->emitInitElem(ElemT, I, E))1270return false;1271}1272return true;1273}12741275return false;1276}12771278template <class Emitter>1279bool Compiler<Emitter>::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {1280const Expr *Base = E->getBase();1281const Expr *Index = E->getIdx();12821283if (DiscardResult)1284return this->discard(Base) && this->discard(Index);12851286// Take pointer of LHS, add offset from RHS.1287// What's left on the stack after this is a pointer.1288if (!this->visit(Base))1289return false;12901291if (!this->visit(Index))1292return false;12931294PrimType IndexT = classifyPrim(Index->getType());1295return this->emitArrayElemPtrPop(IndexT, E);1296}12971298template <class Emitter>1299bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,1300const Expr *ArrayFiller, const Expr *E) {13011302QualType QT = E->getType();13031304if (const auto *AT = QT->getAs<AtomicType>())1305QT = AT->getValueType();13061307if (QT->isVoidType())1308return this->emitInvalid(E);13091310// Handle discarding first.1311if (DiscardResult) {1312for (const Expr *Init : Inits) {1313if (!this->discard(Init))1314return false;1315}1316return true;1317}13181319// Primitive values.1320if (std::optional<PrimType> T = classify(QT)) {1321assert(!DiscardResult);1322if (Inits.size() == 0)1323return this->visitZeroInitializer(*T, QT, E);1324assert(Inits.size() == 1);1325return this->delegate(Inits[0]);1326}13271328if (QT->isRecordType()) {1329const Record *R = getRecord(QT);13301331if (Inits.size() == 1 && E->getType() == Inits[0]->getType())1332return this->delegate(Inits[0]);13331334auto initPrimitiveField = [=](const Record::Field *FieldToInit,1335const Expr *Init, PrimType T) -> bool {1336InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(Init));1337if (!this->visit(Init))1338return false;13391340if (FieldToInit->isBitField())1341return this->emitInitBitField(T, FieldToInit, E);1342return this->emitInitField(T, FieldToInit->Offset, E);1343};13441345auto initCompositeField = [=](const Record::Field *FieldToInit,1346const Expr *Init) -> bool {1347InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(Init));1348InitLinkScope<Emitter> ILS(this, InitLink::Field(FieldToInit->Offset));1349// Non-primitive case. Get a pointer to the field-to-initialize1350// on the stack and recurse into visitInitializer().1351if (!this->emitGetPtrField(FieldToInit->Offset, Init))1352return false;1353if (!this->visitInitializer(Init))1354return false;1355return this->emitPopPtr(E);1356};13571358if (R->isUnion()) {1359if (Inits.size() == 0) {1360// Zero-initialize the first union field.1361if (R->getNumFields() == 0)1362return this->emitFinishInit(E);1363const Record::Field *FieldToInit = R->getField(0u);1364QualType FieldType = FieldToInit->Desc->getType();1365if (std::optional<PrimType> T = classify(FieldType)) {1366if (!this->visitZeroInitializer(*T, FieldType, E))1367return false;1368if (!this->emitInitField(*T, FieldToInit->Offset, E))1369return false;1370}1371// FIXME: Non-primitive case?1372} else {1373const Expr *Init = Inits[0];1374const FieldDecl *FToInit = nullptr;1375if (const auto *ILE = dyn_cast<InitListExpr>(E))1376FToInit = ILE->getInitializedFieldInUnion();1377else1378FToInit = cast<CXXParenListInitExpr>(E)->getInitializedFieldInUnion();13791380const Record::Field *FieldToInit = R->getField(FToInit);1381if (std::optional<PrimType> T = classify(Init)) {1382if (!initPrimitiveField(FieldToInit, Init, *T))1383return false;1384} else {1385if (!initCompositeField(FieldToInit, Init))1386return false;1387}1388}1389return this->emitFinishInit(E);1390}13911392assert(!R->isUnion());1393unsigned InitIndex = 0;1394for (const Expr *Init : Inits) {1395// Skip unnamed bitfields.1396while (InitIndex < R->getNumFields() &&1397R->getField(InitIndex)->Decl->isUnnamedBitField())1398++InitIndex;13991400if (std::optional<PrimType> T = classify(Init)) {1401const Record::Field *FieldToInit = R->getField(InitIndex);1402if (!initPrimitiveField(FieldToInit, Init, *T))1403return false;1404++InitIndex;1405} else {1406// Initializer for a direct base class.1407if (const Record::Base *B = R->getBase(Init->getType())) {1408if (!this->emitGetPtrBase(B->Offset, Init))1409return false;14101411if (!this->visitInitializer(Init))1412return false;14131414if (!this->emitFinishInitPop(E))1415return false;1416// Base initializers don't increase InitIndex, since they don't count1417// into the Record's fields.1418} else {1419const Record::Field *FieldToInit = R->getField(InitIndex);1420if (!initCompositeField(FieldToInit, Init))1421return false;1422++InitIndex;1423}1424}1425}1426return this->emitFinishInit(E);1427}14281429if (QT->isArrayType()) {1430if (Inits.size() == 1 && QT == Inits[0]->getType())1431return this->delegate(Inits[0]);14321433unsigned ElementIndex = 0;1434for (const Expr *Init : Inits) {1435if (const auto *EmbedS =1436dyn_cast<EmbedExpr>(Init->IgnoreParenImpCasts())) {1437PrimType TargetT = classifyPrim(Init->getType());14381439auto Eval = [&](const Expr *Init, unsigned ElemIndex) {1440PrimType InitT = classifyPrim(Init->getType());1441if (!this->visit(Init))1442return false;1443if (InitT != TargetT) {1444if (!this->emitCast(InitT, TargetT, E))1445return false;1446}1447return this->emitInitElem(TargetT, ElemIndex, Init);1448};1449if (!EmbedS->doForEachDataElement(Eval, ElementIndex))1450return false;1451} else {1452if (!this->visitArrayElemInit(ElementIndex, Init))1453return false;1454++ElementIndex;1455}1456}14571458// Expand the filler expression.1459// FIXME: This should go away.1460if (ArrayFiller) {1461const ConstantArrayType *CAT =1462Ctx.getASTContext().getAsConstantArrayType(QT);1463uint64_t NumElems = CAT->getZExtSize();14641465for (; ElementIndex != NumElems; ++ElementIndex) {1466if (!this->visitArrayElemInit(ElementIndex, ArrayFiller))1467return false;1468}1469}14701471return this->emitFinishInit(E);1472}14731474if (const auto *ComplexTy = QT->getAs<ComplexType>()) {1475unsigned NumInits = Inits.size();14761477if (NumInits == 1)1478return this->delegate(Inits[0]);14791480QualType ElemQT = ComplexTy->getElementType();1481PrimType ElemT = classifyPrim(ElemQT);1482if (NumInits == 0) {1483// Zero-initialize both elements.1484for (unsigned I = 0; I < 2; ++I) {1485if (!this->visitZeroInitializer(ElemT, ElemQT, E))1486return false;1487if (!this->emitInitElem(ElemT, I, E))1488return false;1489}1490} else if (NumInits == 2) {1491unsigned InitIndex = 0;1492for (const Expr *Init : Inits) {1493if (!this->visit(Init))1494return false;14951496if (!this->emitInitElem(ElemT, InitIndex, E))1497return false;1498++InitIndex;1499}1500}1501return true;1502}15031504if (const auto *VecT = QT->getAs<VectorType>()) {1505unsigned NumVecElements = VecT->getNumElements();1506assert(NumVecElements >= Inits.size());15071508QualType ElemQT = VecT->getElementType();1509PrimType ElemT = classifyPrim(ElemQT);15101511// All initializer elements.1512unsigned InitIndex = 0;1513for (const Expr *Init : Inits) {1514if (!this->visit(Init))1515return false;15161517// If the initializer is of vector type itself, we have to deconstruct1518// that and initialize all the target fields from the initializer fields.1519if (const auto *InitVecT = Init->getType()->getAs<VectorType>()) {1520if (!this->emitCopyArray(ElemT, 0, InitIndex,1521InitVecT->getNumElements(), E))1522return false;1523InitIndex += InitVecT->getNumElements();1524} else {1525if (!this->emitInitElem(ElemT, InitIndex, E))1526return false;1527++InitIndex;1528}1529}15301531assert(InitIndex <= NumVecElements);15321533// Fill the rest with zeroes.1534for (; InitIndex != NumVecElements; ++InitIndex) {1535if (!this->visitZeroInitializer(ElemT, ElemQT, E))1536return false;1537if (!this->emitInitElem(ElemT, InitIndex, E))1538return false;1539}1540return true;1541}15421543return false;1544}15451546/// Pointer to the array(not the element!) must be on the stack when calling1547/// this.1548template <class Emitter>1549bool Compiler<Emitter>::visitArrayElemInit(unsigned ElemIndex,1550const Expr *Init) {1551if (std::optional<PrimType> T = classify(Init->getType())) {1552// Visit the primitive element like normal.1553if (!this->visit(Init))1554return false;1555return this->emitInitElem(*T, ElemIndex, Init);1556}15571558// Advance the pointer currently on the stack to the given1559// dimension.1560if (!this->emitConstUint32(ElemIndex, Init))1561return false;1562if (!this->emitArrayElemPtrUint32(Init))1563return false;1564if (!this->visitInitializer(Init))1565return false;1566return this->emitFinishInitPop(Init);1567}15681569template <class Emitter>1570bool Compiler<Emitter>::VisitInitListExpr(const InitListExpr *E) {1571return this->visitInitList(E->inits(), E->getArrayFiller(), E);1572}15731574template <class Emitter>1575bool Compiler<Emitter>::VisitCXXParenListInitExpr(1576const CXXParenListInitExpr *E) {1577return this->visitInitList(E->getInitExprs(), E->getArrayFiller(), E);1578}15791580template <class Emitter>1581bool Compiler<Emitter>::VisitSubstNonTypeTemplateParmExpr(1582const SubstNonTypeTemplateParmExpr *E) {1583return this->delegate(E->getReplacement());1584}15851586template <class Emitter>1587bool Compiler<Emitter>::VisitConstantExpr(const ConstantExpr *E) {1588std::optional<PrimType> T = classify(E->getType());1589if (T && E->hasAPValueResult()) {1590// Try to emit the APValue directly, without visiting the subexpr.1591// This will only fail if we can't emit the APValue, so won't emit any1592// diagnostics or any double values.1593if (DiscardResult)1594return true;15951596if (this->visitAPValue(E->getAPValueResult(), *T, E))1597return true;1598}1599return this->delegate(E->getSubExpr());1600}16011602template <class Emitter>1603bool Compiler<Emitter>::VisitEmbedExpr(const EmbedExpr *E) {1604auto It = E->begin();1605return this->visit(*It);1606}16071608static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx,1609UnaryExprOrTypeTrait Kind) {1610bool AlignOfReturnsPreferred =1611ASTCtx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;16121613// C++ [expr.alignof]p3:1614// When alignof is applied to a reference type, the result is the1615// alignment of the referenced type.1616if (const auto *Ref = T->getAs<ReferenceType>())1617T = Ref->getPointeeType();16181619if (T.getQualifiers().hasUnaligned())1620return CharUnits::One();16211622// __alignof is defined to return the preferred alignment.1623// Before 8, clang returned the preferred alignment for alignof and1624// _Alignof as well.1625if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)1626return ASTCtx.toCharUnitsFromBits(ASTCtx.getPreferredTypeAlign(T));16271628return ASTCtx.getTypeAlignInChars(T);1629}16301631template <class Emitter>1632bool Compiler<Emitter>::VisitUnaryExprOrTypeTraitExpr(1633const UnaryExprOrTypeTraitExpr *E) {1634UnaryExprOrTypeTrait Kind = E->getKind();1635const ASTContext &ASTCtx = Ctx.getASTContext();16361637if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {1638QualType ArgType = E->getTypeOfArgument();16391640// C++ [expr.sizeof]p2: "When applied to a reference or a reference type,1641// the result is the size of the referenced type."1642if (const auto *Ref = ArgType->getAs<ReferenceType>())1643ArgType = Ref->getPointeeType();16441645CharUnits Size;1646if (ArgType->isVoidType() || ArgType->isFunctionType())1647Size = CharUnits::One();1648else {1649if (ArgType->isDependentType() || !ArgType->isConstantSizeType())1650return false;16511652if (Kind == UETT_SizeOf)1653Size = ASTCtx.getTypeSizeInChars(ArgType);1654else1655Size = ASTCtx.getTypeInfoDataSizeInChars(ArgType).Width;1656}16571658if (DiscardResult)1659return true;16601661return this->emitConst(Size.getQuantity(), E);1662}16631664if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {1665CharUnits Size;16661667if (E->isArgumentType()) {1668QualType ArgType = E->getTypeOfArgument();16691670Size = AlignOfType(ArgType, ASTCtx, Kind);1671} else {1672// Argument is an expression, not a type.1673const Expr *Arg = E->getArgumentExpr()->IgnoreParens();16741675// The kinds of expressions that we have special-case logic here for1676// should be kept up to date with the special checks for those1677// expressions in Sema.16781679// alignof decl is always accepted, even if it doesn't make sense: we1680// default to 1 in those cases.1681if (const auto *DRE = dyn_cast<DeclRefExpr>(Arg))1682Size = ASTCtx.getDeclAlign(DRE->getDecl(),1683/*RefAsPointee*/ true);1684else if (const auto *ME = dyn_cast<MemberExpr>(Arg))1685Size = ASTCtx.getDeclAlign(ME->getMemberDecl(),1686/*RefAsPointee*/ true);1687else1688Size = AlignOfType(Arg->getType(), ASTCtx, Kind);1689}16901691if (DiscardResult)1692return true;16931694return this->emitConst(Size.getQuantity(), E);1695}16961697if (Kind == UETT_VectorElements) {1698if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>())1699return this->emitConst(VT->getNumElements(), E);1700assert(E->getTypeOfArgument()->isSizelessVectorType());1701return this->emitSizelessVectorElementSize(E);1702}17031704if (Kind == UETT_VecStep) {1705if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>()) {1706unsigned N = VT->getNumElements();17071708// The vec_step built-in functions that take a 3-component1709// vector return 4. (OpenCL 1.1 spec 6.11.12)1710if (N == 3)1711N = 4;17121713return this->emitConst(N, E);1714}1715return this->emitConst(1, E);1716}17171718return false;1719}17201721template <class Emitter>1722bool Compiler<Emitter>::VisitMemberExpr(const MemberExpr *E) {1723// 'Base.Member'1724const Expr *Base = E->getBase();1725const ValueDecl *Member = E->getMemberDecl();17261727if (DiscardResult)1728return this->discard(Base);17291730// MemberExprs are almost always lvalues, in which case we don't need to1731// do the load. But sometimes they aren't.1732const auto maybeLoadValue = [&]() -> bool {1733if (E->isGLValue())1734return true;1735if (std::optional<PrimType> T = classify(E))1736return this->emitLoadPop(*T, E);1737return false;1738};17391740if (const auto *VD = dyn_cast<VarDecl>(Member)) {1741// I am almost confident in saying that a var decl must be static1742// and therefore registered as a global variable. But this will probably1743// turn out to be wrong some time in the future, as always.1744if (auto GlobalIndex = P.getGlobal(VD))1745return this->emitGetPtrGlobal(*GlobalIndex, E) && maybeLoadValue();1746return false;1747}17481749if (!isa<FieldDecl>(Member))1750return this->discard(Base) && this->visitDeclRef(Member, E);17511752if (Initializing) {1753if (!this->delegate(Base))1754return false;1755} else {1756if (!this->visit(Base))1757return false;1758}17591760// Base above gives us a pointer on the stack.1761const auto *FD = cast<FieldDecl>(Member);1762const RecordDecl *RD = FD->getParent();1763const Record *R = getRecord(RD);1764if (!R)1765return false;1766const Record::Field *F = R->getField(FD);1767// Leave a pointer to the field on the stack.1768if (F->Decl->getType()->isReferenceType())1769return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue();1770return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue();1771}17721773template <class Emitter>1774bool Compiler<Emitter>::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E) {1775// ArrayIndex might not be set if a ArrayInitIndexExpr is being evaluated1776// stand-alone, e.g. via EvaluateAsInt().1777if (!ArrayIndex)1778return false;1779return this->emitConst(*ArrayIndex, E);1780}17811782template <class Emitter>1783bool Compiler<Emitter>::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {1784assert(Initializing);1785assert(!DiscardResult);17861787// We visit the common opaque expression here once so we have its value1788// cached.1789if (!this->discard(E->getCommonExpr()))1790return false;17911792// TODO: This compiles to quite a lot of bytecode if the array is larger.1793// Investigate compiling this to a loop.1794const Expr *SubExpr = E->getSubExpr();1795size_t Size = E->getArraySize().getZExtValue();17961797// So, every iteration, we execute an assignment here1798// where the LHS is on the stack (the target array)1799// and the RHS is our SubExpr.1800for (size_t I = 0; I != Size; ++I) {1801ArrayIndexScope<Emitter> IndexScope(this, I);1802BlockScope<Emitter> BS(this);18031804if (!this->visitArrayElemInit(I, SubExpr))1805return false;1806if (!BS.destroyLocals())1807return false;1808}1809return true;1810}18111812template <class Emitter>1813bool Compiler<Emitter>::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {1814const Expr *SourceExpr = E->getSourceExpr();1815if (!SourceExpr)1816return false;18171818if (Initializing)1819return this->visitInitializer(SourceExpr);18201821PrimType SubExprT = classify(SourceExpr).value_or(PT_Ptr);1822if (auto It = OpaqueExprs.find(E); It != OpaqueExprs.end())1823return this->emitGetLocal(SubExprT, It->second, E);18241825if (!this->visit(SourceExpr))1826return false;18271828// At this point we either have the evaluated source expression or a pointer1829// to an object on the stack. We want to create a local variable that stores1830// this value.1831unsigned LocalIndex = allocateLocalPrimitive(E, SubExprT, /*IsConst=*/true);1832if (!this->emitSetLocal(SubExprT, LocalIndex, E))1833return false;18341835// Here the local variable is created but the value is removed from the stack,1836// so we put it back if the caller needs it.1837if (!DiscardResult) {1838if (!this->emitGetLocal(SubExprT, LocalIndex, E))1839return false;1840}18411842// This is cleaned up when the local variable is destroyed.1843OpaqueExprs.insert({E, LocalIndex});18441845return true;1846}18471848template <class Emitter>1849bool Compiler<Emitter>::VisitAbstractConditionalOperator(1850const AbstractConditionalOperator *E) {1851const Expr *Condition = E->getCond();1852const Expr *TrueExpr = E->getTrueExpr();1853const Expr *FalseExpr = E->getFalseExpr();18541855LabelTy LabelEnd = this->getLabel(); // Label after the operator.1856LabelTy LabelFalse = this->getLabel(); // Label for the false expr.18571858if (!this->visitBool(Condition))1859return false;18601861if (!this->jumpFalse(LabelFalse))1862return false;18631864if (!this->delegate(TrueExpr))1865return false;1866if (!this->jump(LabelEnd))1867return false;18681869this->emitLabel(LabelFalse);18701871if (!this->delegate(FalseExpr))1872return false;18731874this->fallthrough(LabelEnd);1875this->emitLabel(LabelEnd);18761877return true;1878}18791880template <class Emitter>1881bool Compiler<Emitter>::VisitStringLiteral(const StringLiteral *E) {1882if (DiscardResult)1883return true;18841885if (!Initializing) {1886unsigned StringIndex = P.createGlobalString(E);1887return this->emitGetPtrGlobal(StringIndex, E);1888}18891890// We are initializing an array on the stack.1891const ConstantArrayType *CAT =1892Ctx.getASTContext().getAsConstantArrayType(E->getType());1893assert(CAT && "a string literal that's not a constant array?");18941895// If the initializer string is too long, a diagnostic has already been1896// emitted. Read only the array length from the string literal.1897unsigned ArraySize = CAT->getZExtSize();1898unsigned N = std::min(ArraySize, E->getLength());1899size_t CharWidth = E->getCharByteWidth();19001901for (unsigned I = 0; I != N; ++I) {1902uint32_t CodeUnit = E->getCodeUnit(I);19031904if (CharWidth == 1) {1905this->emitConstSint8(CodeUnit, E);1906this->emitInitElemSint8(I, E);1907} else if (CharWidth == 2) {1908this->emitConstUint16(CodeUnit, E);1909this->emitInitElemUint16(I, E);1910} else if (CharWidth == 4) {1911this->emitConstUint32(CodeUnit, E);1912this->emitInitElemUint32(I, E);1913} else {1914llvm_unreachable("unsupported character width");1915}1916}19171918// Fill up the rest of the char array with NUL bytes.1919for (unsigned I = N; I != ArraySize; ++I) {1920if (CharWidth == 1) {1921this->emitConstSint8(0, E);1922this->emitInitElemSint8(I, E);1923} else if (CharWidth == 2) {1924this->emitConstUint16(0, E);1925this->emitInitElemUint16(I, E);1926} else if (CharWidth == 4) {1927this->emitConstUint32(0, E);1928this->emitInitElemUint32(I, E);1929} else {1930llvm_unreachable("unsupported character width");1931}1932}19331934return true;1935}19361937template <class Emitter>1938bool Compiler<Emitter>::VisitObjCStringLiteral(const ObjCStringLiteral *E) {1939return this->delegate(E->getString());1940}19411942template <class Emitter>1943bool Compiler<Emitter>::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {1944auto &A = Ctx.getASTContext();1945std::string Str;1946A.getObjCEncodingForType(E->getEncodedType(), Str);1947StringLiteral *SL =1948StringLiteral::Create(A, Str, StringLiteralKind::Ordinary,1949/*Pascal=*/false, E->getType(), E->getAtLoc());1950return this->delegate(SL);1951}19521953template <class Emitter>1954bool Compiler<Emitter>::VisitSYCLUniqueStableNameExpr(1955const SYCLUniqueStableNameExpr *E) {1956if (DiscardResult)1957return true;19581959assert(!Initializing);19601961auto &A = Ctx.getASTContext();1962std::string ResultStr = E->ComputeName(A);19631964QualType CharTy = A.CharTy.withConst();1965APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);1966QualType ArrayTy = A.getConstantArrayType(CharTy, Size, nullptr,1967ArraySizeModifier::Normal, 0);19681969StringLiteral *SL =1970StringLiteral::Create(A, ResultStr, StringLiteralKind::Ordinary,1971/*Pascal=*/false, ArrayTy, E->getLocation());19721973unsigned StringIndex = P.createGlobalString(SL);1974return this->emitGetPtrGlobal(StringIndex, E);1975}19761977template <class Emitter>1978bool Compiler<Emitter>::VisitCharacterLiteral(const CharacterLiteral *E) {1979if (DiscardResult)1980return true;1981return this->emitConst(E->getValue(), E);1982}19831984template <class Emitter>1985bool Compiler<Emitter>::VisitFloatCompoundAssignOperator(1986const CompoundAssignOperator *E) {19871988const Expr *LHS = E->getLHS();1989const Expr *RHS = E->getRHS();1990QualType LHSType = LHS->getType();1991QualType LHSComputationType = E->getComputationLHSType();1992QualType ResultType = E->getComputationResultType();1993std::optional<PrimType> LT = classify(LHSComputationType);1994std::optional<PrimType> RT = classify(ResultType);19951996assert(ResultType->isFloatingType());19971998if (!LT || !RT)1999return false;20002001PrimType LHST = classifyPrim(LHSType);20022003// C++17 onwards require that we evaluate the RHS first.2004// Compute RHS and save it in a temporary variable so we can2005// load it again later.2006if (!visit(RHS))2007return false;20082009unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);2010if (!this->emitSetLocal(*RT, TempOffset, E))2011return false;20122013// First, visit LHS.2014if (!visit(LHS))2015return false;2016if (!this->emitLoad(LHST, E))2017return false;20182019// If necessary, convert LHS to its computation type.2020if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),2021LHSComputationType, E))2022return false;20232024// Now load RHS.2025if (!this->emitGetLocal(*RT, TempOffset, E))2026return false;20272028llvm::RoundingMode RM = getRoundingMode(E);2029switch (E->getOpcode()) {2030case BO_AddAssign:2031if (!this->emitAddf(RM, E))2032return false;2033break;2034case BO_SubAssign:2035if (!this->emitSubf(RM, E))2036return false;2037break;2038case BO_MulAssign:2039if (!this->emitMulf(RM, E))2040return false;2041break;2042case BO_DivAssign:2043if (!this->emitDivf(RM, E))2044return false;2045break;2046default:2047return false;2048}20492050if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->getType(), E))2051return false;20522053if (DiscardResult)2054return this->emitStorePop(LHST, E);2055return this->emitStore(LHST, E);2056}20572058template <class Emitter>2059bool Compiler<Emitter>::VisitPointerCompoundAssignOperator(2060const CompoundAssignOperator *E) {2061BinaryOperatorKind Op = E->getOpcode();2062const Expr *LHS = E->getLHS();2063const Expr *RHS = E->getRHS();2064std::optional<PrimType> LT = classify(LHS->getType());2065std::optional<PrimType> RT = classify(RHS->getType());20662067if (Op != BO_AddAssign && Op != BO_SubAssign)2068return false;20692070if (!LT || !RT)2071return false;20722073if (!visit(LHS))2074return false;20752076if (!this->emitLoad(*LT, LHS))2077return false;20782079if (!visit(RHS))2080return false;20812082if (Op == BO_AddAssign) {2083if (!this->emitAddOffset(*RT, E))2084return false;2085} else {2086if (!this->emitSubOffset(*RT, E))2087return false;2088}20892090if (DiscardResult)2091return this->emitStorePopPtr(E);2092return this->emitStorePtr(E);2093}20942095template <class Emitter>2096bool Compiler<Emitter>::VisitCompoundAssignOperator(2097const CompoundAssignOperator *E) {20982099const Expr *LHS = E->getLHS();2100const Expr *RHS = E->getRHS();2101std::optional<PrimType> LHSComputationT =2102classify(E->getComputationLHSType());2103std::optional<PrimType> LT = classify(LHS->getType());2104std::optional<PrimType> RT = classify(RHS->getType());2105std::optional<PrimType> ResultT = classify(E->getType());21062107if (!Ctx.getLangOpts().CPlusPlus14)2108return this->visit(RHS) && this->visit(LHS) && this->emitError(E);21092110if (!LT || !RT || !ResultT || !LHSComputationT)2111return false;21122113// Handle floating point operations separately here, since they2114// require special care.21152116if (ResultT == PT_Float || RT == PT_Float)2117return VisitFloatCompoundAssignOperator(E);21182119if (E->getType()->isPointerType())2120return VisitPointerCompoundAssignOperator(E);21212122assert(!E->getType()->isPointerType() && "Handled above");2123assert(!E->getType()->isFloatingType() && "Handled above");21242125// C++17 onwards require that we evaluate the RHS first.2126// Compute RHS and save it in a temporary variable so we can2127// load it again later.2128// FIXME: Compound assignments are unsequenced in C, so we might2129// have to figure out how to reject them.2130if (!visit(RHS))2131return false;21322133unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);21342135if (!this->emitSetLocal(*RT, TempOffset, E))2136return false;21372138// Get LHS pointer, load its value and cast it to the2139// computation type if necessary.2140if (!visit(LHS))2141return false;2142if (!this->emitLoad(*LT, E))2143return false;2144if (LT != LHSComputationT) {2145if (!this->emitCast(*LT, *LHSComputationT, E))2146return false;2147}21482149// Get the RHS value on the stack.2150if (!this->emitGetLocal(*RT, TempOffset, E))2151return false;21522153// Perform operation.2154switch (E->getOpcode()) {2155case BO_AddAssign:2156if (!this->emitAdd(*LHSComputationT, E))2157return false;2158break;2159case BO_SubAssign:2160if (!this->emitSub(*LHSComputationT, E))2161return false;2162break;2163case BO_MulAssign:2164if (!this->emitMul(*LHSComputationT, E))2165return false;2166break;2167case BO_DivAssign:2168if (!this->emitDiv(*LHSComputationT, E))2169return false;2170break;2171case BO_RemAssign:2172if (!this->emitRem(*LHSComputationT, E))2173return false;2174break;2175case BO_ShlAssign:2176if (!this->emitShl(*LHSComputationT, *RT, E))2177return false;2178break;2179case BO_ShrAssign:2180if (!this->emitShr(*LHSComputationT, *RT, E))2181return false;2182break;2183case BO_AndAssign:2184if (!this->emitBitAnd(*LHSComputationT, E))2185return false;2186break;2187case BO_XorAssign:2188if (!this->emitBitXor(*LHSComputationT, E))2189return false;2190break;2191case BO_OrAssign:2192if (!this->emitBitOr(*LHSComputationT, E))2193return false;2194break;2195default:2196llvm_unreachable("Unimplemented compound assign operator");2197}21982199// And now cast from LHSComputationT to ResultT.2200if (ResultT != LHSComputationT) {2201if (!this->emitCast(*LHSComputationT, *ResultT, E))2202return false;2203}22042205// And store the result in LHS.2206if (DiscardResult) {2207if (LHS->refersToBitField())2208return this->emitStoreBitFieldPop(*ResultT, E);2209return this->emitStorePop(*ResultT, E);2210}2211if (LHS->refersToBitField())2212return this->emitStoreBitField(*ResultT, E);2213return this->emitStore(*ResultT, E);2214}22152216template <class Emitter>2217bool Compiler<Emitter>::VisitExprWithCleanups(const ExprWithCleanups *E) {2218LocalScope<Emitter> ES(this);2219const Expr *SubExpr = E->getSubExpr();22202221assert(E->getNumObjects() == 0 && "TODO: Implement cleanups");22222223return this->delegate(SubExpr) && ES.destroyLocals();2224}22252226template <class Emitter>2227bool Compiler<Emitter>::VisitMaterializeTemporaryExpr(2228const MaterializeTemporaryExpr *E) {2229const Expr *SubExpr = E->getSubExpr();22302231if (Initializing) {2232// We already have a value, just initialize that.2233return this->delegate(SubExpr);2234}2235// If we don't end up using the materialized temporary anyway, don't2236// bother creating it.2237if (DiscardResult)2238return this->discard(SubExpr);22392240// When we're initializing a global variable *or* the storage duration of2241// the temporary is explicitly static, create a global variable.2242std::optional<PrimType> SubExprT = classify(SubExpr);2243bool IsStatic = E->getStorageDuration() == SD_Static;2244if (GlobalDecl || IsStatic) {2245std::optional<unsigned> GlobalIndex = P.createGlobal(E);2246if (!GlobalIndex)2247return false;22482249const LifetimeExtendedTemporaryDecl *TempDecl =2250E->getLifetimeExtendedTemporaryDecl();2251if (IsStatic)2252assert(TempDecl);22532254if (SubExprT) {2255if (!this->visit(SubExpr))2256return false;2257if (IsStatic) {2258if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl, E))2259return false;2260} else {2261if (!this->emitInitGlobal(*SubExprT, *GlobalIndex, E))2262return false;2263}2264return this->emitGetPtrGlobal(*GlobalIndex, E);2265}22662267// Non-primitive values.2268if (!this->emitGetPtrGlobal(*GlobalIndex, E))2269return false;2270if (!this->visitInitializer(SubExpr))2271return false;2272if (IsStatic)2273return this->emitInitGlobalTempComp(TempDecl, E);2274return true;2275}22762277// For everyhing else, use local variables.2278if (SubExprT) {2279unsigned LocalIndex = allocateLocalPrimitive(2280SubExpr, *SubExprT, /*IsConst=*/true, /*IsExtended=*/true);2281if (!this->visit(SubExpr))2282return false;2283if (!this->emitSetLocal(*SubExprT, LocalIndex, E))2284return false;2285return this->emitGetPtrLocal(LocalIndex, E);2286} else {2287const Expr *Inner = E->getSubExpr()->skipRValueSubobjectAdjustments();2288if (std::optional<unsigned> LocalIndex =2289allocateLocal(Inner, E->getExtendingDecl())) {2290InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));2291if (!this->emitGetPtrLocal(*LocalIndex, E))2292return false;2293return this->visitInitializer(SubExpr);2294}2295}2296return false;2297}22982299template <class Emitter>2300bool Compiler<Emitter>::VisitCXXBindTemporaryExpr(2301const CXXBindTemporaryExpr *E) {2302return this->delegate(E->getSubExpr());2303}23042305template <class Emitter>2306bool Compiler<Emitter>::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {2307const Expr *Init = E->getInitializer();2308if (Initializing) {2309// We already have a value, just initialize that.2310return this->visitInitializer(Init) && this->emitFinishInit(E);2311}23122313std::optional<PrimType> T = classify(E->getType());2314if (E->isFileScope()) {2315// Avoid creating a variable if this is a primitive RValue anyway.2316if (T && !E->isLValue())2317return this->delegate(Init);23182319if (std::optional<unsigned> GlobalIndex = P.createGlobal(E)) {2320if (!this->emitGetPtrGlobal(*GlobalIndex, E))2321return false;23222323if (T) {2324if (!this->visit(Init))2325return false;2326return this->emitInitGlobal(*T, *GlobalIndex, E);2327}23282329return this->visitInitializer(Init) && this->emitFinishInit(E);2330}23312332return false;2333}23342335// Otherwise, use a local variable.2336if (T && !E->isLValue()) {2337// For primitive types, we just visit the initializer.2338return this->delegate(Init);2339} else {2340unsigned LocalIndex;23412342if (T)2343LocalIndex = this->allocateLocalPrimitive(Init, *T, false, false);2344else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(Init))2345LocalIndex = *MaybeIndex;2346else2347return false;23482349if (!this->emitGetPtrLocal(LocalIndex, E))2350return false;23512352if (T) {2353if (!this->visit(Init)) {2354return false;2355}2356return this->emitInit(*T, E);2357} else {2358if (!this->visitInitializer(Init) || !this->emitFinishInit(E))2359return false;2360}23612362if (DiscardResult)2363return this->emitPopPtr(E);2364return true;2365}23662367return false;2368}23692370template <class Emitter>2371bool Compiler<Emitter>::VisitTypeTraitExpr(const TypeTraitExpr *E) {2372if (DiscardResult)2373return true;2374if (E->getType()->isBooleanType())2375return this->emitConstBool(E->getValue(), E);2376return this->emitConst(E->getValue(), E);2377}23782379template <class Emitter>2380bool Compiler<Emitter>::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {2381if (DiscardResult)2382return true;2383return this->emitConst(E->getValue(), E);2384}23852386template <class Emitter>2387bool Compiler<Emitter>::VisitLambdaExpr(const LambdaExpr *E) {2388if (DiscardResult)2389return true;23902391assert(Initializing);2392const Record *R = P.getOrCreateRecord(E->getLambdaClass());23932394auto *CaptureInitIt = E->capture_init_begin();2395// Initialize all fields (which represent lambda captures) of the2396// record with their initializers.2397for (const Record::Field &F : R->fields()) {2398const Expr *Init = *CaptureInitIt;2399++CaptureInitIt;24002401if (!Init)2402continue;24032404if (std::optional<PrimType> T = classify(Init)) {2405if (!this->visit(Init))2406return false;24072408if (!this->emitInitField(*T, F.Offset, E))2409return false;2410} else {2411if (!this->emitGetPtrField(F.Offset, E))2412return false;24132414if (!this->visitInitializer(Init))2415return false;24162417if (!this->emitPopPtr(E))2418return false;2419}2420}24212422return true;2423}24242425template <class Emitter>2426bool Compiler<Emitter>::VisitPredefinedExpr(const PredefinedExpr *E) {2427if (DiscardResult)2428return true;24292430return this->delegate(E->getFunctionName());2431}24322433template <class Emitter>2434bool Compiler<Emitter>::VisitCXXThrowExpr(const CXXThrowExpr *E) {2435if (E->getSubExpr() && !this->discard(E->getSubExpr()))2436return false;24372438return this->emitInvalid(E);2439}24402441template <class Emitter>2442bool Compiler<Emitter>::VisitCXXReinterpretCastExpr(2443const CXXReinterpretCastExpr *E) {2444if (!this->discard(E->getSubExpr()))2445return false;24462447return this->emitInvalidCast(CastKind::Reinterpret, E);2448}24492450template <class Emitter>2451bool Compiler<Emitter>::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {2452assert(E->getType()->isBooleanType());24532454if (DiscardResult)2455return true;2456return this->emitConstBool(E->getValue(), E);2457}24582459template <class Emitter>2460bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) {2461QualType T = E->getType();2462assert(!classify(T));24632464if (T->isRecordType()) {2465const CXXConstructorDecl *Ctor = E->getConstructor();24662467// Trivial copy/move constructor. Avoid copy.2468if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&2469Ctor->isTrivial() &&2470E->getArg(0)->isTemporaryObject(Ctx.getASTContext(),2471T->getAsCXXRecordDecl()))2472return this->visitInitializer(E->getArg(0));24732474// If we're discarding a construct expression, we still need2475// to allocate a variable and call the constructor and destructor.2476if (DiscardResult) {2477if (Ctor->isTrivial())2478return true;2479assert(!Initializing);2480std::optional<unsigned> LocalIndex = allocateLocal(E);24812482if (!LocalIndex)2483return false;24842485if (!this->emitGetPtrLocal(*LocalIndex, E))2486return false;2487}24882489// Zero initialization.2490if (E->requiresZeroInitialization()) {2491const Record *R = getRecord(E->getType());24922493if (!this->visitZeroRecordInitializer(R, E))2494return false;24952496// If the constructor is trivial anyway, we're done.2497if (Ctor->isTrivial())2498return true;2499}25002501const Function *Func = getFunction(Ctor);25022503if (!Func)2504return false;25052506assert(Func->hasThisPointer());2507assert(!Func->hasRVO());25082509// The This pointer is already on the stack because this is an initializer,2510// but we need to dup() so the call() below has its own copy.2511if (!this->emitDupPtr(E))2512return false;25132514// Constructor arguments.2515for (const auto *Arg : E->arguments()) {2516if (!this->visit(Arg))2517return false;2518}25192520if (Func->isVariadic()) {2521uint32_t VarArgSize = 0;2522unsigned NumParams = Func->getNumWrittenParams();2523for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I) {2524VarArgSize +=2525align(primSize(classify(E->getArg(I)->getType()).value_or(PT_Ptr)));2526}2527if (!this->emitCallVar(Func, VarArgSize, E))2528return false;2529} else {2530if (!this->emitCall(Func, 0, E))2531return false;2532}25332534// Immediately call the destructor if we have to.2535if (DiscardResult) {2536if (!this->emitRecordDestruction(getRecord(E->getType())))2537return false;2538if (!this->emitPopPtr(E))2539return false;2540}2541return true;2542}25432544if (T->isArrayType()) {2545const ConstantArrayType *CAT =2546Ctx.getASTContext().getAsConstantArrayType(E->getType());2547if (!CAT)2548return false;25492550size_t NumElems = CAT->getZExtSize();2551const Function *Func = getFunction(E->getConstructor());2552if (!Func || !Func->isConstexpr())2553return false;25542555// FIXME(perf): We're calling the constructor once per array element here,2556// in the old intepreter we had a special-case for trivial constructors.2557for (size_t I = 0; I != NumElems; ++I) {2558if (!this->emitConstUint64(I, E))2559return false;2560if (!this->emitArrayElemPtrUint64(E))2561return false;25622563// Constructor arguments.2564for (const auto *Arg : E->arguments()) {2565if (!this->visit(Arg))2566return false;2567}25682569if (!this->emitCall(Func, 0, E))2570return false;2571}2572return true;2573}25742575return false;2576}25772578template <class Emitter>2579bool Compiler<Emitter>::VisitSourceLocExpr(const SourceLocExpr *E) {2580if (DiscardResult)2581return true;25822583const APValue Val =2584E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);25852586// Things like __builtin_LINE().2587if (E->getType()->isIntegerType()) {2588assert(Val.isInt());2589const APSInt &I = Val.getInt();2590return this->emitConst(I, E);2591}2592// Otherwise, the APValue is an LValue, with only one element.2593// Theoretically, we don't need the APValue at all of course.2594assert(E->getType()->isPointerType());2595assert(Val.isLValue());2596const APValue::LValueBase &Base = Val.getLValueBase();2597if (const Expr *LValueExpr = Base.dyn_cast<const Expr *>())2598return this->visit(LValueExpr);25992600// Otherwise, we have a decl (which is the case for2601// __builtin_source_location).2602assert(Base.is<const ValueDecl *>());2603assert(Val.getLValuePath().size() == 0);2604const auto *BaseDecl = Base.dyn_cast<const ValueDecl *>();2605assert(BaseDecl);26062607auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);26082609std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(UGCD);2610if (!GlobalIndex)2611return false;26122613if (!this->emitGetPtrGlobal(*GlobalIndex, E))2614return false;26152616const Record *R = getRecord(E->getType());2617const APValue &V = UGCD->getValue();2618for (unsigned I = 0, N = R->getNumFields(); I != N; ++I) {2619const Record::Field *F = R->getField(I);2620const APValue &FieldValue = V.getStructField(I);26212622PrimType FieldT = classifyPrim(F->Decl->getType());26232624if (!this->visitAPValue(FieldValue, FieldT, E))2625return false;2626if (!this->emitInitField(FieldT, F->Offset, E))2627return false;2628}26292630// Leave the pointer to the global on the stack.2631return true;2632}26332634template <class Emitter>2635bool Compiler<Emitter>::VisitOffsetOfExpr(const OffsetOfExpr *E) {2636unsigned N = E->getNumComponents();2637if (N == 0)2638return false;26392640for (unsigned I = 0; I != N; ++I) {2641const OffsetOfNode &Node = E->getComponent(I);2642if (Node.getKind() == OffsetOfNode::Array) {2643const Expr *ArrayIndexExpr = E->getIndexExpr(Node.getArrayExprIndex());2644PrimType IndexT = classifyPrim(ArrayIndexExpr->getType());26452646if (DiscardResult) {2647if (!this->discard(ArrayIndexExpr))2648return false;2649continue;2650}26512652if (!this->visit(ArrayIndexExpr))2653return false;2654// Cast to Sint64.2655if (IndexT != PT_Sint64) {2656if (!this->emitCast(IndexT, PT_Sint64, E))2657return false;2658}2659}2660}26612662if (DiscardResult)2663return true;26642665PrimType T = classifyPrim(E->getType());2666return this->emitOffsetOf(T, E, E);2667}26682669template <class Emitter>2670bool Compiler<Emitter>::VisitCXXScalarValueInitExpr(2671const CXXScalarValueInitExpr *E) {2672QualType Ty = E->getType();26732674if (DiscardResult || Ty->isVoidType())2675return true;26762677if (std::optional<PrimType> T = classify(Ty))2678return this->visitZeroInitializer(*T, Ty, E);26792680if (const auto *CT = Ty->getAs<ComplexType>()) {2681if (!Initializing) {2682std::optional<unsigned> LocalIndex = allocateLocal(E);2683if (!LocalIndex)2684return false;2685if (!this->emitGetPtrLocal(*LocalIndex, E))2686return false;2687}26882689// Initialize both fields to 0.2690QualType ElemQT = CT->getElementType();2691PrimType ElemT = classifyPrim(ElemQT);26922693for (unsigned I = 0; I != 2; ++I) {2694if (!this->visitZeroInitializer(ElemT, ElemQT, E))2695return false;2696if (!this->emitInitElem(ElemT, I, E))2697return false;2698}2699return true;2700}27012702if (const auto *VT = Ty->getAs<VectorType>()) {2703// FIXME: Code duplication with the _Complex case above.2704if (!Initializing) {2705std::optional<unsigned> LocalIndex = allocateLocal(E);2706if (!LocalIndex)2707return false;2708if (!this->emitGetPtrLocal(*LocalIndex, E))2709return false;2710}27112712// Initialize all fields to 0.2713QualType ElemQT = VT->getElementType();2714PrimType ElemT = classifyPrim(ElemQT);27152716for (unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {2717if (!this->visitZeroInitializer(ElemT, ElemQT, E))2718return false;2719if (!this->emitInitElem(ElemT, I, E))2720return false;2721}2722return true;2723}27242725return false;2726}27272728template <class Emitter>2729bool Compiler<Emitter>::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {2730return this->emitConst(E->getPackLength(), E);2731}27322733template <class Emitter>2734bool Compiler<Emitter>::VisitGenericSelectionExpr(2735const GenericSelectionExpr *E) {2736return this->delegate(E->getResultExpr());2737}27382739template <class Emitter>2740bool Compiler<Emitter>::VisitChooseExpr(const ChooseExpr *E) {2741return this->delegate(E->getChosenSubExpr());2742}27432744template <class Emitter>2745bool Compiler<Emitter>::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) {2746if (DiscardResult)2747return true;27482749return this->emitConst(E->getValue(), E);2750}27512752template <class Emitter>2753bool Compiler<Emitter>::VisitCXXInheritedCtorInitExpr(2754const CXXInheritedCtorInitExpr *E) {2755const CXXConstructorDecl *Ctor = E->getConstructor();2756assert(!Ctor->isTrivial() &&2757"Trivial CXXInheritedCtorInitExpr, implement. (possible?)");2758const Function *F = this->getFunction(Ctor);2759assert(F);2760assert(!F->hasRVO());2761assert(F->hasThisPointer());27622763if (!this->emitDupPtr(SourceInfo{}))2764return false;27652766// Forward all arguments of the current function (which should be a2767// constructor itself) to the inherited ctor.2768// This is necessary because the calling code has pushed the pointer2769// of the correct base for us already, but the arguments need2770// to come after.2771unsigned Offset = align(primSize(PT_Ptr)); // instance pointer.2772for (const ParmVarDecl *PD : Ctor->parameters()) {2773PrimType PT = this->classify(PD->getType()).value_or(PT_Ptr);27742775if (!this->emitGetParam(PT, Offset, E))2776return false;2777Offset += align(primSize(PT));2778}27792780return this->emitCall(F, 0, E);2781}27822783template <class Emitter>2784bool Compiler<Emitter>::VisitCXXNewExpr(const CXXNewExpr *E) {2785assert(classifyPrim(E->getType()) == PT_Ptr);2786const Expr *Init = E->getInitializer();2787QualType ElementType = E->getAllocatedType();2788std::optional<PrimType> ElemT = classify(ElementType);2789unsigned PlacementArgs = E->getNumPlacementArgs();2790bool IsNoThrow = false;27912792// FIXME: Better diagnostic. diag::note_constexpr_new_placement2793if (PlacementArgs != 0) {2794// The only new-placement list we support is of the form (std::nothrow).2795//2796// FIXME: There is no restriction on this, but it's not clear that any2797// other form makes any sense. We get here for cases such as:2798//2799// new (std::align_val_t{N}) X(int)2800//2801// (which should presumably be valid only if N is a multiple of2802// alignof(int), and in any case can't be deallocated unless N is2803// alignof(X) and X has new-extended alignment).2804if (PlacementArgs != 1 || !E->getPlacementArg(0)->getType()->isNothrowT())2805return this->emitInvalid(E);28062807if (!this->discard(E->getPlacementArg(0)))2808return false;2809IsNoThrow = true;2810}28112812const Descriptor *Desc;2813if (ElemT) {2814if (E->isArray())2815Desc = nullptr; // We're not going to use it in this case.2816else2817Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,2818/*IsConst=*/false, /*IsTemporary=*/false,2819/*IsMutable=*/false);2820} else {2821Desc = P.createDescriptor(2822E, ElementType.getTypePtr(),2823E->isArray() ? std::nullopt : Descriptor::InlineDescMD,2824/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);2825}28262827if (E->isArray()) {2828std::optional<const Expr *> ArraySizeExpr = E->getArraySize();2829if (!ArraySizeExpr)2830return false;28312832const Expr *Stripped = *ArraySizeExpr;2833for (; auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);2834Stripped = ICE->getSubExpr())2835if (ICE->getCastKind() != CK_NoOp &&2836ICE->getCastKind() != CK_IntegralCast)2837break;28382839PrimType SizeT = classifyPrim(Stripped->getType());28402841if (!this->visit(Stripped))2842return false;28432844if (ElemT) {2845// N primitive elements.2846if (!this->emitAllocN(SizeT, *ElemT, E, IsNoThrow, E))2847return false;2848} else {2849// N Composite elements.2850if (!this->emitAllocCN(SizeT, Desc, IsNoThrow, E))2851return false;2852}28532854if (Init && !this->visitInitializer(Init))2855return false;28562857} else {2858// Allocate just one element.2859if (!this->emitAlloc(Desc, E))2860return false;28612862if (Init) {2863if (ElemT) {2864if (!this->visit(Init))2865return false;28662867if (!this->emitInit(*ElemT, E))2868return false;2869} else {2870// Composite.2871if (!this->visitInitializer(Init))2872return false;2873}2874}2875}28762877if (DiscardResult)2878return this->emitPopPtr(E);28792880return true;2881}28822883template <class Emitter>2884bool Compiler<Emitter>::VisitCXXDeleteExpr(const CXXDeleteExpr *E) {2885const Expr *Arg = E->getArgument();28862887// Arg must be an lvalue.2888if (!this->visit(Arg))2889return false;28902891return this->emitFree(E->isArrayForm(), E);2892}28932894template <class Emitter>2895bool Compiler<Emitter>::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {2896assert(Ctx.getLangOpts().CPlusPlus);2897return this->emitConstBool(E->getValue(), E);2898}28992900template <class Emitter>2901bool Compiler<Emitter>::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {2902if (DiscardResult)2903return true;2904assert(!Initializing);29052906const MSGuidDecl *GuidDecl = E->getGuidDecl();2907const RecordDecl *RD = GuidDecl->getType()->getAsRecordDecl();2908assert(RD);2909// If the definiton of the result type is incomplete, just return a dummy.2910// If (and when) that is read from, we will fail, but not now.2911if (!RD->isCompleteDefinition()) {2912if (std::optional<unsigned> I = P.getOrCreateDummy(GuidDecl))2913return this->emitGetPtrGlobal(*I, E);2914return false;2915}29162917std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(GuidDecl);2918if (!GlobalIndex)2919return false;2920if (!this->emitGetPtrGlobal(*GlobalIndex, E))2921return false;29222923assert(this->getRecord(E->getType()));29242925const APValue &V = GuidDecl->getAsAPValue();2926if (V.getKind() == APValue::None)2927return true;29282929assert(V.isStruct());2930assert(V.getStructNumBases() == 0);2931if (!this->visitAPValueInitializer(V, E))2932return false;29332934return this->emitFinishInit(E);2935}29362937template <class Emitter>2938bool Compiler<Emitter>::VisitRequiresExpr(const RequiresExpr *E) {2939assert(classifyPrim(E->getType()) == PT_Bool);2940if (DiscardResult)2941return true;2942return this->emitConstBool(E->isSatisfied(), E);2943}29442945template <class Emitter>2946bool Compiler<Emitter>::VisitConceptSpecializationExpr(2947const ConceptSpecializationExpr *E) {2948assert(classifyPrim(E->getType()) == PT_Bool);2949if (DiscardResult)2950return true;2951return this->emitConstBool(E->isSatisfied(), E);2952}29532954template <class Emitter>2955bool Compiler<Emitter>::VisitCXXRewrittenBinaryOperator(2956const CXXRewrittenBinaryOperator *E) {2957return this->delegate(E->getSemanticForm());2958}29592960template <class Emitter>2961bool Compiler<Emitter>::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {29622963for (const Expr *SemE : E->semantics()) {2964if (auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {2965if (SemE == E->getResultExpr())2966return false;29672968if (OVE->isUnique())2969continue;29702971if (!this->discard(OVE))2972return false;2973} else if (SemE == E->getResultExpr()) {2974if (!this->delegate(SemE))2975return false;2976} else {2977if (!this->discard(SemE))2978return false;2979}2980}2981return true;2982}29832984template <class Emitter>2985bool Compiler<Emitter>::VisitPackIndexingExpr(const PackIndexingExpr *E) {2986return this->delegate(E->getSelectedExpr());2987}29882989template <class Emitter>2990bool Compiler<Emitter>::VisitRecoveryExpr(const RecoveryExpr *E) {2991return this->emitError(E);2992}29932994template <class Emitter>2995bool Compiler<Emitter>::VisitAddrLabelExpr(const AddrLabelExpr *E) {2996assert(E->getType()->isVoidPointerType());29972998unsigned Offset = allocateLocalPrimitive(2999E->getLabel(), PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false);30003001return this->emitGetLocal(PT_Ptr, Offset, E);3002}30033004template <class Emitter>3005bool Compiler<Emitter>::VisitConvertVectorExpr(const ConvertVectorExpr *E) {3006assert(Initializing);3007const auto *VT = E->getType()->castAs<VectorType>();3008QualType ElemType = VT->getElementType();3009PrimType ElemT = classifyPrim(ElemType);3010const Expr *Src = E->getSrcExpr();3011PrimType SrcElemT =3012classifyPrim(Src->getType()->castAs<VectorType>()->getElementType());30133014unsigned SrcOffset = this->allocateLocalPrimitive(Src, PT_Ptr, true, false);3015if (!this->visit(Src))3016return false;3017if (!this->emitSetLocal(PT_Ptr, SrcOffset, E))3018return false;30193020for (unsigned I = 0; I != VT->getNumElements(); ++I) {3021if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))3022return false;3023if (!this->emitArrayElemPop(SrcElemT, I, E))3024return false;3025if (SrcElemT != ElemT) {3026if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))3027return false;3028}3029if (!this->emitInitElem(ElemT, I, E))3030return false;3031}30323033return true;3034}30353036template <class Emitter>3037bool Compiler<Emitter>::VisitShuffleVectorExpr(const ShuffleVectorExpr *E) {3038assert(Initializing);3039assert(E->getNumSubExprs() > 2);30403041const Expr *Vecs[] = {E->getExpr(0), E->getExpr(1)};3042const VectorType *VT = Vecs[0]->getType()->castAs<VectorType>();3043PrimType ElemT = classifyPrim(VT->getElementType());3044unsigned NumInputElems = VT->getNumElements();3045unsigned NumOutputElems = E->getNumSubExprs() - 2;3046assert(NumOutputElems > 0);30473048// Save both input vectors to a local variable.3049unsigned VectorOffsets[2];3050for (unsigned I = 0; I != 2; ++I) {3051VectorOffsets[I] = this->allocateLocalPrimitive(3052Vecs[I], PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false);3053if (!this->visit(Vecs[I]))3054return false;3055if (!this->emitSetLocal(PT_Ptr, VectorOffsets[I], E))3056return false;3057}3058for (unsigned I = 0; I != NumOutputElems; ++I) {3059APSInt ShuffleIndex = E->getShuffleMaskIdx(Ctx.getASTContext(), I);3060if (ShuffleIndex == -1)3061return this->emitInvalid(E); // FIXME: Better diagnostic.30623063assert(ShuffleIndex < (NumInputElems * 2));3064if (!this->emitGetLocal(PT_Ptr,3065VectorOffsets[ShuffleIndex >= NumInputElems], E))3066return false;3067unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;3068if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))3069return false;30703071if (!this->emitInitElem(ElemT, I, E))3072return false;3073}30743075return true;3076}30773078template <class Emitter>3079bool Compiler<Emitter>::VisitExtVectorElementExpr(3080const ExtVectorElementExpr *E) {3081const Expr *Base = E->getBase();3082assert(3083Base->getType()->isVectorType() ||3084Base->getType()->getAs<PointerType>()->getPointeeType()->isVectorType());30853086SmallVector<uint32_t, 4> Indices;3087E->getEncodedElementAccess(Indices);30883089if (Indices.size() == 1) {3090if (!this->visit(Base))3091return false;30923093if (E->isGLValue()) {3094if (!this->emitConstUint32(Indices[0], E))3095return false;3096return this->emitArrayElemPtrPop(PT_Uint32, E);3097}3098// Else, also load the value.3099return this->emitArrayElemPop(classifyPrim(E->getType()), Indices[0], E);3100}31013102// Create a local variable for the base.3103unsigned BaseOffset = allocateLocalPrimitive(Base, PT_Ptr, /*IsConst=*/true,3104/*IsExtended=*/false);3105if (!this->visit(Base))3106return false;3107if (!this->emitSetLocal(PT_Ptr, BaseOffset, E))3108return false;31093110// Now the vector variable for the return value.3111if (!Initializing) {3112std::optional<unsigned> ResultIndex;3113ResultIndex = allocateLocal(E);3114if (!ResultIndex)3115return false;3116if (!this->emitGetPtrLocal(*ResultIndex, E))3117return false;3118}31193120assert(Indices.size() == E->getType()->getAs<VectorType>()->getNumElements());31213122PrimType ElemT =3123classifyPrim(E->getType()->getAs<VectorType>()->getElementType());3124uint32_t DstIndex = 0;3125for (uint32_t I : Indices) {3126if (!this->emitGetLocal(PT_Ptr, BaseOffset, E))3127return false;3128if (!this->emitArrayElemPop(ElemT, I, E))3129return false;3130if (!this->emitInitElem(ElemT, DstIndex, E))3131return false;3132++DstIndex;3133}31343135// Leave the result pointer on the stack.3136assert(!DiscardResult);3137return true;3138}31393140template <class Emitter>3141bool Compiler<Emitter>::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {3142if (!E->isExpressibleAsConstantInitializer())3143return this->emitInvalid(E);31443145return this->delegate(E->getSubExpr());3146}31473148template <class Emitter>3149bool Compiler<Emitter>::VisitCXXStdInitializerListExpr(3150const CXXStdInitializerListExpr *E) {3151const Expr *SubExpr = E->getSubExpr();3152const ConstantArrayType *ArrayType =3153Ctx.getASTContext().getAsConstantArrayType(SubExpr->getType());3154const Record *R = getRecord(E->getType());3155assert(Initializing);3156assert(SubExpr->isGLValue());31573158if (!this->visit(SubExpr))3159return false;3160if (!this->emitInitFieldPtr(R->getField(0u)->Offset, E))3161return false;31623163PrimType SecondFieldT = classifyPrim(R->getField(1u)->Decl->getType());3164if (isIntegralType(SecondFieldT)) {3165if (!this->emitConst(static_cast<APSInt>(ArrayType->getSize()),3166SecondFieldT, E))3167return false;3168return this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E);3169}3170assert(SecondFieldT == PT_Ptr);31713172if (!this->emitGetFieldPtr(R->getField(0u)->Offset, E))3173return false;3174if (!this->emitConst(static_cast<APSInt>(ArrayType->getSize()), PT_Uint64, E))3175return false;3176if (!this->emitArrayElemPtrPop(PT_Uint64, E))3177return false;3178return this->emitInitFieldPtr(R->getField(1u)->Offset, E);3179}31803181template <class Emitter>3182bool Compiler<Emitter>::VisitStmtExpr(const StmtExpr *E) {3183BlockScope<Emitter> BS(this);3184StmtExprScope<Emitter> SS(this);31853186const CompoundStmt *CS = E->getSubStmt();3187const Stmt *Result = CS->getStmtExprResult();3188for (const Stmt *S : CS->body()) {3189if (S != Result) {3190if (!this->visitStmt(S))3191return false;3192continue;3193}31943195assert(S == Result);3196if (const Expr *ResultExpr = dyn_cast<Expr>(S)) {3197if (DiscardResult)3198return this->discard(ResultExpr);3199return this->delegate(ResultExpr);3200}32013202return this->visitStmt(S);3203}32043205return BS.destroyLocals();3206}32073208template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {3209OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,3210/*NewInitializing=*/false);3211return this->Visit(E);3212}32133214template <class Emitter> bool Compiler<Emitter>::delegate(const Expr *E) {3215if (E->containsErrors())3216return this->emitError(E);32173218// We're basically doing:3219// OptionScope<Emitter> Scope(this, DicardResult, Initializing);3220// but that's unnecessary of course.3221return this->Visit(E);3222}32233224template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) {3225if (E->getType().isNull())3226return false;32273228if (E->getType()->isVoidType())3229return this->discard(E);32303231// Create local variable to hold the return value.3232if (!E->isGLValue() && !E->getType()->isAnyComplexType() &&3233!classify(E->getType())) {3234std::optional<unsigned> LocalIndex = allocateLocal(E);3235if (!LocalIndex)3236return false;32373238if (!this->emitGetPtrLocal(*LocalIndex, E))3239return false;3240return this->visitInitializer(E);3241}32423243// Otherwise,we have a primitive return value, produce the value directly3244// and push it on the stack.3245OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,3246/*NewInitializing=*/false);3247return this->Visit(E);3248}32493250template <class Emitter>3251bool Compiler<Emitter>::visitInitializer(const Expr *E) {3252assert(!classify(E->getType()));32533254if (E->containsErrors())3255return this->emitError(E);32563257OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,3258/*NewInitializing=*/true);3259return this->Visit(E);3260}32613262template <class Emitter> bool Compiler<Emitter>::visitBool(const Expr *E) {3263std::optional<PrimType> T = classify(E->getType());3264if (!T) {3265// Convert complex values to bool.3266if (E->getType()->isAnyComplexType()) {3267if (!this->visit(E))3268return false;3269return this->emitComplexBoolCast(E);3270}3271return false;3272}32733274if (!this->visit(E))3275return false;32763277if (T == PT_Bool)3278return true;32793280// Convert pointers to bool.3281if (T == PT_Ptr || T == PT_FnPtr) {3282if (!this->emitNull(*T, nullptr, E))3283return false;3284return this->emitNE(*T, E);3285}32863287// Or Floats.3288if (T == PT_Float)3289return this->emitCastFloatingIntegralBool(E);32903291// Or anything else we can.3292return this->emitCast(*T, PT_Bool, E);3293}32943295template <class Emitter>3296bool Compiler<Emitter>::visitZeroInitializer(PrimType T, QualType QT,3297const Expr *E) {3298switch (T) {3299case PT_Bool:3300return this->emitZeroBool(E);3301case PT_Sint8:3302return this->emitZeroSint8(E);3303case PT_Uint8:3304return this->emitZeroUint8(E);3305case PT_Sint16:3306return this->emitZeroSint16(E);3307case PT_Uint16:3308return this->emitZeroUint16(E);3309case PT_Sint32:3310return this->emitZeroSint32(E);3311case PT_Uint32:3312return this->emitZeroUint32(E);3313case PT_Sint64:3314return this->emitZeroSint64(E);3315case PT_Uint64:3316return this->emitZeroUint64(E);3317case PT_IntAP:3318return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);3319case PT_IntAPS:3320return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);3321case PT_Ptr:3322return this->emitNullPtr(nullptr, E);3323case PT_FnPtr:3324return this->emitNullFnPtr(nullptr, E);3325case PT_MemberPtr:3326return this->emitNullMemberPtr(nullptr, E);3327case PT_Float: {3328return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E);3329}3330}3331llvm_unreachable("unknown primitive type");3332}33333334template <class Emitter>3335bool Compiler<Emitter>::visitZeroRecordInitializer(const Record *R,3336const Expr *E) {3337assert(E);3338assert(R);3339// Fields3340for (const Record::Field &Field : R->fields()) {3341const Descriptor *D = Field.Desc;3342if (D->isPrimitive()) {3343QualType QT = D->getType();3344PrimType T = classifyPrim(D->getType());3345if (!this->visitZeroInitializer(T, QT, E))3346return false;3347if (!this->emitInitField(T, Field.Offset, E))3348return false;3349continue;3350}33513352if (!this->emitGetPtrField(Field.Offset, E))3353return false;33543355if (D->isPrimitiveArray()) {3356QualType ET = D->getElemQualType();3357PrimType T = classifyPrim(ET);3358for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {3359if (!this->visitZeroInitializer(T, ET, E))3360return false;3361if (!this->emitInitElem(T, I, E))3362return false;3363}3364} else if (D->isCompositeArray()) {3365const Record *ElemRecord = D->ElemDesc->ElemRecord;3366assert(D->ElemDesc->ElemRecord);3367for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {3368if (!this->emitConstUint32(I, E))3369return false;3370if (!this->emitArrayElemPtr(PT_Uint32, E))3371return false;3372if (!this->visitZeroRecordInitializer(ElemRecord, E))3373return false;3374if (!this->emitPopPtr(E))3375return false;3376}3377} else if (D->isRecord()) {3378if (!this->visitZeroRecordInitializer(D->ElemRecord, E))3379return false;3380} else {3381assert(false);3382}33833384if (!this->emitPopPtr(E))3385return false;3386}33873388for (const Record::Base &B : R->bases()) {3389if (!this->emitGetPtrBase(B.Offset, E))3390return false;3391if (!this->visitZeroRecordInitializer(B.R, E))3392return false;3393if (!this->emitFinishInitPop(E))3394return false;3395}33963397// FIXME: Virtual bases.33983399return true;3400}34013402template <class Emitter>3403template <typename T>3404bool Compiler<Emitter>::emitConst(T Value, PrimType Ty, const Expr *E) {3405switch (Ty) {3406case PT_Sint8:3407return this->emitConstSint8(Value, E);3408case PT_Uint8:3409return this->emitConstUint8(Value, E);3410case PT_Sint16:3411return this->emitConstSint16(Value, E);3412case PT_Uint16:3413return this->emitConstUint16(Value, E);3414case PT_Sint32:3415return this->emitConstSint32(Value, E);3416case PT_Uint32:3417return this->emitConstUint32(Value, E);3418case PT_Sint64:3419return this->emitConstSint64(Value, E);3420case PT_Uint64:3421return this->emitConstUint64(Value, E);3422case PT_Bool:3423return this->emitConstBool(Value, E);3424case PT_Ptr:3425case PT_FnPtr:3426case PT_MemberPtr:3427case PT_Float:3428case PT_IntAP:3429case PT_IntAPS:3430llvm_unreachable("Invalid integral type");3431break;3432}3433llvm_unreachable("unknown primitive type");3434}34353436template <class Emitter>3437template <typename T>3438bool Compiler<Emitter>::emitConst(T Value, const Expr *E) {3439return this->emitConst(Value, classifyPrim(E->getType()), E);3440}34413442template <class Emitter>3443bool Compiler<Emitter>::emitConst(const APSInt &Value, PrimType Ty,3444const Expr *E) {3445if (Ty == PT_IntAPS)3446return this->emitConstIntAPS(Value, E);3447if (Ty == PT_IntAP)3448return this->emitConstIntAP(Value, E);34493450if (Value.isSigned())3451return this->emitConst(Value.getSExtValue(), Ty, E);3452return this->emitConst(Value.getZExtValue(), Ty, E);3453}34543455template <class Emitter>3456bool Compiler<Emitter>::emitConst(const APSInt &Value, const Expr *E) {3457return this->emitConst(Value, classifyPrim(E->getType()), E);3458}34593460template <class Emitter>3461unsigned Compiler<Emitter>::allocateLocalPrimitive(DeclTy &&Src, PrimType Ty,3462bool IsConst,3463bool IsExtended) {3464// Make sure we don't accidentally register the same decl twice.3465if (const auto *VD =3466dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {3467assert(!P.getGlobal(VD));3468assert(!Locals.contains(VD));3469(void)VD;3470}34713472// FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.3473// (int){12} in C. Consider using Expr::isTemporaryObject() instead3474// or isa<MaterializeTemporaryExpr>().3475Descriptor *D = P.createDescriptor(Src, Ty, Descriptor::InlineDescMD, IsConst,3476Src.is<const Expr *>());3477Scope::Local Local = this->createLocal(D);3478if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>()))3479Locals.insert({VD, Local});3480VarScope->add(Local, IsExtended);3481return Local.Offset;3482}34833484template <class Emitter>3485std::optional<unsigned>3486Compiler<Emitter>::allocateLocal(DeclTy &&Src, const ValueDecl *ExtendingDecl) {3487// Make sure we don't accidentally register the same decl twice.3488if ([[maybe_unused]] const auto *VD =3489dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {3490assert(!P.getGlobal(VD));3491assert(!Locals.contains(VD));3492}34933494QualType Ty;3495const ValueDecl *Key = nullptr;3496const Expr *Init = nullptr;3497bool IsTemporary = false;3498if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {3499Key = VD;3500Ty = VD->getType();35013502if (const auto *VarD = dyn_cast<VarDecl>(VD))3503Init = VarD->getInit();3504}3505if (auto *E = Src.dyn_cast<const Expr *>()) {3506IsTemporary = true;3507Ty = E->getType();3508}35093510Descriptor *D = P.createDescriptor(3511Src, Ty.getTypePtr(), Descriptor::InlineDescMD, Ty.isConstQualified(),3512IsTemporary, /*IsMutable=*/false, Init);3513if (!D)3514return std::nullopt;35153516Scope::Local Local = this->createLocal(D);3517if (Key)3518Locals.insert({Key, Local});3519if (ExtendingDecl)3520VarScope->addExtended(Local, ExtendingDecl);3521else3522VarScope->add(Local, false);3523return Local.Offset;3524}35253526template <class Emitter>3527const RecordType *Compiler<Emitter>::getRecordTy(QualType Ty) {3528if (const PointerType *PT = dyn_cast<PointerType>(Ty))3529return PT->getPointeeType()->getAs<RecordType>();3530return Ty->getAs<RecordType>();3531}35323533template <class Emitter> Record *Compiler<Emitter>::getRecord(QualType Ty) {3534if (const auto *RecordTy = getRecordTy(Ty))3535return getRecord(RecordTy->getDecl());3536return nullptr;3537}35383539template <class Emitter>3540Record *Compiler<Emitter>::getRecord(const RecordDecl *RD) {3541return P.getOrCreateRecord(RD);3542}35433544template <class Emitter>3545const Function *Compiler<Emitter>::getFunction(const FunctionDecl *FD) {3546return Ctx.getOrCreateFunction(FD);3547}35483549template <class Emitter> bool Compiler<Emitter>::visitExpr(const Expr *E) {3550LocalScope<Emitter> RootScope(this);3551// Void expressions.3552if (E->getType()->isVoidType()) {3553if (!visit(E))3554return false;3555return this->emitRetVoid(E) && RootScope.destroyLocals();3556}35573558// Expressions with a primitive return type.3559if (std::optional<PrimType> T = classify(E)) {3560if (!visit(E))3561return false;3562return this->emitRet(*T, E) && RootScope.destroyLocals();3563}35643565// Expressions with a composite return type.3566// For us, that means everything we don't3567// have a PrimType for.3568if (std::optional<unsigned> LocalOffset = this->allocateLocal(E)) {3569if (!this->emitGetPtrLocal(*LocalOffset, E))3570return false;35713572if (!visitInitializer(E))3573return false;35743575if (!this->emitFinishInit(E))3576return false;3577// We are destroying the locals AFTER the Ret op.3578// The Ret op needs to copy the (alive) values, but the3579// destructors may still turn the entire expression invalid.3580return this->emitRetValue(E) && RootScope.destroyLocals();3581}35823583RootScope.destroyLocals();3584return false;3585}35863587template <class Emitter>3588VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD) {35893590auto R = this->visitVarDecl(VD, /*Toplevel=*/true);35913592if (R.notCreated())3593return R;35943595if (R)3596return true;35973598if (!R && Context::shouldBeGloballyIndexed(VD)) {3599if (auto GlobalIndex = P.getGlobal(VD)) {3600Block *GlobalBlock = P.getGlobal(*GlobalIndex);3601GlobalInlineDescriptor &GD =3602*reinterpret_cast<GlobalInlineDescriptor *>(GlobalBlock->rawData());36033604GD.InitState = GlobalInitState::InitializerFailed;3605GlobalBlock->invokeDtor();3606}3607}36083609return R;3610}36113612/// Toplevel visitDeclAndReturn().3613/// We get here from evaluateAsInitializer().3614/// We need to evaluate the initializer and return its value.3615template <class Emitter>3616bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,3617bool ConstantContext) {3618std::optional<PrimType> VarT = classify(VD->getType());36193620// We only create variables if we're evaluating in a constant context.3621// Otherwise, just evaluate the initializer and return it.3622if (!ConstantContext) {3623DeclScope<Emitter> LS(this, VD);3624if (!this->visit(VD->getAnyInitializer()))3625return false;3626return this->emitRet(VarT.value_or(PT_Ptr), VD) && LS.destroyLocals();3627}36283629LocalScope<Emitter> VDScope(this, VD);3630if (!this->visitVarDecl(VD, /*Toplevel=*/true))3631return false;36323633if (Context::shouldBeGloballyIndexed(VD)) {3634auto GlobalIndex = P.getGlobal(VD);3635assert(GlobalIndex); // visitVarDecl() didn't return false.3636if (VarT) {3637if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))3638return false;3639} else {3640if (!this->emitGetPtrGlobal(*GlobalIndex, VD))3641return false;3642}3643} else {3644auto Local = Locals.find(VD);3645assert(Local != Locals.end()); // Same here.3646if (VarT) {3647if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))3648return false;3649} else {3650if (!this->emitGetPtrLocal(Local->second.Offset, VD))3651return false;3652}3653}36543655// Return the value.3656if (!this->emitRet(VarT.value_or(PT_Ptr), VD)) {3657// If the Ret above failed and this is a global variable, mark it as3658// uninitialized, even everything else succeeded.3659if (Context::shouldBeGloballyIndexed(VD)) {3660auto GlobalIndex = P.getGlobal(VD);3661assert(GlobalIndex);3662Block *GlobalBlock = P.getGlobal(*GlobalIndex);3663GlobalInlineDescriptor &GD =3664*reinterpret_cast<GlobalInlineDescriptor *>(GlobalBlock->rawData());36653666GD.InitState = GlobalInitState::InitializerFailed;3667GlobalBlock->invokeDtor();3668}3669return false;3670}36713672return VDScope.destroyLocals();3673}36743675template <class Emitter>3676VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD, bool Toplevel) {3677// We don't know what to do with these, so just return false.3678if (VD->getType().isNull())3679return false;36803681// This case is EvalEmitter-only. If we won't create any instructions for the3682// initializer anyway, don't bother creating the variable in the first place.3683if (!this->isActive())3684return VarCreationState::NotCreated();36853686const Expr *Init = VD->getInit();3687std::optional<PrimType> VarT = classify(VD->getType());36883689if (Context::shouldBeGloballyIndexed(VD)) {3690auto checkDecl = [&]() -> bool {3691bool NeedsOp = !Toplevel && VD->isLocalVarDecl() && VD->isStaticLocal();3692return !NeedsOp || this->emitCheckDecl(VD, VD);3693};36943695auto initGlobal = [&](unsigned GlobalIndex) -> bool {3696assert(Init);3697DeclScope<Emitter> LocalScope(this, VD);36983699if (VarT) {3700if (!this->visit(Init))3701return checkDecl() && false;37023703return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);3704}37053706if (!checkDecl())3707return false;37083709if (!this->emitGetPtrGlobal(GlobalIndex, Init))3710return false;37113712if (!visitInitializer(Init))3713return false;37143715if (!this->emitFinishInit(Init))3716return false;37173718return this->emitPopPtr(Init);3719};37203721// We've already seen and initialized this global.3722if (std::optional<unsigned> GlobalIndex = P.getGlobal(VD)) {3723if (P.getPtrGlobal(*GlobalIndex).isInitialized())3724return checkDecl();37253726// The previous attempt at initialization might've been unsuccessful,3727// so let's try this one.3728return Init && checkDecl() && initGlobal(*GlobalIndex);3729}37303731std::optional<unsigned> GlobalIndex = P.createGlobal(VD, Init);37323733if (!GlobalIndex)3734return false;37353736return !Init || (checkDecl() && initGlobal(*GlobalIndex));3737} else {3738InitLinkScope<Emitter> ILS(this, InitLink::Decl(VD));37393740if (VarT) {3741unsigned Offset = this->allocateLocalPrimitive(3742VD, *VarT, VD->getType().isConstQualified());3743if (Init) {3744// If this is a toplevel declaration, create a scope for the3745// initializer.3746if (Toplevel) {3747LocalScope<Emitter> Scope(this);3748if (!this->visit(Init))3749return false;3750return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals();3751} else {3752if (!this->visit(Init))3753return false;3754return this->emitSetLocal(*VarT, Offset, VD);3755}3756}3757} else {3758if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {3759if (!Init)3760return true;37613762if (!this->emitGetPtrLocal(*Offset, Init))3763return false;37643765if (!visitInitializer(Init))3766return false;37673768if (!this->emitFinishInit(Init))3769return false;37703771return this->emitPopPtr(Init);3772}3773return false;3774}3775return true;3776}37773778return false;3779}37803781template <class Emitter>3782bool Compiler<Emitter>::visitAPValue(const APValue &Val, PrimType ValType,3783const Expr *E) {3784assert(!DiscardResult);3785if (Val.isInt())3786return this->emitConst(Val.getInt(), ValType, E);3787else if (Val.isFloat())3788return this->emitConstFloat(Val.getFloat(), E);37893790if (Val.isLValue()) {3791if (Val.isNullPointer())3792return this->emitNull(ValType, nullptr, E);3793APValue::LValueBase Base = Val.getLValueBase();3794if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>())3795return this->visit(BaseExpr);3796else if (const auto *VD = Base.dyn_cast<const ValueDecl *>()) {3797return this->visitDeclRef(VD, E);3798}3799} else if (Val.isMemberPointer()) {3800if (const ValueDecl *MemberDecl = Val.getMemberPointerDecl())3801return this->emitGetMemberPtr(MemberDecl, E);3802return this->emitNullMemberPtr(nullptr, E);3803}38043805return false;3806}38073808template <class Emitter>3809bool Compiler<Emitter>::visitAPValueInitializer(const APValue &Val,3810const Expr *E) {38113812if (Val.isStruct()) {3813const Record *R = this->getRecord(E->getType());3814assert(R);3815for (unsigned I = 0, N = Val.getStructNumFields(); I != N; ++I) {3816const APValue &F = Val.getStructField(I);3817const Record::Field *RF = R->getField(I);38183819if (F.isInt() || F.isFloat() || F.isLValue() || F.isMemberPointer()) {3820PrimType T = classifyPrim(RF->Decl->getType());3821if (!this->visitAPValue(F, T, E))3822return false;3823if (!this->emitInitField(T, RF->Offset, E))3824return false;3825} else if (F.isArray()) {3826assert(RF->Desc->isPrimitiveArray());3827const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();3828PrimType ElemT = classifyPrim(ArrType->getElementType());3829assert(ArrType);38303831if (!this->emitGetPtrField(RF->Offset, E))3832return false;38333834for (unsigned A = 0, AN = F.getArraySize(); A != AN; ++A) {3835if (!this->visitAPValue(F.getArrayInitializedElt(A), ElemT, E))3836return false;3837if (!this->emitInitElem(ElemT, A, E))3838return false;3839}38403841if (!this->emitPopPtr(E))3842return false;3843} else if (F.isStruct() || F.isUnion()) {3844if (!this->emitGetPtrField(RF->Offset, E))3845return false;3846if (!this->visitAPValueInitializer(F, E))3847return false;3848if (!this->emitPopPtr(E))3849return false;3850} else {3851assert(false && "I don't think this should be possible");3852}3853}3854return true;3855} else if (Val.isUnion()) {3856const FieldDecl *UnionField = Val.getUnionField();3857const Record *R = this->getRecord(UnionField->getParent());3858assert(R);3859const APValue &F = Val.getUnionValue();3860const Record::Field *RF = R->getField(UnionField);3861PrimType T = classifyPrim(RF->Decl->getType());3862if (!this->visitAPValue(F, T, E))3863return false;3864return this->emitInitField(T, RF->Offset, E);3865}3866// TODO: Other types.38673868return false;3869}38703871template <class Emitter>3872bool Compiler<Emitter>::VisitBuiltinCallExpr(const CallExpr *E) {3873const Function *Func = getFunction(E->getDirectCallee());3874if (!Func)3875return false;38763877// For these, we're expected to ultimately return an APValue pointing3878// to the CallExpr. This is needed to get the correct codegen.3879unsigned Builtin = E->getBuiltinCallee();3880if (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||3881Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||3882Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||3883Builtin == Builtin::BI__builtin_function_start) {3884if (std::optional<unsigned> GlobalOffset = P.createGlobal(E)) {3885if (!this->emitGetPtrGlobal(*GlobalOffset, E))3886return false;38873888if (PrimType PT = classifyPrim(E); PT != PT_Ptr && isPtrType(PT))3889return this->emitDecayPtr(PT_Ptr, PT, E);3890return true;3891}3892return false;3893}38943895QualType ReturnType = E->getType();3896std::optional<PrimType> ReturnT = classify(E);38973898// Non-primitive return type. Prepare storage.3899if (!Initializing && !ReturnT && !ReturnType->isVoidType()) {3900std::optional<unsigned> LocalIndex = allocateLocal(E);3901if (!LocalIndex)3902return false;3903if (!this->emitGetPtrLocal(*LocalIndex, E))3904return false;3905}39063907if (!Func->isUnevaluatedBuiltin()) {3908// Put arguments on the stack.3909for (const auto *Arg : E->arguments()) {3910if (!this->visit(Arg))3911return false;3912}3913}39143915if (!this->emitCallBI(Func, E, E))3916return false;39173918if (DiscardResult && !ReturnType->isVoidType()) {3919assert(ReturnT);3920return this->emitPop(*ReturnT, E);3921}39223923return true;3924}39253926template <class Emitter>3927bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {3928if (E->getBuiltinCallee())3929return VisitBuiltinCallExpr(E);39303931QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());3932std::optional<PrimType> T = classify(ReturnType);3933bool HasRVO = !ReturnType->isVoidType() && !T;3934const FunctionDecl *FuncDecl = E->getDirectCallee();39353936if (HasRVO) {3937if (DiscardResult) {3938// If we need to discard the return value but the function returns its3939// value via an RVO pointer, we need to create one such pointer just3940// for this call.3941if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {3942if (!this->emitGetPtrLocal(*LocalIndex, E))3943return false;3944}3945} else {3946// We need the result. Prepare a pointer to return or3947// dup the current one.3948if (!Initializing) {3949if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {3950if (!this->emitGetPtrLocal(*LocalIndex, E))3951return false;3952}3953}3954if (!this->emitDupPtr(E))3955return false;3956}3957}39583959auto Args = llvm::ArrayRef(E->getArgs(), E->getNumArgs());3960// Calling a static operator will still3961// pass the instance, but we don't need it.3962// Discard it here.3963if (isa<CXXOperatorCallExpr>(E)) {3964if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);3965MD && MD->isStatic()) {3966if (!this->discard(E->getArg(0)))3967return false;3968Args = Args.drop_front();3969}3970}39713972std::optional<unsigned> CalleeOffset;3973// Add the (optional, implicit) This pointer.3974if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {3975if (!FuncDecl && classifyPrim(E->getCallee()) == PT_MemberPtr) {3976// If we end up creating a CallPtr op for this, we need the base of the3977// member pointer as the instance pointer, and later extract the function3978// decl as the function pointer.3979const Expr *Callee = E->getCallee();3980CalleeOffset =3981this->allocateLocalPrimitive(Callee, PT_MemberPtr, true, false);3982if (!this->visit(Callee))3983return false;3984if (!this->emitSetLocal(PT_MemberPtr, *CalleeOffset, E))3985return false;3986if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))3987return false;3988if (!this->emitGetMemberPtrBase(E))3989return false;3990} else if (!this->visit(MC->getImplicitObjectArgument())) {3991return false;3992}3993}39943995llvm::BitVector NonNullArgs = collectNonNullArgs(FuncDecl, Args);3996// Put arguments on the stack.3997unsigned ArgIndex = 0;3998for (const auto *Arg : Args) {3999if (!this->visit(Arg))4000return false;40014002// If we know the callee already, check the known parametrs for nullability.4003if (FuncDecl && NonNullArgs[ArgIndex]) {4004PrimType ArgT = classify(Arg).value_or(PT_Ptr);4005if (ArgT == PT_Ptr || ArgT == PT_FnPtr) {4006if (!this->emitCheckNonNullArg(ArgT, Arg))4007return false;4008}4009}4010++ArgIndex;4011}40124013if (FuncDecl) {4014const Function *Func = getFunction(FuncDecl);4015if (!Func)4016return false;4017assert(HasRVO == Func->hasRVO());40184019bool HasQualifier = false;4020if (const auto *ME = dyn_cast<MemberExpr>(E->getCallee()))4021HasQualifier = ME->hasQualifier();40224023bool IsVirtual = false;4024if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))4025IsVirtual = MD->isVirtual();40264027// In any case call the function. The return value will end up on the stack4028// and if the function has RVO, we already have the pointer on the stack to4029// write the result into.4030if (IsVirtual && !HasQualifier) {4031uint32_t VarArgSize = 0;4032unsigned NumParams =4033Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(E);4034for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)4035VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));40364037if (!this->emitCallVirt(Func, VarArgSize, E))4038return false;4039} else if (Func->isVariadic()) {4040uint32_t VarArgSize = 0;4041unsigned NumParams =4042Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(E);4043for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)4044VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));4045if (!this->emitCallVar(Func, VarArgSize, E))4046return false;4047} else {4048if (!this->emitCall(Func, 0, E))4049return false;4050}4051} else {4052// Indirect call. Visit the callee, which will leave a FunctionPointer on4053// the stack. Cleanup of the returned value if necessary will be done after4054// the function call completed.40554056// Sum the size of all args from the call expr.4057uint32_t ArgSize = 0;4058for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)4059ArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));40604061// Get the callee, either from a member pointer saved in CalleeOffset,4062// or by just visiting the Callee expr.4063if (CalleeOffset) {4064if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))4065return false;4066if (!this->emitGetMemberPtrDecl(E))4067return false;4068if (!this->emitCallPtr(ArgSize, E, E))4069return false;4070} else {4071if (!this->visit(E->getCallee()))4072return false;40734074if (!this->emitCallPtr(ArgSize, E, E))4075return false;4076}4077}40784079// Cleanup for discarded return values.4080if (DiscardResult && !ReturnType->isVoidType() && T)4081return this->emitPop(*T, E);40824083return true;4084}40854086template <class Emitter>4087bool Compiler<Emitter>::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) {4088SourceLocScope<Emitter> SLS(this, E);40894090return this->delegate(E->getExpr());4091}40924093template <class Emitter>4094bool Compiler<Emitter>::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) {4095SourceLocScope<Emitter> SLS(this, E);40964097const Expr *SubExpr = E->getExpr();4098if (std::optional<PrimType> T = classify(E->getExpr()))4099return this->visit(SubExpr);41004101assert(Initializing);4102return this->visitInitializer(SubExpr);4103}41044105template <class Emitter>4106bool Compiler<Emitter>::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {4107if (DiscardResult)4108return true;41094110return this->emitConstBool(E->getValue(), E);4111}41124113template <class Emitter>4114bool Compiler<Emitter>::VisitCXXNullPtrLiteralExpr(4115const CXXNullPtrLiteralExpr *E) {4116if (DiscardResult)4117return true;41184119return this->emitNullPtr(nullptr, E);4120}41214122template <class Emitter>4123bool Compiler<Emitter>::VisitGNUNullExpr(const GNUNullExpr *E) {4124if (DiscardResult)4125return true;41264127assert(E->getType()->isIntegerType());41284129PrimType T = classifyPrim(E->getType());4130return this->emitZero(T, E);4131}41324133template <class Emitter>4134bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {4135if (DiscardResult)4136return true;41374138if (this->LambdaThisCapture.Offset > 0) {4139if (this->LambdaThisCapture.IsPtr)4140return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);4141return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);4142}41434144// In some circumstances, the 'this' pointer does not actually refer to the4145// instance pointer of the current function frame, but e.g. to the declaration4146// currently being initialized. Here we emit the necessary instruction(s) for4147// this scenario.4148if (!InitStackActive || !E->isImplicit())4149return this->emitThis(E);41504151if (InitStackActive && !InitStack.empty()) {4152unsigned StartIndex = 0;4153for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {4154if (InitStack[StartIndex].Kind != InitLink::K_Field)4155break;4156}41574158for (unsigned I = StartIndex, N = InitStack.size(); I != N; ++I) {4159if (!InitStack[I].template emit<Emitter>(this, E))4160return false;4161}4162return true;4163}4164return this->emitThis(E);4165}41664167template <class Emitter> bool Compiler<Emitter>::visitStmt(const Stmt *S) {4168switch (S->getStmtClass()) {4169case Stmt::CompoundStmtClass:4170return visitCompoundStmt(cast<CompoundStmt>(S));4171case Stmt::DeclStmtClass:4172return visitDeclStmt(cast<DeclStmt>(S));4173case Stmt::ReturnStmtClass:4174return visitReturnStmt(cast<ReturnStmt>(S));4175case Stmt::IfStmtClass:4176return visitIfStmt(cast<IfStmt>(S));4177case Stmt::WhileStmtClass:4178return visitWhileStmt(cast<WhileStmt>(S));4179case Stmt::DoStmtClass:4180return visitDoStmt(cast<DoStmt>(S));4181case Stmt::ForStmtClass:4182return visitForStmt(cast<ForStmt>(S));4183case Stmt::CXXForRangeStmtClass:4184return visitCXXForRangeStmt(cast<CXXForRangeStmt>(S));4185case Stmt::BreakStmtClass:4186return visitBreakStmt(cast<BreakStmt>(S));4187case Stmt::ContinueStmtClass:4188return visitContinueStmt(cast<ContinueStmt>(S));4189case Stmt::SwitchStmtClass:4190return visitSwitchStmt(cast<SwitchStmt>(S));4191case Stmt::CaseStmtClass:4192return visitCaseStmt(cast<CaseStmt>(S));4193case Stmt::DefaultStmtClass:4194return visitDefaultStmt(cast<DefaultStmt>(S));4195case Stmt::AttributedStmtClass:4196return visitAttributedStmt(cast<AttributedStmt>(S));4197case Stmt::CXXTryStmtClass:4198return visitCXXTryStmt(cast<CXXTryStmt>(S));4199case Stmt::NullStmtClass:4200return true;4201// Always invalid statements.4202case Stmt::GCCAsmStmtClass:4203case Stmt::MSAsmStmtClass:4204case Stmt::GotoStmtClass:4205return this->emitInvalid(S);4206case Stmt::LabelStmtClass:4207return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());4208default: {4209if (const auto *E = dyn_cast<Expr>(S))4210return this->discard(E);4211return false;4212}4213}4214}42154216/// Visits the given statment without creating a variable4217/// scope for it in case it is a compound statement.4218template <class Emitter> bool Compiler<Emitter>::visitLoopBody(const Stmt *S) {4219if (isa<NullStmt>(S))4220return true;42214222if (const auto *CS = dyn_cast<CompoundStmt>(S)) {4223for (const auto *InnerStmt : CS->body())4224if (!visitStmt(InnerStmt))4225return false;4226return true;4227}42284229return this->visitStmt(S);4230}42314232template <class Emitter>4233bool Compiler<Emitter>::visitCompoundStmt(const CompoundStmt *S) {4234BlockScope<Emitter> Scope(this);4235for (const auto *InnerStmt : S->body())4236if (!visitStmt(InnerStmt))4237return false;4238return Scope.destroyLocals();4239}42404241template <class Emitter>4242bool Compiler<Emitter>::visitDeclStmt(const DeclStmt *DS) {4243for (const auto *D : DS->decls()) {4244if (isa<StaticAssertDecl, TagDecl, TypedefNameDecl, UsingEnumDecl,4245FunctionDecl>(D))4246continue;42474248const auto *VD = dyn_cast<VarDecl>(D);4249if (!VD)4250return false;4251if (!this->visitVarDecl(VD))4252return false;4253}42544255return true;4256}42574258template <class Emitter>4259bool Compiler<Emitter>::visitReturnStmt(const ReturnStmt *RS) {4260if (this->InStmtExpr)4261return this->emitUnsupported(RS);42624263if (const Expr *RE = RS->getRetValue()) {4264LocalScope<Emitter> RetScope(this);4265if (ReturnType) {4266// Primitive types are simply returned.4267if (!this->visit(RE))4268return false;4269this->emitCleanup();4270return this->emitRet(*ReturnType, RS);4271} else if (RE->getType()->isVoidType()) {4272if (!this->visit(RE))4273return false;4274} else {4275// RVO - construct the value in the return location.4276if (!this->emitRVOPtr(RE))4277return false;4278if (!this->visitInitializer(RE))4279return false;4280if (!this->emitPopPtr(RE))4281return false;42824283this->emitCleanup();4284return this->emitRetVoid(RS);4285}4286}42874288// Void return.4289this->emitCleanup();4290return this->emitRetVoid(RS);4291}42924293template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {4294BlockScope<Emitter> IfScope(this);42954296if (IS->isNonNegatedConsteval())4297return visitStmt(IS->getThen());4298if (IS->isNegatedConsteval())4299return IS->getElse() ? visitStmt(IS->getElse()) : true;43004301if (auto *CondInit = IS->getInit())4302if (!visitStmt(CondInit))4303return false;43044305if (const DeclStmt *CondDecl = IS->getConditionVariableDeclStmt())4306if (!visitDeclStmt(CondDecl))4307return false;43084309if (!this->visitBool(IS->getCond()))4310return false;43114312if (const Stmt *Else = IS->getElse()) {4313LabelTy LabelElse = this->getLabel();4314LabelTy LabelEnd = this->getLabel();4315if (!this->jumpFalse(LabelElse))4316return false;4317if (!visitStmt(IS->getThen()))4318return false;4319if (!this->jump(LabelEnd))4320return false;4321this->emitLabel(LabelElse);4322if (!visitStmt(Else))4323return false;4324this->emitLabel(LabelEnd);4325} else {4326LabelTy LabelEnd = this->getLabel();4327if (!this->jumpFalse(LabelEnd))4328return false;4329if (!visitStmt(IS->getThen()))4330return false;4331this->emitLabel(LabelEnd);4332}43334334return IfScope.destroyLocals();4335}43364337template <class Emitter>4338bool Compiler<Emitter>::visitWhileStmt(const WhileStmt *S) {4339const Expr *Cond = S->getCond();4340const Stmt *Body = S->getBody();43414342LabelTy CondLabel = this->getLabel(); // Label before the condition.4343LabelTy EndLabel = this->getLabel(); // Label after the loop.4344LoopScope<Emitter> LS(this, EndLabel, CondLabel);43454346this->fallthrough(CondLabel);4347this->emitLabel(CondLabel);43484349if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())4350if (!visitDeclStmt(CondDecl))4351return false;43524353if (!this->visitBool(Cond))4354return false;4355if (!this->jumpFalse(EndLabel))4356return false;43574358LocalScope<Emitter> Scope(this);4359{4360DestructorScope<Emitter> DS(Scope);4361if (!this->visitLoopBody(Body))4362return false;4363}43644365if (!this->jump(CondLabel))4366return false;4367this->emitLabel(EndLabel);43684369return true;4370}43714372template <class Emitter> bool Compiler<Emitter>::visitDoStmt(const DoStmt *S) {4373const Expr *Cond = S->getCond();4374const Stmt *Body = S->getBody();43754376LabelTy StartLabel = this->getLabel();4377LabelTy EndLabel = this->getLabel();4378LabelTy CondLabel = this->getLabel();4379LoopScope<Emitter> LS(this, EndLabel, CondLabel);4380LocalScope<Emitter> Scope(this);43814382this->fallthrough(StartLabel);4383this->emitLabel(StartLabel);4384{4385DestructorScope<Emitter> DS(Scope);43864387if (!this->visitLoopBody(Body))4388return false;4389this->fallthrough(CondLabel);4390this->emitLabel(CondLabel);4391if (!this->visitBool(Cond))4392return false;4393}4394if (!this->jumpTrue(StartLabel))4395return false;43964397this->fallthrough(EndLabel);4398this->emitLabel(EndLabel);4399return true;4400}44014402template <class Emitter>4403bool Compiler<Emitter>::visitForStmt(const ForStmt *S) {4404// for (Init; Cond; Inc) { Body }4405const Stmt *Init = S->getInit();4406const Expr *Cond = S->getCond();4407const Expr *Inc = S->getInc();4408const Stmt *Body = S->getBody();44094410LabelTy EndLabel = this->getLabel();4411LabelTy CondLabel = this->getLabel();4412LabelTy IncLabel = this->getLabel();4413LoopScope<Emitter> LS(this, EndLabel, IncLabel);4414LocalScope<Emitter> Scope(this);44154416if (Init && !this->visitStmt(Init))4417return false;4418this->fallthrough(CondLabel);4419this->emitLabel(CondLabel);44204421if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())4422if (!visitDeclStmt(CondDecl))4423return false;44244425if (Cond) {4426if (!this->visitBool(Cond))4427return false;4428if (!this->jumpFalse(EndLabel))4429return false;4430}44314432{4433DestructorScope<Emitter> DS(Scope);44344435if (Body && !this->visitLoopBody(Body))4436return false;4437this->fallthrough(IncLabel);4438this->emitLabel(IncLabel);4439if (Inc && !this->discard(Inc))4440return false;4441}44424443if (!this->jump(CondLabel))4444return false;4445this->fallthrough(EndLabel);4446this->emitLabel(EndLabel);4447return true;4448}44494450template <class Emitter>4451bool Compiler<Emitter>::visitCXXForRangeStmt(const CXXForRangeStmt *S) {4452const Stmt *Init = S->getInit();4453const Expr *Cond = S->getCond();4454const Expr *Inc = S->getInc();4455const Stmt *Body = S->getBody();4456const Stmt *BeginStmt = S->getBeginStmt();4457const Stmt *RangeStmt = S->getRangeStmt();4458const Stmt *EndStmt = S->getEndStmt();4459const VarDecl *LoopVar = S->getLoopVariable();44604461LabelTy EndLabel = this->getLabel();4462LabelTy CondLabel = this->getLabel();4463LabelTy IncLabel = this->getLabel();4464LoopScope<Emitter> LS(this, EndLabel, IncLabel);44654466// Emit declarations needed in the loop.4467if (Init && !this->visitStmt(Init))4468return false;4469if (!this->visitStmt(RangeStmt))4470return false;4471if (!this->visitStmt(BeginStmt))4472return false;4473if (!this->visitStmt(EndStmt))4474return false;44754476// Now the condition as well as the loop variable assignment.4477this->fallthrough(CondLabel);4478this->emitLabel(CondLabel);4479if (!this->visitBool(Cond))4480return false;4481if (!this->jumpFalse(EndLabel))4482return false;44834484if (!this->visitVarDecl(LoopVar))4485return false;44864487// Body.4488LocalScope<Emitter> Scope(this);4489{4490DestructorScope<Emitter> DS(Scope);44914492if (!this->visitLoopBody(Body))4493return false;4494this->fallthrough(IncLabel);4495this->emitLabel(IncLabel);4496if (!this->discard(Inc))4497return false;4498}44994500if (!this->jump(CondLabel))4501return false;45024503this->fallthrough(EndLabel);4504this->emitLabel(EndLabel);4505return true;4506}45074508template <class Emitter>4509bool Compiler<Emitter>::visitBreakStmt(const BreakStmt *S) {4510if (!BreakLabel)4511return false;45124513this->VarScope->emitDestructors();4514return this->jump(*BreakLabel);4515}45164517template <class Emitter>4518bool Compiler<Emitter>::visitContinueStmt(const ContinueStmt *S) {4519if (!ContinueLabel)4520return false;45214522this->VarScope->emitDestructors();4523return this->jump(*ContinueLabel);4524}45254526template <class Emitter>4527bool Compiler<Emitter>::visitSwitchStmt(const SwitchStmt *S) {4528const Expr *Cond = S->getCond();4529PrimType CondT = this->classifyPrim(Cond->getType());45304531LabelTy EndLabel = this->getLabel();4532OptLabelTy DefaultLabel = std::nullopt;4533unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT, true, false);45344535if (const auto *CondInit = S->getInit())4536if (!visitStmt(CondInit))4537return false;45384539if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())4540if (!visitDeclStmt(CondDecl))4541return false;45424543// Initialize condition variable.4544if (!this->visit(Cond))4545return false;4546if (!this->emitSetLocal(CondT, CondVar, S))4547return false;45484549CaseMap CaseLabels;4550// Create labels and comparison ops for all case statements.4551for (const SwitchCase *SC = S->getSwitchCaseList(); SC;4552SC = SC->getNextSwitchCase()) {4553if (const auto *CS = dyn_cast<CaseStmt>(SC)) {4554// FIXME: Implement ranges.4555if (CS->caseStmtIsGNURange())4556return false;4557CaseLabels[SC] = this->getLabel();45584559const Expr *Value = CS->getLHS();4560PrimType ValueT = this->classifyPrim(Value->getType());45614562// Compare the case statement's value to the switch condition.4563if (!this->emitGetLocal(CondT, CondVar, CS))4564return false;4565if (!this->visit(Value))4566return false;45674568// Compare and jump to the case label.4569if (!this->emitEQ(ValueT, S))4570return false;4571if (!this->jumpTrue(CaseLabels[CS]))4572return false;4573} else {4574assert(!DefaultLabel);4575DefaultLabel = this->getLabel();4576}4577}45784579// If none of the conditions above were true, fall through to the default4580// statement or jump after the switch statement.4581if (DefaultLabel) {4582if (!this->jump(*DefaultLabel))4583return false;4584} else {4585if (!this->jump(EndLabel))4586return false;4587}45884589SwitchScope<Emitter> SS(this, std::move(CaseLabels), EndLabel, DefaultLabel);4590if (!this->visitStmt(S->getBody()))4591return false;4592this->emitLabel(EndLabel);4593return true;4594}45954596template <class Emitter>4597bool Compiler<Emitter>::visitCaseStmt(const CaseStmt *S) {4598this->emitLabel(CaseLabels[S]);4599return this->visitStmt(S->getSubStmt());4600}46014602template <class Emitter>4603bool Compiler<Emitter>::visitDefaultStmt(const DefaultStmt *S) {4604this->emitLabel(*DefaultLabel);4605return this->visitStmt(S->getSubStmt());4606}46074608template <class Emitter>4609bool Compiler<Emitter>::visitAttributedStmt(const AttributedStmt *S) {4610if (this->Ctx.getLangOpts().CXXAssumptions &&4611!this->Ctx.getLangOpts().MSVCCompat) {4612for (const Attr *A : S->getAttrs()) {4613auto *AA = dyn_cast<CXXAssumeAttr>(A);4614if (!AA)4615continue;46164617assert(isa<NullStmt>(S->getSubStmt()));46184619const Expr *Assumption = AA->getAssumption();4620if (Assumption->isValueDependent())4621return false;46224623if (Assumption->HasSideEffects(this->Ctx.getASTContext()))4624continue;46254626// Evaluate assumption.4627if (!this->visitBool(Assumption))4628return false;46294630if (!this->emitAssume(Assumption))4631return false;4632}4633}46344635// Ignore other attributes.4636return this->visitStmt(S->getSubStmt());4637}46384639template <class Emitter>4640bool Compiler<Emitter>::visitCXXTryStmt(const CXXTryStmt *S) {4641// Ignore all handlers.4642return this->visitStmt(S->getTryBlock());4643}46444645template <class Emitter>4646bool Compiler<Emitter>::emitLambdaStaticInvokerBody(const CXXMethodDecl *MD) {4647assert(MD->isLambdaStaticInvoker());4648assert(MD->hasBody());4649assert(cast<CompoundStmt>(MD->getBody())->body_empty());46504651const CXXRecordDecl *ClosureClass = MD->getParent();4652const CXXMethodDecl *LambdaCallOp = ClosureClass->getLambdaCallOperator();4653assert(ClosureClass->captures_begin() == ClosureClass->captures_end());4654const Function *Func = this->getFunction(LambdaCallOp);4655if (!Func)4656return false;4657assert(Func->hasThisPointer());4658assert(Func->getNumParams() == (MD->getNumParams() + 1 + Func->hasRVO()));46594660if (Func->hasRVO()) {4661if (!this->emitRVOPtr(MD))4662return false;4663}46644665// The lambda call operator needs an instance pointer, but we don't have4666// one here, and we don't need one either because the lambda cannot have4667// any captures, as verified above. Emit a null pointer. This is then4668// special-cased when interpreting to not emit any misleading diagnostics.4669if (!this->emitNullPtr(nullptr, MD))4670return false;46714672// Forward all arguments from the static invoker to the lambda call operator.4673for (const ParmVarDecl *PVD : MD->parameters()) {4674auto It = this->Params.find(PVD);4675assert(It != this->Params.end());46764677// We do the lvalue-to-rvalue conversion manually here, so no need4678// to care about references.4679PrimType ParamType = this->classify(PVD->getType()).value_or(PT_Ptr);4680if (!this->emitGetParam(ParamType, It->second.Offset, MD))4681return false;4682}46834684if (!this->emitCall(Func, 0, LambdaCallOp))4685return false;46864687this->emitCleanup();4688if (ReturnType)4689return this->emitRet(*ReturnType, MD);46904691// Nothing to do, since we emitted the RVO pointer above.4692return this->emitRetVoid(MD);4693}46944695template <class Emitter>4696bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {4697// Classify the return type.4698ReturnType = this->classify(F->getReturnType());46994700auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,4701const Expr *InitExpr) -> bool {4702// We don't know what to do with these, so just return false.4703if (InitExpr->getType().isNull())4704return false;47054706if (std::optional<PrimType> T = this->classify(InitExpr)) {4707if (!this->visit(InitExpr))4708return false;47094710if (F->isBitField())4711return this->emitInitThisBitField(*T, F, FieldOffset, InitExpr);4712return this->emitInitThisField(*T, FieldOffset, InitExpr);4713}4714// Non-primitive case. Get a pointer to the field-to-initialize4715// on the stack and call visitInitialzer() for it.4716InitLinkScope<Emitter> FieldScope(this, InitLink::Field(F->Offset));4717if (!this->emitGetPtrThisField(FieldOffset, InitExpr))4718return false;47194720if (!this->visitInitializer(InitExpr))4721return false;47224723return this->emitPopPtr(InitExpr);4724};47254726// Emit custom code if this is a lambda static invoker.4727if (const auto *MD = dyn_cast<CXXMethodDecl>(F);4728MD && MD->isLambdaStaticInvoker())4729return this->emitLambdaStaticInvokerBody(MD);47304731// Constructor. Set up field initializers.4732if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(F)) {4733const RecordDecl *RD = Ctor->getParent();4734const Record *R = this->getRecord(RD);4735if (!R)4736return false;47374738InitLinkScope<Emitter> InitScope(this, InitLink::This());4739for (const auto *Init : Ctor->inits()) {4740// Scope needed for the initializers.4741BlockScope<Emitter> Scope(this);47424743const Expr *InitExpr = Init->getInit();4744if (const FieldDecl *Member = Init->getMember()) {4745const Record::Field *F = R->getField(Member);47464747if (!emitFieldInitializer(F, F->Offset, InitExpr))4748return false;4749} else if (const Type *Base = Init->getBaseClass()) {4750const auto *BaseDecl = Base->getAsCXXRecordDecl();4751assert(BaseDecl);47524753if (Init->isBaseVirtual()) {4754assert(R->getVirtualBase(BaseDecl));4755if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))4756return false;47574758} else {4759// Base class initializer.4760// Get This Base and call initializer on it.4761const Record::Base *B = R->getBase(BaseDecl);4762assert(B);4763if (!this->emitGetPtrThisBase(B->Offset, InitExpr))4764return false;4765}47664767if (!this->visitInitializer(InitExpr))4768return false;4769if (!this->emitFinishInitPop(InitExpr))4770return false;4771} else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {4772assert(IFD->getChainingSize() >= 2);47734774unsigned NestedFieldOffset = 0;4775const Record::Field *NestedField = nullptr;4776for (const NamedDecl *ND : IFD->chain()) {4777const auto *FD = cast<FieldDecl>(ND);4778const Record *FieldRecord =4779this->P.getOrCreateRecord(FD->getParent());4780assert(FieldRecord);47814782NestedField = FieldRecord->getField(FD);4783assert(NestedField);47844785NestedFieldOffset += NestedField->Offset;4786}4787assert(NestedField);47884789if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))4790return false;4791} else {4792assert(Init->isDelegatingInitializer());4793if (!this->emitThis(InitExpr))4794return false;4795if (!this->visitInitializer(Init->getInit()))4796return false;4797if (!this->emitPopPtr(InitExpr))4798return false;4799}48004801if (!Scope.destroyLocals())4802return false;4803}4804}48054806if (const auto *Body = F->getBody())4807if (!visitStmt(Body))4808return false;48094810// Emit a guard return to protect against a code path missing one.4811if (F->getReturnType()->isVoidType())4812return this->emitRetVoid(SourceInfo{});4813return this->emitNoRet(SourceInfo{});4814}48154816template <class Emitter>4817bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {4818const Expr *SubExpr = E->getSubExpr();4819if (SubExpr->getType()->isAnyComplexType())4820return this->VisitComplexUnaryOperator(E);4821std::optional<PrimType> T = classify(SubExpr->getType());48224823switch (E->getOpcode()) {4824case UO_PostInc: { // x++4825if (!Ctx.getLangOpts().CPlusPlus14)4826return this->emitInvalid(E);4827if (!T)4828return this->emitError(E);48294830if (!this->visit(SubExpr))4831return false;48324833if (T == PT_Ptr || T == PT_FnPtr) {4834if (!this->emitIncPtr(E))4835return false;48364837return DiscardResult ? this->emitPopPtr(E) : true;4838}48394840if (T == PT_Float) {4841return DiscardResult ? this->emitIncfPop(getRoundingMode(E), E)4842: this->emitIncf(getRoundingMode(E), E);4843}48444845return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E);4846}4847case UO_PostDec: { // x--4848if (!Ctx.getLangOpts().CPlusPlus14)4849return this->emitInvalid(E);4850if (!T)4851return this->emitError(E);48524853if (!this->visit(SubExpr))4854return false;48554856if (T == PT_Ptr || T == PT_FnPtr) {4857if (!this->emitDecPtr(E))4858return false;48594860return DiscardResult ? this->emitPopPtr(E) : true;4861}48624863if (T == PT_Float) {4864return DiscardResult ? this->emitDecfPop(getRoundingMode(E), E)4865: this->emitDecf(getRoundingMode(E), E);4866}48674868return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E);4869}4870case UO_PreInc: { // ++x4871if (!Ctx.getLangOpts().CPlusPlus14)4872return this->emitInvalid(E);4873if (!T)4874return this->emitError(E);48754876if (!this->visit(SubExpr))4877return false;48784879if (T == PT_Ptr || T == PT_FnPtr) {4880if (!this->emitLoadPtr(E))4881return false;4882if (!this->emitConstUint8(1, E))4883return false;4884if (!this->emitAddOffsetUint8(E))4885return false;4886return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);4887}48884889// Post-inc and pre-inc are the same if the value is to be discarded.4890if (DiscardResult) {4891if (T == PT_Float)4892return this->emitIncfPop(getRoundingMode(E), E);4893return this->emitIncPop(*T, E);4894}48954896if (T == PT_Float) {4897const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());4898if (!this->emitLoadFloat(E))4899return false;4900if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))4901return false;4902if (!this->emitAddf(getRoundingMode(E), E))4903return false;4904if (!this->emitStoreFloat(E))4905return false;4906} else {4907assert(isIntegralType(*T));4908if (!this->emitLoad(*T, E))4909return false;4910if (!this->emitConst(1, E))4911return false;4912if (!this->emitAdd(*T, E))4913return false;4914if (!this->emitStore(*T, E))4915return false;4916}4917return E->isGLValue() || this->emitLoadPop(*T, E);4918}4919case UO_PreDec: { // --x4920if (!Ctx.getLangOpts().CPlusPlus14)4921return this->emitInvalid(E);4922if (!T)4923return this->emitError(E);49244925if (!this->visit(SubExpr))4926return false;49274928if (T == PT_Ptr || T == PT_FnPtr) {4929if (!this->emitLoadPtr(E))4930return false;4931if (!this->emitConstUint8(1, E))4932return false;4933if (!this->emitSubOffsetUint8(E))4934return false;4935return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);4936}49374938// Post-dec and pre-dec are the same if the value is to be discarded.4939if (DiscardResult) {4940if (T == PT_Float)4941return this->emitDecfPop(getRoundingMode(E), E);4942return this->emitDecPop(*T, E);4943}49444945if (T == PT_Float) {4946const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());4947if (!this->emitLoadFloat(E))4948return false;4949if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))4950return false;4951if (!this->emitSubf(getRoundingMode(E), E))4952return false;4953if (!this->emitStoreFloat(E))4954return false;4955} else {4956assert(isIntegralType(*T));4957if (!this->emitLoad(*T, E))4958return false;4959if (!this->emitConst(1, E))4960return false;4961if (!this->emitSub(*T, E))4962return false;4963if (!this->emitStore(*T, E))4964return false;4965}4966return E->isGLValue() || this->emitLoadPop(*T, E);4967}4968case UO_LNot: // !x4969if (!T)4970return this->emitError(E);49714972if (DiscardResult)4973return this->discard(SubExpr);49744975if (!this->visitBool(SubExpr))4976return false;49774978if (!this->emitInvBool(E))4979return false;49804981if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)4982return this->emitCast(PT_Bool, ET, E);4983return true;4984case UO_Minus: // -x4985if (!T)4986return this->emitError(E);49874988if (!this->visit(SubExpr))4989return false;4990return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);4991case UO_Plus: // +x4992if (!T)4993return this->emitError(E);49944995if (!this->visit(SubExpr)) // noop4996return false;4997return DiscardResult ? this->emitPop(*T, E) : true;4998case UO_AddrOf: // &x4999if (E->getType()->isMemberPointerType()) {5000// C++11 [expr.unary.op]p3 has very strict rules on how the address of a5001// member can be formed.5002return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(), E);5003}5004// We should already have a pointer when we get here.5005return this->delegate(SubExpr);5006case UO_Deref: // *x5007if (DiscardResult)5008return this->discard(SubExpr);5009return this->visit(SubExpr);5010case UO_Not: // ~x5011if (!T)5012return this->emitError(E);50135014if (!this->visit(SubExpr))5015return false;5016return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);5017case UO_Real: // __real x5018assert(T);5019return this->delegate(SubExpr);5020case UO_Imag: { // __imag x5021assert(T);5022if (!this->discard(SubExpr))5023return false;5024return this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);5025}5026case UO_Extension:5027return this->delegate(SubExpr);5028case UO_Coawait:5029assert(false && "Unhandled opcode");5030}50315032return false;5033}50345035template <class Emitter>5036bool Compiler<Emitter>::VisitComplexUnaryOperator(const UnaryOperator *E) {5037const Expr *SubExpr = E->getSubExpr();5038assert(SubExpr->getType()->isAnyComplexType());50395040if (DiscardResult)5041return this->discard(SubExpr);50425043std::optional<PrimType> ResT = classify(E);5044auto prepareResult = [=]() -> bool {5045if (!ResT && !Initializing) {5046std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);5047if (!LocalIndex)5048return false;5049return this->emitGetPtrLocal(*LocalIndex, E);5050}50515052return true;5053};50545055// The offset of the temporary, if we created one.5056unsigned SubExprOffset = ~0u;5057auto createTemp = [=, &SubExprOffset]() -> bool {5058SubExprOffset = this->allocateLocalPrimitive(SubExpr, PT_Ptr, true, false);5059if (!this->visit(SubExpr))5060return false;5061return this->emitSetLocal(PT_Ptr, SubExprOffset, E);5062};50635064PrimType ElemT = classifyComplexElementType(SubExpr->getType());5065auto getElem = [=](unsigned Offset, unsigned Index) -> bool {5066if (!this->emitGetLocal(PT_Ptr, Offset, E))5067return false;5068return this->emitArrayElemPop(ElemT, Index, E);5069};50705071switch (E->getOpcode()) {5072case UO_Minus:5073if (!prepareResult())5074return false;5075if (!createTemp())5076return false;5077for (unsigned I = 0; I != 2; ++I) {5078if (!getElem(SubExprOffset, I))5079return false;5080if (!this->emitNeg(ElemT, E))5081return false;5082if (!this->emitInitElem(ElemT, I, E))5083return false;5084}5085break;50865087case UO_Plus: // +x5088case UO_AddrOf: // &x5089case UO_Deref: // *x5090return this->delegate(SubExpr);50915092case UO_LNot:5093if (!this->visit(SubExpr))5094return false;5095if (!this->emitComplexBoolCast(SubExpr))5096return false;5097if (!this->emitInvBool(E))5098return false;5099if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)5100return this->emitCast(PT_Bool, ET, E);5101return true;51025103case UO_Real:5104return this->emitComplexReal(SubExpr);51055106case UO_Imag:5107if (!this->visit(SubExpr))5108return false;51095110if (SubExpr->isLValue()) {5111if (!this->emitConstUint8(1, E))5112return false;5113return this->emitArrayElemPtrPopUint8(E);5114}51155116// Since our _Complex implementation does not map to a primitive type,5117// we sometimes have to do the lvalue-to-rvalue conversion here manually.5118return this->emitArrayElemPop(classifyPrim(E->getType()), 1, E);51195120case UO_Not: // ~x5121if (!this->visit(SubExpr))5122return false;5123// Negate the imaginary component.5124if (!this->emitArrayElem(ElemT, 1, E))5125return false;5126if (!this->emitNeg(ElemT, E))5127return false;5128if (!this->emitInitElem(ElemT, 1, E))5129return false;5130return DiscardResult ? this->emitPopPtr(E) : true;51315132case UO_Extension:5133return this->delegate(SubExpr);51345135default:5136return this->emitInvalid(E);5137}51385139return true;5140}51415142template <class Emitter>5143bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {5144if (DiscardResult)5145return true;51465147if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {5148return this->emitConst(ECD->getInitVal(), E);5149} else if (const auto *BD = dyn_cast<BindingDecl>(D)) {5150return this->visit(BD->getBinding());5151} else if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {5152const Function *F = getFunction(FuncDecl);5153return F && this->emitGetFnPtr(F, E);5154} else if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {5155if (std::optional<unsigned> Index = P.getOrCreateGlobal(D)) {5156if (!this->emitGetPtrGlobal(*Index, E))5157return false;5158if (std::optional<PrimType> T = classify(E->getType())) {5159if (!this->visitAPValue(TPOD->getValue(), *T, E))5160return false;5161return this->emitInitGlobal(*T, *Index, E);5162}5163return this->visitAPValueInitializer(TPOD->getValue(), E);5164}5165return false;5166}51675168// References are implemented via pointers, so when we see a DeclRefExpr5169// pointing to a reference, we need to get its value directly (i.e. the5170// pointer to the actual value) instead of a pointer to the pointer to the5171// value.5172bool IsReference = D->getType()->isReferenceType();51735174// Check for local/global variables and parameters.5175if (auto It = Locals.find(D); It != Locals.end()) {5176const unsigned Offset = It->second.Offset;5177if (IsReference)5178return this->emitGetLocal(PT_Ptr, Offset, E);5179return this->emitGetPtrLocal(Offset, E);5180} else if (auto GlobalIndex = P.getGlobal(D)) {5181if (IsReference) {5182if (!Ctx.getLangOpts().CPlusPlus11)5183return this->emitGetGlobal(classifyPrim(E), *GlobalIndex, E);5184return this->emitGetGlobalUnchecked(classifyPrim(E), *GlobalIndex, E);5185}51865187return this->emitGetPtrGlobal(*GlobalIndex, E);5188} else if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {5189if (auto It = this->Params.find(PVD); It != this->Params.end()) {5190if (IsReference || !It->second.IsPtr)5191return this->emitGetParam(classifyPrim(E), It->second.Offset, E);51925193return this->emitGetPtrParam(It->second.Offset, E);5194}5195}51965197// In case we need to re-visit a declaration.5198auto revisit = [&](const VarDecl *VD) -> bool {5199auto VarState = this->visitDecl(VD);52005201if (VarState.notCreated())5202return true;5203if (!VarState)5204return false;5205// Retry.5206return this->visitDeclRef(D, E);5207};52085209// Handle lambda captures.5210if (auto It = this->LambdaCaptures.find(D);5211It != this->LambdaCaptures.end()) {5212auto [Offset, IsPtr] = It->second;52135214if (IsPtr)5215return this->emitGetThisFieldPtr(Offset, E);5216return this->emitGetPtrThisField(Offset, E);5217} else if (const auto *DRE = dyn_cast<DeclRefExpr>(E);5218DRE && DRE->refersToEnclosingVariableOrCapture()) {5219if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture())5220return revisit(VD);5221}52225223if (D != InitializingDecl) {5224// Try to lazily visit (or emit dummy pointers for) declarations5225// we haven't seen yet.5226if (Ctx.getLangOpts().CPlusPlus) {5227if (const auto *VD = dyn_cast<VarDecl>(D)) {5228const auto typeShouldBeVisited = [&](QualType T) -> bool {5229if (T.isConstant(Ctx.getASTContext()))5230return true;5231if (const auto *RT = T->getAs<ReferenceType>())5232return RT->getPointeeType().isConstQualified();5233return false;5234};52355236// Visit local const variables like normal.5237if ((VD->hasGlobalStorage() || VD->isLocalVarDecl() ||5238VD->isStaticDataMember()) &&5239typeShouldBeVisited(VD->getType()))5240return revisit(VD);5241}5242} else {5243if (const auto *VD = dyn_cast<VarDecl>(D);5244VD && VD->getAnyInitializer() &&5245VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak())5246return revisit(VD);5247}5248}52495250if (std::optional<unsigned> I = P.getOrCreateDummy(D)) {5251if (!this->emitGetPtrGlobal(*I, E))5252return false;5253if (E->getType()->isVoidType())5254return true;5255// Convert the dummy pointer to another pointer type if we have to.5256if (PrimType PT = classifyPrim(E); PT != PT_Ptr) {5257if (isPtrType(PT))5258return this->emitDecayPtr(PT_Ptr, PT, E);5259return false;5260}5261return true;5262}52635264if (const auto *DRE = dyn_cast<DeclRefExpr>(E))5265return this->emitInvalidDeclRef(DRE, E);5266return false;5267}52685269template <class Emitter>5270bool Compiler<Emitter>::VisitDeclRefExpr(const DeclRefExpr *E) {5271const auto *D = E->getDecl();5272return this->visitDeclRef(D, E);5273}52745275template <class Emitter> void Compiler<Emitter>::emitCleanup() {5276for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent())5277C->emitDestruction();5278}52795280template <class Emitter>5281unsigned Compiler<Emitter>::collectBaseOffset(const QualType BaseType,5282const QualType DerivedType) {5283const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {5284if (const auto *PT = dyn_cast<PointerType>(Ty))5285return PT->getPointeeType()->getAsCXXRecordDecl();5286return Ty->getAsCXXRecordDecl();5287};5288const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);5289const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);52905291return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);5292}52935294/// Emit casts from a PrimType to another PrimType.5295template <class Emitter>5296bool Compiler<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT,5297QualType ToQT, const Expr *E) {52985299if (FromT == PT_Float) {5300// Floating to floating.5301if (ToT == PT_Float) {5302const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);5303return this->emitCastFP(ToSem, getRoundingMode(E), E);5304}53055306if (ToT == PT_IntAP)5307return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT), E);5308if (ToT == PT_IntAPS)5309return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT), E);53105311// Float to integral.5312if (isIntegralType(ToT) || ToT == PT_Bool)5313return this->emitCastFloatingIntegral(ToT, E);5314}53155316if (isIntegralType(FromT) || FromT == PT_Bool) {5317if (ToT == PT_IntAP)5318return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);5319if (ToT == PT_IntAPS)5320return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);53215322// Integral to integral.5323if (isIntegralType(ToT) || ToT == PT_Bool)5324return FromT != ToT ? this->emitCast(FromT, ToT, E) : true;53255326if (ToT == PT_Float) {5327// Integral to floating.5328const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);5329return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(E),5330E);5331}5332}53335334return false;5335}53365337/// Emits __real(SubExpr)5338template <class Emitter>5339bool Compiler<Emitter>::emitComplexReal(const Expr *SubExpr) {5340assert(SubExpr->getType()->isAnyComplexType());53415342if (DiscardResult)5343return this->discard(SubExpr);53445345if (!this->visit(SubExpr))5346return false;5347if (SubExpr->isLValue()) {5348if (!this->emitConstUint8(0, SubExpr))5349return false;5350return this->emitArrayElemPtrPopUint8(SubExpr);5351}53525353// Rvalue, load the actual element.5354return this->emitArrayElemPop(classifyComplexElementType(SubExpr->getType()),53550, SubExpr);5356}53575358template <class Emitter>5359bool Compiler<Emitter>::emitComplexBoolCast(const Expr *E) {5360assert(!DiscardResult);5361PrimType ElemT = classifyComplexElementType(E->getType());5362// We emit the expression (__real(E) != 0 || __imag(E) != 0)5363// for us, that means (bool)E[0] || (bool)E[1]5364if (!this->emitArrayElem(ElemT, 0, E))5365return false;5366if (ElemT == PT_Float) {5367if (!this->emitCastFloatingIntegral(PT_Bool, E))5368return false;5369} else {5370if (!this->emitCast(ElemT, PT_Bool, E))5371return false;5372}53735374// We now have the bool value of E[0] on the stack.5375LabelTy LabelTrue = this->getLabel();5376if (!this->jumpTrue(LabelTrue))5377return false;53785379if (!this->emitArrayElemPop(ElemT, 1, E))5380return false;5381if (ElemT == PT_Float) {5382if (!this->emitCastFloatingIntegral(PT_Bool, E))5383return false;5384} else {5385if (!this->emitCast(ElemT, PT_Bool, E))5386return false;5387}5388// Leave the boolean value of E[1] on the stack.5389LabelTy EndLabel = this->getLabel();5390this->jump(EndLabel);53915392this->emitLabel(LabelTrue);5393if (!this->emitPopPtr(E))5394return false;5395if (!this->emitConstBool(true, E))5396return false;53975398this->fallthrough(EndLabel);5399this->emitLabel(EndLabel);54005401return true;5402}54035404template <class Emitter>5405bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS,5406const BinaryOperator *E) {5407assert(E->isComparisonOp());5408assert(!Initializing);5409assert(!DiscardResult);54105411PrimType ElemT;5412bool LHSIsComplex;5413unsigned LHSOffset;5414if (LHS->getType()->isAnyComplexType()) {5415LHSIsComplex = true;5416ElemT = classifyComplexElementType(LHS->getType());5417LHSOffset = allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true,5418/*IsExtended=*/false);5419if (!this->visit(LHS))5420return false;5421if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))5422return false;5423} else {5424LHSIsComplex = false;5425PrimType LHST = classifyPrim(LHS->getType());5426LHSOffset = this->allocateLocalPrimitive(LHS, LHST, true, false);5427if (!this->visit(LHS))5428return false;5429if (!this->emitSetLocal(LHST, LHSOffset, E))5430return false;5431}54325433bool RHSIsComplex;5434unsigned RHSOffset;5435if (RHS->getType()->isAnyComplexType()) {5436RHSIsComplex = true;5437ElemT = classifyComplexElementType(RHS->getType());5438RHSOffset = allocateLocalPrimitive(RHS, PT_Ptr, /*IsConst=*/true,5439/*IsExtended=*/false);5440if (!this->visit(RHS))5441return false;5442if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))5443return false;5444} else {5445RHSIsComplex = false;5446PrimType RHST = classifyPrim(RHS->getType());5447RHSOffset = this->allocateLocalPrimitive(RHS, RHST, true, false);5448if (!this->visit(RHS))5449return false;5450if (!this->emitSetLocal(RHST, RHSOffset, E))5451return false;5452}54535454auto getElem = [&](unsigned LocalOffset, unsigned Index,5455bool IsComplex) -> bool {5456if (IsComplex) {5457if (!this->emitGetLocal(PT_Ptr, LocalOffset, E))5458return false;5459return this->emitArrayElemPop(ElemT, Index, E);5460}5461return this->emitGetLocal(ElemT, LocalOffset, E);5462};54635464for (unsigned I = 0; I != 2; ++I) {5465// Get both values.5466if (!getElem(LHSOffset, I, LHSIsComplex))5467return false;5468if (!getElem(RHSOffset, I, RHSIsComplex))5469return false;5470// And compare them.5471if (!this->emitEQ(ElemT, E))5472return false;54735474if (!this->emitCastBoolUint8(E))5475return false;5476}54775478// We now have two bool values on the stack. Compare those.5479if (!this->emitAddUint8(E))5480return false;5481if (!this->emitConstUint8(2, E))5482return false;54835484if (E->getOpcode() == BO_EQ) {5485if (!this->emitEQUint8(E))5486return false;5487} else if (E->getOpcode() == BO_NE) {5488if (!this->emitNEUint8(E))5489return false;5490} else5491return false;54925493// In C, this returns an int.5494if (PrimType ResT = classifyPrim(E->getType()); ResT != PT_Bool)5495return this->emitCast(PT_Bool, ResT, E);5496return true;5497}54985499/// When calling this, we have a pointer of the local-to-destroy5500/// on the stack.5501/// Emit destruction of record types (or arrays of record types).5502template <class Emitter>5503bool Compiler<Emitter>::emitRecordDestruction(const Record *R) {5504assert(R);5505// First, destroy all fields.5506for (const Record::Field &Field : llvm::reverse(R->fields())) {5507const Descriptor *D = Field.Desc;5508if (!D->isPrimitive() && !D->isPrimitiveArray()) {5509if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))5510return false;5511if (!this->emitDestruction(D))5512return false;5513if (!this->emitPopPtr(SourceInfo{}))5514return false;5515}5516}55175518// FIXME: Unions need to be handled differently here. We don't want to5519// call the destructor of its members.55205521// Now emit the destructor and recurse into base classes.5522if (const CXXDestructorDecl *Dtor = R->getDestructor();5523Dtor && !Dtor->isTrivial()) {5524const Function *DtorFunc = getFunction(Dtor);5525if (!DtorFunc)5526return false;5527assert(DtorFunc->hasThisPointer());5528assert(DtorFunc->getNumParams() == 1);5529if (!this->emitDupPtr(SourceInfo{}))5530return false;5531if (!this->emitCall(DtorFunc, 0, SourceInfo{}))5532return false;5533}55345535for (const Record::Base &Base : llvm::reverse(R->bases())) {5536if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))5537return false;5538if (!this->emitRecordDestruction(Base.R))5539return false;5540if (!this->emitPopPtr(SourceInfo{}))5541return false;5542}55435544// FIXME: Virtual bases.5545return true;5546}5547/// When calling this, we have a pointer of the local-to-destroy5548/// on the stack.5549/// Emit destruction of record types (or arrays of record types).5550template <class Emitter>5551bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc) {5552assert(Desc);5553assert(!Desc->isPrimitive());5554assert(!Desc->isPrimitiveArray());55555556// Arrays.5557if (Desc->isArray()) {5558const Descriptor *ElemDesc = Desc->ElemDesc;5559assert(ElemDesc);55605561// Don't need to do anything for these.5562if (ElemDesc->isPrimitiveArray())5563return true;55645565// If this is an array of record types, check if we need5566// to call the element destructors at all. If not, try5567// to save the work.5568if (const Record *ElemRecord = ElemDesc->ElemRecord) {5569if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();5570!Dtor || Dtor->isTrivial())5571return true;5572}55735574for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) {5575if (!this->emitConstUint64(I, SourceInfo{}))5576return false;5577if (!this->emitArrayElemPtrUint64(SourceInfo{}))5578return false;5579if (!this->emitDestruction(ElemDesc))5580return false;5581if (!this->emitPopPtr(SourceInfo{}))5582return false;5583}5584return true;5585}55865587assert(Desc->ElemRecord);5588return this->emitRecordDestruction(Desc->ElemRecord);5589}55905591namespace clang {5592namespace interp {55935594template class Compiler<ByteCodeEmitter>;5595template class Compiler<EvalEmitter>;55965597} // namespace interp5598} // namespace clang559956005601