1 //===--- ByteCodeExprGen.cpp - Code generator for expressions ---*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "ByteCodeExprGen.h" 10 #include "ByteCodeEmitter.h" 11 #include "ByteCodeGenError.h" 12 #include "ByteCodeStmtGen.h" 13 #include "Context.h" 14 #include "Function.h" 15 #include "PrimType.h" 16 #include "Program.h" 17 #include "State.h" 18 19 using namespace clang; 20 using namespace clang::interp; 21 22 using APSInt = llvm::APSInt; 23 24 namespace clang { 25 namespace interp { 26 27 /// Scope used to handle temporaries in toplevel variable declarations. 28 template <class Emitter> class DeclScope final : public LocalScope<Emitter> { 29 public: 30 DeclScope(ByteCodeExprGen<Emitter> *Ctx, const VarDecl *VD) 31 : LocalScope<Emitter>(Ctx), Scope(Ctx->P, VD) {} 32 33 void addExtended(const Scope::Local &Local) override { 34 return this->addLocal(Local); 35 } 36 37 private: 38 Program::DeclScope Scope; 39 }; 40 41 /// Scope used to handle initialization methods. 42 template <class Emitter> class OptionScope { 43 public: 44 /// Root constructor, compiling or discarding primitives. 45 OptionScope(ByteCodeExprGen<Emitter> *Ctx, bool NewDiscardResult) 46 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult) { 47 Ctx->DiscardResult = NewDiscardResult; 48 } 49 50 ~OptionScope() { Ctx->DiscardResult = OldDiscardResult; } 51 52 private: 53 /// Parent context. 54 ByteCodeExprGen<Emitter> *Ctx; 55 /// Old discard flag to restore. 56 bool OldDiscardResult; 57 }; 58 59 } // namespace interp 60 } // namespace clang 61 62 template <class Emitter> 63 bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) { 64 auto *SubExpr = CE->getSubExpr(); 65 switch (CE->getCastKind()) { 66 67 case CK_LValueToRValue: { 68 return dereference( 69 CE->getSubExpr(), DerefKind::Read, 70 [](PrimType) { 71 // Value loaded - nothing to do here. 72 return true; 73 }, 74 [this, CE](PrimType T) { 75 // Pointer on stack - dereference it. 76 if (!this->emitLoadPop(T, CE)) 77 return false; 78 return DiscardResult ? this->emitPop(T, CE) : true; 79 }); 80 } 81 82 case CK_UncheckedDerivedToBase: 83 case CK_DerivedToBase: { 84 if (!this->visit(SubExpr)) 85 return false; 86 87 const CXXRecordDecl *FromDecl = getRecordDecl(SubExpr); 88 assert(FromDecl); 89 const CXXRecordDecl *ToDecl = getRecordDecl(CE); 90 assert(ToDecl); 91 const Record *R = getRecord(FromDecl); 92 const Record::Base *ToBase = R->getBase(ToDecl); 93 assert(ToBase); 94 95 return this->emitGetPtrBase(ToBase->Offset, CE); 96 } 97 98 case CK_ArrayToPointerDecay: 99 case CK_AtomicToNonAtomic: 100 case CK_ConstructorConversion: 101 case CK_FunctionToPointerDecay: 102 case CK_NonAtomicToAtomic: 103 case CK_NoOp: 104 case CK_UserDefinedConversion: 105 case CK_NullToPointer: 106 return this->visit(SubExpr); 107 108 case CK_IntegralToBoolean: 109 case CK_IntegralCast: { 110 std::optional<PrimType> FromT = classify(SubExpr->getType()); 111 std::optional<PrimType> ToT = classify(CE->getType()); 112 if (!FromT || !ToT) 113 return false; 114 115 if (!this->visit(SubExpr)) 116 return false; 117 118 // TODO: Emit this only if FromT != ToT. 119 return this->emitCast(*FromT, *ToT, CE); 120 } 121 122 case CK_ToVoid: 123 return discard(SubExpr); 124 125 default: 126 assert(false && "Cast not implemented"); 127 } 128 llvm_unreachable("Unhandled clang::CastKind enum"); 129 } 130 131 template <class Emitter> 132 bool ByteCodeExprGen<Emitter>::VisitIntegerLiteral(const IntegerLiteral *LE) { 133 if (DiscardResult) 134 return true; 135 136 return this->emitConst(LE->getValue(), LE); 137 } 138 139 template <class Emitter> 140 bool ByteCodeExprGen<Emitter>::VisitParenExpr(const ParenExpr *PE) { 141 return this->visit(PE->getSubExpr()); 142 } 143 144 template <class Emitter> 145 bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) { 146 const Expr *LHS = BO->getLHS(); 147 const Expr *RHS = BO->getRHS(); 148 149 // Deal with operations which have composite or void types. 150 switch (BO->getOpcode()) { 151 case BO_Comma: 152 if (!discard(LHS)) 153 return false; 154 if (!this->visit(RHS)) 155 return false; 156 return true; 157 default: 158 break; 159 } 160 161 // Typecheck the args. 162 std::optional<PrimType> LT = classify(LHS->getType()); 163 std::optional<PrimType> RT = classify(RHS->getType()); 164 std::optional<PrimType> T = classify(BO->getType()); 165 if (!LT || !RT || !T) { 166 return this->bail(BO); 167 } 168 169 auto Discard = [this, T, BO](bool Result) { 170 if (!Result) 171 return false; 172 return DiscardResult ? this->emitPop(*T, BO) : true; 173 }; 174 175 // Pointer arithmetic special case. 176 if (BO->getOpcode() == BO_Add || BO->getOpcode() == BO_Sub) { 177 if (*T == PT_Ptr || (*LT == PT_Ptr && *RT == PT_Ptr)) 178 return this->VisitPointerArithBinOp(BO); 179 } 180 181 if (!visit(LHS) || !visit(RHS)) 182 return false; 183 184 switch (BO->getOpcode()) { 185 case BO_EQ: 186 return Discard(this->emitEQ(*LT, BO)); 187 case BO_NE: 188 return Discard(this->emitNE(*LT, BO)); 189 case BO_LT: 190 return Discard(this->emitLT(*LT, BO)); 191 case BO_LE: 192 return Discard(this->emitLE(*LT, BO)); 193 case BO_GT: 194 return Discard(this->emitGT(*LT, BO)); 195 case BO_GE: 196 return Discard(this->emitGE(*LT, BO)); 197 case BO_Sub: 198 return Discard(this->emitSub(*T, BO)); 199 case BO_Add: 200 return Discard(this->emitAdd(*T, BO)); 201 case BO_Mul: 202 return Discard(this->emitMul(*T, BO)); 203 case BO_Rem: 204 return Discard(this->emitRem(*T, BO)); 205 case BO_Div: 206 return Discard(this->emitDiv(*T, BO)); 207 case BO_Assign: 208 if (DiscardResult) 209 return this->emitStorePop(*T, BO); 210 return this->emitStore(*T, BO); 211 case BO_And: 212 return Discard(this->emitBitAnd(*T, BO)); 213 case BO_Or: 214 return Discard(this->emitBitOr(*T, BO)); 215 case BO_Shl: 216 return Discard(this->emitShl(*LT, *RT, BO)); 217 case BO_Shr: 218 return Discard(this->emitShr(*LT, *RT, BO)); 219 case BO_Xor: 220 return Discard(this->emitBitXor(*T, BO)); 221 case BO_LAnd: 222 case BO_LOr: 223 default: 224 return this->bail(BO); 225 } 226 227 llvm_unreachable("Unhandled binary op"); 228 } 229 230 /// Perform addition/subtraction of a pointer and an integer or 231 /// subtraction of two pointers. 232 template <class Emitter> 233 bool ByteCodeExprGen<Emitter>::VisitPointerArithBinOp(const BinaryOperator *E) { 234 BinaryOperatorKind Op = E->getOpcode(); 235 const Expr *LHS = E->getLHS(); 236 const Expr *RHS = E->getRHS(); 237 238 if ((Op != BO_Add && Op != BO_Sub) || 239 (!LHS->getType()->isPointerType() && !RHS->getType()->isPointerType())) 240 return false; 241 242 std::optional<PrimType> LT = classify(LHS); 243 std::optional<PrimType> RT = classify(RHS); 244 245 if (!LT || !RT) 246 return false; 247 248 if (LHS->getType()->isPointerType() && RHS->getType()->isPointerType()) { 249 if (Op != BO_Sub) 250 return false; 251 252 assert(E->getType()->isIntegerType()); 253 if (!visit(RHS) || !visit(LHS)) 254 return false; 255 256 return this->emitSubPtr(classifyPrim(E->getType()), E); 257 } 258 259 PrimType OffsetType; 260 if (LHS->getType()->isIntegerType()) { 261 if (!visit(RHS) || !visit(LHS)) 262 return false; 263 OffsetType = *LT; 264 } else if (RHS->getType()->isIntegerType()) { 265 if (!visit(LHS) || !visit(RHS)) 266 return false; 267 OffsetType = *RT; 268 } else { 269 return false; 270 } 271 272 if (Op == BO_Add) 273 return this->emitAddOffset(OffsetType, E); 274 else if (Op == BO_Sub) 275 return this->emitSubOffset(OffsetType, E); 276 277 return this->bail(E); 278 } 279 280 template <class Emitter> 281 bool ByteCodeExprGen<Emitter>::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) { 282 if (std::optional<PrimType> T = classify(E)) 283 return this->emitZero(*T, E); 284 285 return false; 286 } 287 288 template <class Emitter> 289 bool ByteCodeExprGen<Emitter>::VisitArraySubscriptExpr( 290 const ArraySubscriptExpr *E) { 291 const Expr *Base = E->getBase(); 292 const Expr *Index = E->getIdx(); 293 PrimType IndexT = classifyPrim(Index->getType()); 294 295 // Take pointer of LHS, add offset from RHS, narrow result. 296 // What's left on the stack after this is a pointer. 297 if (!this->visit(Base)) 298 return false; 299 300 if (!this->visit(Index)) 301 return false; 302 303 if (!this->emitAddOffset(IndexT, E)) 304 return false; 305 306 if (!this->emitNarrowPtr(E)) 307 return false; 308 309 if (DiscardResult) 310 return this->emitPopPtr(E); 311 312 return true; 313 } 314 315 template <class Emitter> 316 bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) { 317 for (const Expr *Init : E->inits()) { 318 if (!this->visit(Init)) 319 return false; 320 } 321 return true; 322 } 323 324 template <class Emitter> 325 bool ByteCodeExprGen<Emitter>::VisitSubstNonTypeTemplateParmExpr( 326 const SubstNonTypeTemplateParmExpr *E) { 327 return this->visit(E->getReplacement()); 328 } 329 330 template <class Emitter> 331 bool ByteCodeExprGen<Emitter>::VisitConstantExpr(const ConstantExpr *E) { 332 // TODO: Check if the ConstantExpr already has a value set and if so, 333 // use that instead of evaluating it again. 334 return this->visit(E->getSubExpr()); 335 } 336 337 static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, 338 UnaryExprOrTypeTrait Kind) { 339 bool AlignOfReturnsPreferred = 340 ASTCtx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7; 341 342 // C++ [expr.alignof]p3: 343 // When alignof is applied to a reference type, the result is the 344 // alignment of the referenced type. 345 if (const auto *Ref = T->getAs<ReferenceType>()) 346 T = Ref->getPointeeType(); 347 348 // __alignof is defined to return the preferred alignment. 349 // Before 8, clang returned the preferred alignment for alignof and 350 // _Alignof as well. 351 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred) 352 return ASTCtx.toCharUnitsFromBits(ASTCtx.getPreferredTypeAlign(T)); 353 354 return ASTCtx.getTypeAlignInChars(T); 355 } 356 357 template <class Emitter> 358 bool ByteCodeExprGen<Emitter>::VisitUnaryExprOrTypeTraitExpr( 359 const UnaryExprOrTypeTraitExpr *E) { 360 UnaryExprOrTypeTrait Kind = E->getKind(); 361 ASTContext &ASTCtx = Ctx.getASTContext(); 362 363 if (Kind == UETT_SizeOf) { 364 QualType ArgType = E->getTypeOfArgument(); 365 CharUnits Size; 366 if (ArgType->isVoidType() || ArgType->isFunctionType()) 367 Size = CharUnits::One(); 368 else { 369 if (ArgType->isDependentType() || !ArgType->isConstantSizeType()) 370 return false; 371 372 Size = ASTCtx.getTypeSizeInChars(ArgType); 373 } 374 375 return this->emitConst(Size.getQuantity(), E); 376 } 377 378 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) { 379 CharUnits Size; 380 381 if (E->isArgumentType()) { 382 QualType ArgType = E->getTypeOfArgument(); 383 384 Size = AlignOfType(ArgType, ASTCtx, Kind); 385 } else { 386 // Argument is an expression, not a type. 387 const Expr *Arg = E->getArgumentExpr()->IgnoreParens(); 388 389 // The kinds of expressions that we have special-case logic here for 390 // should be kept up to date with the special checks for those 391 // expressions in Sema. 392 393 // alignof decl is always accepted, even if it doesn't make sense: we 394 // default to 1 in those cases. 395 if (const auto *DRE = dyn_cast<DeclRefExpr>(Arg)) 396 Size = ASTCtx.getDeclAlign(DRE->getDecl(), 397 /*RefAsPointee*/ true); 398 else if (const auto *ME = dyn_cast<MemberExpr>(Arg)) 399 Size = ASTCtx.getDeclAlign(ME->getMemberDecl(), 400 /*RefAsPointee*/ true); 401 else 402 Size = AlignOfType(Arg->getType(), ASTCtx, Kind); 403 } 404 405 return this->emitConst(Size.getQuantity(), E); 406 } 407 408 return false; 409 } 410 411 template <class Emitter> 412 bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) { 413 if (DiscardResult) 414 return true; 415 416 // 'Base.Member' 417 const Expr *Base = E->getBase(); 418 const ValueDecl *Member = E->getMemberDecl(); 419 420 if (!this->visit(Base)) 421 return false; 422 423 // Base above gives us a pointer on the stack. 424 // TODO: Implement non-FieldDecl members. 425 if (const auto *FD = dyn_cast<FieldDecl>(Member)) { 426 const RecordDecl *RD = FD->getParent(); 427 const Record *R = getRecord(RD); 428 const Record::Field *F = R->getField(FD); 429 // Leave a pointer to the field on the stack. 430 if (F->Decl->getType()->isReferenceType()) 431 return this->emitGetFieldPop(PT_Ptr, F->Offset, E); 432 return this->emitGetPtrField(F->Offset, E); 433 } 434 435 return false; 436 } 437 438 template <class Emitter> 439 bool ByteCodeExprGen<Emitter>::VisitArrayInitIndexExpr( 440 const ArrayInitIndexExpr *E) { 441 // ArrayIndex might not be set if a ArrayInitIndexExpr is being evaluated 442 // stand-alone, e.g. via EvaluateAsInt(). 443 if (!ArrayIndex) 444 return false; 445 return this->emitConst(*ArrayIndex, E); 446 } 447 448 template <class Emitter> 449 bool ByteCodeExprGen<Emitter>::VisitOpaqueValueExpr(const OpaqueValueExpr *E) { 450 return this->visit(E->getSourceExpr()); 451 } 452 453 template <class Emitter> 454 bool ByteCodeExprGen<Emitter>::VisitAbstractConditionalOperator( 455 const AbstractConditionalOperator *E) { 456 const Expr *Condition = E->getCond(); 457 const Expr *TrueExpr = E->getTrueExpr(); 458 const Expr *FalseExpr = E->getFalseExpr(); 459 460 LabelTy LabelEnd = this->getLabel(); // Label after the operator. 461 LabelTy LabelFalse = this->getLabel(); // Label for the false expr. 462 463 if (!this->visit(Condition)) 464 return false; 465 if (!this->jumpFalse(LabelFalse)) 466 return false; 467 468 if (!this->visit(TrueExpr)) 469 return false; 470 if (!this->jump(LabelEnd)) 471 return false; 472 473 this->emitLabel(LabelFalse); 474 475 if (!this->visit(FalseExpr)) 476 return false; 477 478 this->fallthrough(LabelEnd); 479 this->emitLabel(LabelEnd); 480 481 return true; 482 } 483 484 template <class Emitter> 485 bool ByteCodeExprGen<Emitter>::VisitStringLiteral(const StringLiteral *E) { 486 unsigned StringIndex = P.createGlobalString(E); 487 return this->emitGetPtrGlobal(StringIndex, E); 488 } 489 490 template <class Emitter> 491 bool ByteCodeExprGen<Emitter>::VisitCharacterLiteral( 492 const CharacterLiteral *E) { 493 return this->emitConst(E->getValue(), E); 494 } 495 496 template <class Emitter> 497 bool ByteCodeExprGen<Emitter>::VisitCompoundAssignOperator( 498 const CompoundAssignOperator *E) { 499 const Expr *LHS = E->getLHS(); 500 const Expr *RHS = E->getRHS(); 501 std::optional<PrimType> LT = classify(E->getLHS()->getType()); 502 std::optional<PrimType> RT = classify(E->getRHS()->getType()); 503 504 if (!LT || !RT) 505 return false; 506 507 assert(!E->getType()->isPointerType() && 508 "Support pointer arithmethic in compound assignment operators"); 509 510 // Get LHS pointer, load its value and get RHS value. 511 if (!visit(LHS)) 512 return false; 513 if (!this->emitLoad(*LT, E)) 514 return false; 515 if (!visit(RHS)) 516 return false; 517 518 // Perform operation. 519 switch (E->getOpcode()) { 520 case BO_AddAssign: 521 if (!this->emitAdd(*LT, E)) 522 return false; 523 break; 524 case BO_SubAssign: 525 if (!this->emitSub(*LT, E)) 526 return false; 527 break; 528 529 case BO_MulAssign: 530 case BO_DivAssign: 531 case BO_RemAssign: 532 case BO_ShlAssign: 533 if (!this->emitShl(*LT, *RT, E)) 534 return false; 535 break; 536 case BO_ShrAssign: 537 if (!this->emitShr(*LT, *RT, E)) 538 return false; 539 break; 540 case BO_AndAssign: 541 case BO_XorAssign: 542 case BO_OrAssign: 543 default: 544 llvm_unreachable("Unimplemented compound assign operator"); 545 } 546 547 // And store the result in LHS. 548 if (DiscardResult) 549 return this->emitStorePop(*LT, E); 550 return this->emitStore(*LT, E); 551 } 552 553 template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) { 554 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true); 555 return this->Visit(E); 556 } 557 558 template <class Emitter> 559 bool ByteCodeExprGen<Emitter>::visit(const Expr *E) { 560 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false); 561 return this->Visit(E); 562 } 563 564 template <class Emitter> 565 bool ByteCodeExprGen<Emitter>::visitBool(const Expr *E) { 566 if (std::optional<PrimType> T = classify(E->getType())) { 567 return visit(E); 568 } else { 569 return this->bail(E); 570 } 571 } 572 573 template <class Emitter> 574 bool ByteCodeExprGen<Emitter>::visitZeroInitializer(PrimType T, const Expr *E) { 575 switch (T) { 576 case PT_Bool: 577 return this->emitZeroBool(E); 578 case PT_Sint8: 579 return this->emitZeroSint8(E); 580 case PT_Uint8: 581 return this->emitZeroUint8(E); 582 case PT_Sint16: 583 return this->emitZeroSint16(E); 584 case PT_Uint16: 585 return this->emitZeroUint16(E); 586 case PT_Sint32: 587 return this->emitZeroSint32(E); 588 case PT_Uint32: 589 return this->emitZeroUint32(E); 590 case PT_Sint64: 591 return this->emitZeroSint64(E); 592 case PT_Uint64: 593 return this->emitZeroUint64(E); 594 case PT_Ptr: 595 return this->emitNullPtr(E); 596 } 597 llvm_unreachable("unknown primitive type"); 598 } 599 600 template <class Emitter> 601 bool ByteCodeExprGen<Emitter>::dereference( 602 const Expr *LV, DerefKind AK, llvm::function_ref<bool(PrimType)> Direct, 603 llvm::function_ref<bool(PrimType)> Indirect) { 604 if (std::optional<PrimType> T = classify(LV->getType())) { 605 if (!LV->refersToBitField()) { 606 // Only primitive, non bit-field types can be dereferenced directly. 607 if (auto *DE = dyn_cast<DeclRefExpr>(LV)) { 608 if (!DE->getDecl()->getType()->isReferenceType()) { 609 if (auto *PD = dyn_cast<ParmVarDecl>(DE->getDecl())) 610 return dereferenceParam(LV, *T, PD, AK, Direct, Indirect); 611 if (auto *VD = dyn_cast<VarDecl>(DE->getDecl())) 612 return dereferenceVar(LV, *T, VD, AK, Direct, Indirect); 613 } 614 } 615 } 616 617 if (!visit(LV)) 618 return false; 619 return Indirect(*T); 620 } 621 622 return false; 623 } 624 625 template <class Emitter> 626 bool ByteCodeExprGen<Emitter>::dereferenceParam( 627 const Expr *LV, PrimType T, const ParmVarDecl *PD, DerefKind AK, 628 llvm::function_ref<bool(PrimType)> Direct, 629 llvm::function_ref<bool(PrimType)> Indirect) { 630 auto It = this->Params.find(PD); 631 if (It != this->Params.end()) { 632 unsigned Idx = It->second; 633 switch (AK) { 634 case DerefKind::Read: 635 return DiscardResult ? true : this->emitGetParam(T, Idx, LV); 636 637 case DerefKind::Write: 638 if (!Direct(T)) 639 return false; 640 if (!this->emitSetParam(T, Idx, LV)) 641 return false; 642 return DiscardResult ? true : this->emitGetPtrParam(Idx, LV); 643 644 case DerefKind::ReadWrite: 645 if (!this->emitGetParam(T, Idx, LV)) 646 return false; 647 if (!Direct(T)) 648 return false; 649 if (!this->emitSetParam(T, Idx, LV)) 650 return false; 651 return DiscardResult ? true : this->emitGetPtrParam(Idx, LV); 652 } 653 return true; 654 } 655 656 // If the param is a pointer, we can dereference a dummy value. 657 if (!DiscardResult && T == PT_Ptr && AK == DerefKind::Read) { 658 if (auto Idx = P.getOrCreateDummy(PD)) 659 return this->emitGetPtrGlobal(*Idx, PD); 660 return false; 661 } 662 663 // Value cannot be produced - try to emit pointer and do stuff with it. 664 return visit(LV) && Indirect(T); 665 } 666 667 template <class Emitter> 668 bool ByteCodeExprGen<Emitter>::dereferenceVar( 669 const Expr *LV, PrimType T, const VarDecl *VD, DerefKind AK, 670 llvm::function_ref<bool(PrimType)> Direct, 671 llvm::function_ref<bool(PrimType)> Indirect) { 672 auto It = Locals.find(VD); 673 if (It != Locals.end()) { 674 const auto &L = It->second; 675 switch (AK) { 676 case DerefKind::Read: 677 if (!this->emitGetLocal(T, L.Offset, LV)) 678 return false; 679 return DiscardResult ? this->emitPop(T, LV) : true; 680 681 case DerefKind::Write: 682 if (!Direct(T)) 683 return false; 684 if (!this->emitSetLocal(T, L.Offset, LV)) 685 return false; 686 return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV); 687 688 case DerefKind::ReadWrite: 689 if (!this->emitGetLocal(T, L.Offset, LV)) 690 return false; 691 if (!Direct(T)) 692 return false; 693 if (!this->emitSetLocal(T, L.Offset, LV)) 694 return false; 695 return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV); 696 } 697 } else if (auto Idx = P.getGlobal(VD)) { 698 switch (AK) { 699 case DerefKind::Read: 700 if (!this->emitGetGlobal(T, *Idx, LV)) 701 return false; 702 return DiscardResult ? this->emitPop(T, LV) : true; 703 704 case DerefKind::Write: 705 if (!Direct(T)) 706 return false; 707 if (!this->emitSetGlobal(T, *Idx, LV)) 708 return false; 709 return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV); 710 711 case DerefKind::ReadWrite: 712 if (!this->emitGetGlobal(T, *Idx, LV)) 713 return false; 714 if (!Direct(T)) 715 return false; 716 if (!this->emitSetGlobal(T, *Idx, LV)) 717 return false; 718 return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV); 719 } 720 } 721 722 // If the declaration is a constant value, emit it here even 723 // though the declaration was not evaluated in the current scope. 724 // The access mode can only be read in this case. 725 if (!DiscardResult && AK == DerefKind::Read) { 726 if (VD->hasLocalStorage() && VD->hasInit() && !VD->isConstexpr()) { 727 QualType VT = VD->getType(); 728 if (VT.isConstQualified() && VT->isFundamentalType()) 729 return this->visit(VD->getInit()); 730 } 731 } 732 733 // Value cannot be produced - try to emit pointer. 734 return visit(LV) && Indirect(T); 735 } 736 737 template <class Emitter> 738 template <typename T> 739 bool ByteCodeExprGen<Emitter>::emitConst(T Value, const Expr *E) { 740 switch (classifyPrim(E->getType())) { 741 case PT_Sint8: 742 return this->emitConstSint8(Value, E); 743 case PT_Uint8: 744 return this->emitConstUint8(Value, E); 745 case PT_Sint16: 746 return this->emitConstSint16(Value, E); 747 case PT_Uint16: 748 return this->emitConstUint16(Value, E); 749 case PT_Sint32: 750 return this->emitConstSint32(Value, E); 751 case PT_Uint32: 752 return this->emitConstUint32(Value, E); 753 case PT_Sint64: 754 return this->emitConstSint64(Value, E); 755 case PT_Uint64: 756 return this->emitConstUint64(Value, E); 757 case PT_Bool: 758 return this->emitConstBool(Value, E); 759 case PT_Ptr: 760 llvm_unreachable("Invalid integral type"); 761 break; 762 } 763 llvm_unreachable("unknown primitive type"); 764 } 765 766 template <class Emitter> 767 bool ByteCodeExprGen<Emitter>::emitConst(const APSInt &Value, const Expr *E) { 768 if (Value.isSigned()) 769 return this->emitConst(Value.getSExtValue(), E); 770 return this->emitConst(Value.getZExtValue(), E); 771 } 772 773 template <class Emitter> 774 unsigned ByteCodeExprGen<Emitter>::allocateLocalPrimitive(DeclTy &&Src, 775 PrimType Ty, 776 bool IsConst, 777 bool IsExtended) { 778 // Make sure we don't accidentally register the same decl twice. 779 if (const auto *VD = 780 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) { 781 assert(!P.getGlobal(VD)); 782 assert(Locals.find(VD) == Locals.end()); 783 } 784 785 // FIXME: There are cases where Src.is<Expr*>() is wrong, e.g. 786 // (int){12} in C. Consider using Expr::isTemporaryObject() instead 787 // or isa<MaterializeTemporaryExpr>(). 788 Descriptor *D = P.createDescriptor(Src, Ty, Descriptor::InlineDescMD, IsConst, 789 Src.is<const Expr *>()); 790 Scope::Local Local = this->createLocal(D); 791 if (auto *VD = dyn_cast_or_null<ValueDecl>(Src.dyn_cast<const Decl *>())) 792 Locals.insert({VD, Local}); 793 VarScope->add(Local, IsExtended); 794 return Local.Offset; 795 } 796 797 template <class Emitter> 798 std::optional<unsigned> 799 ByteCodeExprGen<Emitter>::allocateLocal(DeclTy &&Src, bool IsExtended) { 800 // Make sure we don't accidentally register the same decl twice. 801 if (const auto *VD = 802 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) { 803 assert(!P.getGlobal(VD)); 804 assert(Locals.find(VD) == Locals.end()); 805 } 806 807 QualType Ty; 808 const ValueDecl *Key = nullptr; 809 const Expr *Init = nullptr; 810 bool IsTemporary = false; 811 if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) { 812 Key = VD; 813 Ty = VD->getType(); 814 815 if (const auto *VarD = dyn_cast<VarDecl>(VD)) 816 Init = VarD->getInit(); 817 } 818 if (auto *E = Src.dyn_cast<const Expr *>()) { 819 IsTemporary = true; 820 Ty = E->getType(); 821 } 822 823 Descriptor *D = P.createDescriptor( 824 Src, Ty.getTypePtr(), Descriptor::InlineDescMD, Ty.isConstQualified(), 825 IsTemporary, /*IsMutable=*/false, Init); 826 if (!D) 827 return {}; 828 829 Scope::Local Local = this->createLocal(D); 830 if (Key) 831 Locals.insert({Key, Local}); 832 VarScope->add(Local, IsExtended); 833 return Local.Offset; 834 } 835 836 // NB: When calling this function, we have a pointer to the 837 // array-to-initialize on the stack. 838 template <class Emitter> 839 bool ByteCodeExprGen<Emitter>::visitArrayInitializer(const Expr *Initializer) { 840 assert(Initializer->getType()->isArrayType()); 841 842 // TODO: Fillers? 843 if (const auto *InitList = dyn_cast<InitListExpr>(Initializer)) { 844 unsigned ElementIndex = 0; 845 for (const Expr *Init : InitList->inits()) { 846 if (std::optional<PrimType> T = classify(Init->getType())) { 847 // Visit the primitive element like normal. 848 if (!this->emitDupPtr(Init)) 849 return false; 850 if (!this->visit(Init)) 851 return false; 852 if (!this->emitInitElem(*T, ElementIndex, Init)) 853 return false; 854 } else { 855 // Advance the pointer currently on the stack to the given 856 // dimension and narrow(). 857 if (!this->emitDupPtr(Init)) 858 return false; 859 if (!this->emitConstUint32(ElementIndex, Init)) 860 return false; 861 if (!this->emitAddOffsetUint32(Init)) 862 return false; 863 if (!this->emitNarrowPtr(Init)) 864 return false; 865 866 if (!visitInitializer(Init)) 867 return false; 868 } 869 if (!this->emitPopPtr(Init)) 870 return false; 871 872 ++ElementIndex; 873 } 874 return true; 875 } else if (const auto *DIE = dyn_cast<CXXDefaultInitExpr>(Initializer)) { 876 return this->visitInitializer(DIE->getExpr()); 877 } else if (const auto *AILE = dyn_cast<ArrayInitLoopExpr>(Initializer)) { 878 // TODO: This compiles to quite a lot of bytecode if the array is larger. 879 // Investigate compiling this to a loop, or at least try to use 880 // the AILE's Common expr. 881 const Expr *SubExpr = AILE->getSubExpr(); 882 size_t Size = AILE->getArraySize().getZExtValue(); 883 std::optional<PrimType> ElemT = classify(SubExpr->getType()); 884 885 // So, every iteration, we execute an assignment here 886 // where the LHS is on the stack (the target array) 887 // and the RHS is our SubExpr. 888 for (size_t I = 0; I != Size; ++I) { 889 ArrayIndexScope<Emitter> IndexScope(this, I); 890 891 if (!this->emitDupPtr(SubExpr)) // LHS 892 return false; 893 894 if (ElemT) { 895 if (!this->visit(SubExpr)) 896 return false; 897 if (!this->emitInitElem(*ElemT, I, Initializer)) 898 return false; 899 } else { 900 // Narrow to our array element and recurse into visitInitializer() 901 if (!this->emitConstUint64(I, SubExpr)) 902 return false; 903 904 if (!this->emitAddOffsetUint64(SubExpr)) 905 return false; 906 907 if (!this->emitNarrowPtr(SubExpr)) 908 return false; 909 910 if (!visitInitializer(SubExpr)) 911 return false; 912 } 913 914 if (!this->emitPopPtr(Initializer)) 915 return false; 916 } 917 return true; 918 } else if (const auto *IVIE = dyn_cast<ImplicitValueInitExpr>(Initializer)) { 919 const ArrayType *AT = IVIE->getType()->getAsArrayTypeUnsafe(); 920 assert(AT); 921 const auto *CAT = cast<ConstantArrayType>(AT); 922 size_t NumElems = CAT->getSize().getZExtValue(); 923 924 if (std::optional<PrimType> ElemT = classify(CAT->getElementType())) { 925 // TODO(perf): For int and bool types, we can probably just skip this 926 // since we memset our Block*s to 0 and so we have the desired value 927 // without this. 928 for (size_t I = 0; I != NumElems; ++I) { 929 if (!this->emitZero(*ElemT, Initializer)) 930 return false; 931 if (!this->emitInitElem(*ElemT, I, Initializer)) 932 return false; 933 } 934 } else { 935 assert(false && "default initializer for non-primitive type"); 936 } 937 938 return true; 939 } else if (const auto *Ctor = dyn_cast<CXXConstructExpr>(Initializer)) { 940 const ConstantArrayType *CAT = 941 Ctx.getASTContext().getAsConstantArrayType(Ctor->getType()); 942 assert(CAT); 943 size_t NumElems = CAT->getSize().getZExtValue(); 944 const Function *Func = getFunction(Ctor->getConstructor()); 945 if (!Func || !Func->isConstexpr()) 946 return false; 947 948 // FIXME(perf): We're calling the constructor once per array element here, 949 // in the old intepreter we had a special-case for trivial constructors. 950 for (size_t I = 0; I != NumElems; ++I) { 951 if (!this->emitDupPtr(Initializer)) 952 return false; 953 if (!this->emitConstUint64(I, Initializer)) 954 return false; 955 if (!this->emitAddOffsetUint64(Initializer)) 956 return false; 957 if (!this->emitNarrowPtr(Initializer)) 958 return false; 959 960 // Constructor arguments. 961 for (const auto *Arg : Ctor->arguments()) { 962 if (!this->visit(Arg)) 963 return false; 964 } 965 966 if (!this->emitCall(Func, Initializer)) 967 return false; 968 } 969 return true; 970 } 971 972 assert(false && "Unknown expression for array initialization"); 973 return false; 974 } 975 976 template <class Emitter> 977 bool ByteCodeExprGen<Emitter>::visitRecordInitializer(const Expr *Initializer) { 978 Initializer = Initializer->IgnoreParenImpCasts(); 979 assert(Initializer->getType()->isRecordType()); 980 981 if (const auto CtorExpr = dyn_cast<CXXConstructExpr>(Initializer)) { 982 const Function *Func = getFunction(CtorExpr->getConstructor()); 983 984 if (!Func || !Func->isConstexpr()) 985 return false; 986 987 // The This pointer is already on the stack because this is an initializer, 988 // but we need to dup() so the call() below has its own copy. 989 if (!this->emitDupPtr(Initializer)) 990 return false; 991 992 // Constructor arguments. 993 for (const auto *Arg : CtorExpr->arguments()) { 994 if (!this->visit(Arg)) 995 return false; 996 } 997 998 return this->emitCall(Func, Initializer); 999 } else if (const auto *InitList = dyn_cast<InitListExpr>(Initializer)) { 1000 const Record *R = getRecord(InitList->getType()); 1001 1002 unsigned InitIndex = 0; 1003 for (const Expr *Init : InitList->inits()) { 1004 const Record::Field *FieldToInit = R->getField(InitIndex); 1005 1006 if (!this->emitDupPtr(Initializer)) 1007 return false; 1008 1009 if (std::optional<PrimType> T = classify(Init)) { 1010 if (!this->visit(Init)) 1011 return false; 1012 1013 if (!this->emitInitField(*T, FieldToInit->Offset, Initializer)) 1014 return false; 1015 1016 if (!this->emitPopPtr(Initializer)) 1017 return false; 1018 } else { 1019 // Non-primitive case. Get a pointer to the field-to-initialize 1020 // on the stack and recurse into visitInitializer(). 1021 if (!this->emitGetPtrField(FieldToInit->Offset, Init)) 1022 return false; 1023 1024 if (!this->visitInitializer(Init)) 1025 return false; 1026 1027 if (!this->emitPopPtr(Initializer)) 1028 return false; 1029 } 1030 ++InitIndex; 1031 } 1032 1033 return true; 1034 } else if (const CallExpr *CE = dyn_cast<CallExpr>(Initializer)) { 1035 // RVO functions expect a pointer to initialize on the stack. 1036 // Dup our existing pointer so it has its own copy to use. 1037 if (!this->emitDupPtr(Initializer)) 1038 return false; 1039 1040 return this->VisitCallExpr(CE); 1041 } else if (const auto *DIE = dyn_cast<CXXDefaultInitExpr>(Initializer)) { 1042 return this->visitInitializer(DIE->getExpr()); 1043 } 1044 1045 return false; 1046 } 1047 1048 template <class Emitter> 1049 bool ByteCodeExprGen<Emitter>::visitInitializer(const Expr *Initializer) { 1050 QualType InitializerType = Initializer->getType(); 1051 1052 if (InitializerType->isArrayType()) 1053 return visitArrayInitializer(Initializer); 1054 1055 if (InitializerType->isRecordType()) 1056 return visitRecordInitializer(Initializer); 1057 1058 // Otherwise, visit the expression like normal. 1059 return this->visit(Initializer); 1060 } 1061 1062 template <class Emitter> 1063 const RecordType *ByteCodeExprGen<Emitter>::getRecordTy(QualType Ty) { 1064 if (const PointerType *PT = dyn_cast<PointerType>(Ty)) 1065 return PT->getPointeeType()->getAs<RecordType>(); 1066 else 1067 return Ty->getAs<RecordType>(); 1068 } 1069 1070 template <class Emitter> 1071 Record *ByteCodeExprGen<Emitter>::getRecord(QualType Ty) { 1072 if (auto *RecordTy = getRecordTy(Ty)) { 1073 return getRecord(RecordTy->getDecl()); 1074 } 1075 return nullptr; 1076 } 1077 1078 template <class Emitter> 1079 Record *ByteCodeExprGen<Emitter>::getRecord(const RecordDecl *RD) { 1080 return P.getOrCreateRecord(RD); 1081 } 1082 1083 template <class Emitter> 1084 const Function *ByteCodeExprGen<Emitter>::getFunction(const FunctionDecl *FD) { 1085 assert(FD); 1086 const Function *Func = P.getFunction(FD); 1087 bool IsBeingCompiled = Func && !Func->isFullyCompiled(); 1088 bool WasNotDefined = Func && !Func->hasBody(); 1089 1090 if (IsBeingCompiled) 1091 return Func; 1092 1093 if (!Func || WasNotDefined) { 1094 if (auto R = ByteCodeStmtGen<ByteCodeEmitter>(Ctx, P).compileFunc(FD)) 1095 Func = *R; 1096 else { 1097 llvm::consumeError(R.takeError()); 1098 return nullptr; 1099 } 1100 } 1101 1102 return Func; 1103 } 1104 1105 template <class Emitter> 1106 bool ByteCodeExprGen<Emitter>::visitExpr(const Expr *Exp) { 1107 ExprScope<Emitter> RootScope(this); 1108 if (!visit(Exp)) 1109 return false; 1110 1111 if (std::optional<PrimType> T = classify(Exp)) 1112 return this->emitRet(*T, Exp); 1113 else 1114 return this->emitRetValue(Exp); 1115 } 1116 1117 /// Toplevel visitDecl(). 1118 /// We get here from evaluateAsInitializer(). 1119 /// We need to evaluate the initializer and return its value. 1120 template <class Emitter> 1121 bool ByteCodeExprGen<Emitter>::visitDecl(const VarDecl *VD) { 1122 std::optional<PrimType> VarT = classify(VD->getType()); 1123 1124 // Create and initialize the variable. 1125 if (!this->visitVarDecl(VD)) 1126 return false; 1127 1128 // Get a pointer to the variable 1129 if (shouldBeGloballyIndexed(VD)) { 1130 auto GlobalIndex = P.getGlobal(VD); 1131 assert(GlobalIndex); // visitVarDecl() didn't return false. 1132 if (!this->emitGetPtrGlobal(*GlobalIndex, VD)) 1133 return false; 1134 } else { 1135 auto Local = Locals.find(VD); 1136 assert(Local != Locals.end()); // Same here. 1137 if (!this->emitGetPtrLocal(Local->second.Offset, VD)) 1138 return false; 1139 } 1140 1141 // Return the value 1142 if (VarT) { 1143 if (!this->emitLoadPop(*VarT, VD)) 1144 return false; 1145 1146 return this->emitRet(*VarT, VD); 1147 } 1148 1149 return this->emitRetValue(VD); 1150 } 1151 1152 template <class Emitter> 1153 bool ByteCodeExprGen<Emitter>::visitVarDecl(const VarDecl *VD) { 1154 const Expr *Init = VD->getInit(); 1155 std::optional<PrimType> VarT = classify(VD->getType()); 1156 1157 if (shouldBeGloballyIndexed(VD)) { 1158 std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(VD, Init); 1159 1160 if (!GlobalIndex) 1161 return this->bail(VD); 1162 1163 assert(Init); 1164 { 1165 DeclScope<Emitter> LocalScope(this, VD); 1166 1167 if (VarT) { 1168 if (!this->visit(Init)) 1169 return false; 1170 return this->emitInitGlobal(*VarT, *GlobalIndex, VD); 1171 } 1172 return this->visitGlobalInitializer(Init, *GlobalIndex); 1173 } 1174 } else { 1175 VariableScope<Emitter> LocalScope(this); 1176 if (VarT) { 1177 unsigned Offset = this->allocateLocalPrimitive( 1178 VD, *VarT, VD->getType().isConstQualified()); 1179 if (Init) { 1180 // Compile the initializer in its own scope. 1181 ExprScope<Emitter> Scope(this); 1182 if (!this->visit(Init)) 1183 return false; 1184 1185 return this->emitSetLocal(*VarT, Offset, VD); 1186 } 1187 } else { 1188 if (std::optional<unsigned> Offset = this->allocateLocal(VD)) { 1189 if (Init) 1190 return this->visitLocalInitializer(Init, *Offset); 1191 } 1192 } 1193 return true; 1194 } 1195 1196 return false; 1197 } 1198 1199 template <class Emitter> 1200 bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) { 1201 assert(!E->getBuiltinCallee() && "Builtin functions aren't supported yet"); 1202 1203 const Decl *Callee = E->getCalleeDecl(); 1204 if (const auto *FuncDecl = dyn_cast_or_null<FunctionDecl>(Callee)) { 1205 const Function *Func = getFunction(FuncDecl); 1206 if (!Func) 1207 return false; 1208 // If the function is being compiled right now, this is a recursive call. 1209 // In that case, the function can't be valid yet, even though it will be 1210 // later. 1211 // If the function is already fully compiled but not constexpr, it was 1212 // found to be faulty earlier on, so bail out. 1213 if (Func->isFullyCompiled() && !Func->isConstexpr()) 1214 return false; 1215 1216 QualType ReturnType = E->getCallReturnType(Ctx.getASTContext()); 1217 std::optional<PrimType> T = classify(ReturnType); 1218 1219 if (Func->hasRVO() && DiscardResult) { 1220 // If we need to discard the return value but the function returns its 1221 // value via an RVO pointer, we need to create one such pointer just 1222 // for this call. 1223 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) { 1224 if (!this->emitGetPtrLocal(*LocalIndex, E)) 1225 return false; 1226 } 1227 } 1228 1229 // Put arguments on the stack. 1230 for (const auto *Arg : E->arguments()) { 1231 if (!this->visit(Arg)) 1232 return false; 1233 } 1234 1235 // In any case call the function. The return value will end up on the stack and 1236 // if the function has RVO, we already have the pointer on the stack to write 1237 // the result into. 1238 if (!this->emitCall(Func, E)) 1239 return false; 1240 1241 if (DiscardResult && !ReturnType->isVoidType() && T) 1242 return this->emitPop(*T, E); 1243 1244 return true; 1245 } else { 1246 assert(false && "We don't support non-FunctionDecl callees right now."); 1247 } 1248 1249 return false; 1250 } 1251 1252 template <class Emitter> 1253 bool ByteCodeExprGen<Emitter>::VisitCXXMemberCallExpr( 1254 const CXXMemberCallExpr *E) { 1255 // Get a This pointer on the stack. 1256 if (!this->visit(E->getImplicitObjectArgument())) 1257 return false; 1258 1259 return VisitCallExpr(E); 1260 } 1261 1262 template <class Emitter> 1263 bool ByteCodeExprGen<Emitter>::VisitCXXDefaultInitExpr( 1264 const CXXDefaultInitExpr *E) { 1265 return this->visit(E->getExpr()); 1266 } 1267 1268 template <class Emitter> 1269 bool ByteCodeExprGen<Emitter>::VisitCXXDefaultArgExpr( 1270 const CXXDefaultArgExpr *E) { 1271 return this->visit(E->getExpr()); 1272 } 1273 1274 template <class Emitter> 1275 bool ByteCodeExprGen<Emitter>::VisitCXXBoolLiteralExpr( 1276 const CXXBoolLiteralExpr *E) { 1277 if (DiscardResult) 1278 return true; 1279 1280 return this->emitConstBool(E->getValue(), E); 1281 } 1282 1283 template <class Emitter> 1284 bool ByteCodeExprGen<Emitter>::VisitCXXNullPtrLiteralExpr( 1285 const CXXNullPtrLiteralExpr *E) { 1286 if (DiscardResult) 1287 return true; 1288 1289 return this->emitNullPtr(E); 1290 } 1291 1292 template <class Emitter> 1293 bool ByteCodeExprGen<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) { 1294 if (DiscardResult) 1295 return true; 1296 return this->emitThis(E); 1297 } 1298 1299 template <class Emitter> 1300 bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { 1301 const Expr *SubExpr = E->getSubExpr(); 1302 std::optional<PrimType> T = classify(SubExpr->getType()); 1303 1304 // TODO: Support pointers for inc/dec operators. 1305 switch (E->getOpcode()) { 1306 case UO_PostInc: { // x++ 1307 if (!this->visit(SubExpr)) 1308 return false; 1309 1310 return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E); 1311 } 1312 case UO_PostDec: { // x-- 1313 if (!this->visit(SubExpr)) 1314 return false; 1315 1316 return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E); 1317 } 1318 case UO_PreInc: { // ++x 1319 if (!this->visit(SubExpr)) 1320 return false; 1321 1322 // Post-inc and pre-inc are the same if the value is to be discarded. 1323 if (DiscardResult) 1324 return this->emitIncPop(*T, E); 1325 1326 this->emitLoad(*T, E); 1327 this->emitConst(1, E); 1328 this->emitAdd(*T, E); 1329 return this->emitStore(*T, E); 1330 } 1331 case UO_PreDec: { // --x 1332 if (!this->visit(SubExpr)) 1333 return false; 1334 1335 // Post-dec and pre-dec are the same if the value is to be discarded. 1336 if (DiscardResult) 1337 return this->emitDecPop(*T, E); 1338 1339 this->emitLoad(*T, E); 1340 this->emitConst(1, E); 1341 this->emitSub(*T, E); 1342 return this->emitStore(*T, E); 1343 } 1344 case UO_LNot: // !x 1345 if (!this->visit(SubExpr)) 1346 return false; 1347 // The Inv doesn't change anything, so skip it if we don't need the result. 1348 return DiscardResult ? this->emitPop(*T, E) : this->emitInvBool(E); 1349 case UO_Minus: // -x 1350 if (!this->visit(SubExpr)) 1351 return false; 1352 return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E); 1353 case UO_Plus: // +x 1354 if (!this->visit(SubExpr)) // noop 1355 return false; 1356 return DiscardResult ? this->emitPop(*T, E) : true; 1357 case UO_AddrOf: // &x 1358 // We should already have a pointer when we get here. 1359 if (!this->visit(SubExpr)) 1360 return false; 1361 return DiscardResult ? this->emitPop(*T, E) : true; 1362 case UO_Deref: // *x 1363 return dereference( 1364 SubExpr, DerefKind::Read, 1365 [](PrimType) { 1366 llvm_unreachable("Dereferencing requires a pointer"); 1367 return false; 1368 }, 1369 [this, E](PrimType T) { 1370 return DiscardResult ? this->emitPop(T, E) : true; 1371 }); 1372 case UO_Not: // ~x 1373 if (!this->visit(SubExpr)) 1374 return false; 1375 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E); 1376 case UO_Real: // __real x 1377 case UO_Imag: // __imag x 1378 case UO_Extension: 1379 case UO_Coawait: 1380 assert(false && "Unhandled opcode"); 1381 } 1382 1383 return false; 1384 } 1385 1386 template <class Emitter> 1387 bool ByteCodeExprGen<Emitter>::VisitDeclRefExpr(const DeclRefExpr *E) { 1388 const auto *Decl = E->getDecl(); 1389 // References are implemented via pointers, so when we see a DeclRefExpr 1390 // pointing to a reference, we need to get its value directly (i.e. the 1391 // pointer to the actual value) instead of a pointer to the pointer to the 1392 // value. 1393 bool IsReference = Decl->getType()->isReferenceType(); 1394 1395 if (auto It = Locals.find(Decl); It != Locals.end()) { 1396 const unsigned Offset = It->second.Offset; 1397 1398 if (IsReference) 1399 return this->emitGetLocal(PT_Ptr, Offset, E); 1400 return this->emitGetPtrLocal(Offset, E); 1401 } else if (auto GlobalIndex = P.getGlobal(Decl)) { 1402 if (IsReference) 1403 return this->emitGetGlobal(PT_Ptr, *GlobalIndex, E); 1404 1405 return this->emitGetPtrGlobal(*GlobalIndex, E); 1406 } else if (const auto *PVD = dyn_cast<ParmVarDecl>(Decl)) { 1407 if (auto It = this->Params.find(PVD); It != this->Params.end()) { 1408 if (IsReference) 1409 return this->emitGetParam(PT_Ptr, It->second, E); 1410 return this->emitGetPtrParam(It->second, E); 1411 } 1412 } else if (const auto *ECD = dyn_cast<EnumConstantDecl>(Decl)) { 1413 return this->emitConst(ECD->getInitVal(), E); 1414 } 1415 1416 return false; 1417 } 1418 1419 template <class Emitter> 1420 void ByteCodeExprGen<Emitter>::emitCleanup() { 1421 for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent()) 1422 C->emitDestruction(); 1423 } 1424 1425 namespace clang { 1426 namespace interp { 1427 1428 template class ByteCodeExprGen<ByteCodeEmitter>; 1429 template class ByteCodeExprGen<EvalEmitter>; 1430 1431 } // namespace interp 1432 } // namespace clang 1433