clang: lib/CodeGen/CGExprAgg.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

28#include "llvm/IR/Constants.h"

29#include "llvm/IR/Function.h"

30#include "llvm/IR/GlobalVariable.h"

31#include "llvm/IR/Instruction.h"

32#include "llvm/IR/IntrinsicInst.h"

33#include "llvm/IR/Intrinsics.h"

34using namespace clang;

36

37

38

39

40

41namespace llvm {

43}

44

45namespace {

46class AggExprEmitter : public StmtVisitor {

47 CodeGenFunction &CGF;

48 CGBuilderTy &Builder;

49 AggValueSlot Dest;

50 bool IsResultUnused;

51

52 AggValueSlot EnsureSlot(QualType T) {

53 if (!Dest.isIgnored()) return Dest;

55 }

56 void EnsureDest(QualType T) {

59 }

60

61

62

63

64

65

66

67 void withReturnValueSlot(const Expr *E,

68 llvm::function_ref<RValue(ReturnValueSlot)> Fn);

69

70 void DoZeroInitPadding(uint64_t &PaddingStart, uint64_t PaddingEnd,

71 const FieldDecl *NextField);

72

73public:

74 AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest, bool IsResultUnused)

75 : CGF(cgf), Builder(CGF.Builder), Dest(Dest),

76 IsResultUnused(IsResultUnused) { }

77

78

79

80

81

82

83

84

85 void EmitAggLoadOfLValue(const Expr *E);

86

87

88

89 void EmitFinalDestCopy(QualType type, const LValue &src,

92 void EmitFinalDestCopy(QualType type, RValue src);

93 void EmitCopy(QualType type, const AggValueSlot &dest,

94 const AggValueSlot &src);

95

96 void EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, QualType ArrayQTy,

97 Expr *ExprToVisit, ArrayRef<Expr *> Args,

98 Expr *ArrayFiller);

99

101 if (CGF.getLangOpts().getGC() && TypeRequiresGCollection(T))

104 }

105

106 bool TypeRequiresGCollection(QualType T);

107

108

109

110

111

112 void Visit(Expr *E) {

113 ApplyDebugLocation DL(CGF, E);

114 StmtVisitor::Visit(E);

115 }

116

117 void VisitStmt(Stmt *S) {

119 }

120 void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }

121 void VisitGenericSelectionExpr(GenericSelectionExpr *GE) {

122 Visit(GE->getResultExpr());

123 }

124 void VisitCoawaitExpr(CoawaitExpr *E) {

126 }

127 void VisitCoyieldExpr(CoyieldExpr *E) {

129 }

130 void VisitUnaryCoawait(UnaryOperator *E) { Visit(E->getSubExpr()); }

131 void VisitUnaryExtension(UnaryOperator *E) { Visit(E->getSubExpr()); }

132 void VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {

134 }

135

136 void VisitConstantExpr(ConstantExpr *E) {

137 EnsureDest(E->getType());

138

139 if (llvm::Value *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {

142 llvm::TypeSize::getFixed(

146 return;

147 }

149 }

150

151

152 void VisitDeclRefExpr(DeclRefExpr *E) { EmitAggLoadOfLValue(E); }

153 void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }

154 void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }

155 void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }

156 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);

157 void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {

158 EmitAggLoadOfLValue(E);

159 }

160 void VisitPredefinedExpr(const PredefinedExpr *E) {

161 EmitAggLoadOfLValue(E);

162 }

163

164

165 void VisitCastExpr(CastExpr *E);

166 void VisitCallExpr(const CallExpr *E);

167 void VisitStmtExpr(const StmtExpr *E);

168 void VisitBinaryOperator(const BinaryOperator *BO);

169 void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *BO);

170 void VisitBinAssign(const BinaryOperator *E);

171 void VisitBinComma(const BinaryOperator *E);

172 void VisitBinCmp(const BinaryOperator *E);

173 void VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {

175 }

176

177 void VisitObjCMessageExpr(ObjCMessageExpr *E);

178 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {

179 EmitAggLoadOfLValue(E);

180 }

181

182 void VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E);

183 void VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO);

184 void VisitChooseExpr(const ChooseExpr *CE);

185 void VisitInitListExpr(InitListExpr *E);

186 void VisitCXXParenListOrInitListExpr(Expr *ExprToVisit, ArrayRef<Expr *> Args,

187 FieldDecl *InitializedFieldInUnion,

188 Expr *ArrayFiller);

189 void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E,

190 llvm::Value *outerBegin = nullptr);

191 void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);

192 void VisitNoInitExpr(NoInitExpr *E) { }

193 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {

194 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);

196 }

197 void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {

198 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);

200 }

201 void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);

202 void VisitCXXConstructExpr(const CXXConstructExpr *E);

203 void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E);

205 void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);

206 void VisitExprWithCleanups(ExprWithCleanups *E);

207 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);

208 void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }

209 void VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);

210 void VisitOpaqueValueExpr(OpaqueValueExpr *E);

211

212 void VisitPseudoObjectExpr(PseudoObjectExpr *E) {

215 return EmitFinalDestCopy(E->getType(), LV);

216 }

217

218 AggValueSlot Slot = EnsureSlot(E->getType());

219 bool NeedsDestruction =

222 if (NeedsDestruction)

225 if (NeedsDestruction)

228 }

229

230 void VisitVAArgExpr(VAArgExpr *E);

231 void VisitCXXParenListInitExpr(CXXParenListInitExpr *E);

232 void VisitCXXParenListOrInitListExpr(Expr *ExprToVisit, ArrayRef<Expr *> Args,

233 Expr *ArrayFiller);

234

235 void EmitInitializationToLValue(Expr *E, LValue Address);

236 void EmitNullInitializationToLValue(LValue Address);

237

238 void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); }

239 void VisitAtomicExpr(AtomicExpr *E) {

241 EmitFinalDestCopy(E->getType(), Res);

242 }

243 void VisitPackIndexingExpr(PackIndexingExpr *E) {

245 }

246};

247}

248

249

250

251

252

253

254

255

256void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {

258

259

262 return;

263 }

264

265 EmitFinalDestCopy(E->getType(), LV);

266}

267

268

269bool AggExprEmitter::TypeRequiresGCollection(QualType T) {

270

273 return false;

274

275

279 return false;

280

281

283}

284

285void AggExprEmitter::withReturnValueSlot(

286 const Expr *E, llvm::function_ref<RValue(ReturnValueSlot)> EmitCall) {

287 QualType RetTy = E->getType();

288 bool RequiresDestruction =

291

292

293

294

295

296

298 (RequiresDestruction && Dest.isIgnored());

299

301

302 EHScopeStack::stable_iterator LifetimeEndBlock;

303 llvm::IntrinsicInst *LifetimeStartInst = nullptr;

304 if (!UseTemp) {

306 } else {

309 LifetimeStartInst =

311 assert(LifetimeStartInst->getIntrinsicID() ==

312 llvm::Intrinsic::lifetime_start &&

313 "Last insertion wasn't a lifetime.start?");

314

318 }

319 }

320

321 RValue Src =

322 EmitCall(ReturnValueSlot(RetAddr, Dest.isVolatile(), IsResultUnused,

324

325 if (!UseTemp)

326 return;

327

330 EmitFinalDestCopy(E->getType(), Src);

331

332 if (!RequiresDestruction && LifetimeStartInst) {

333

334

335

338 }

339}

340

341

342void AggExprEmitter::EmitFinalDestCopy(QualType type, RValue src) {

343 assert(src.isAggregate() && "value must be aggregate value!");

346}

347

348

349void AggExprEmitter::EmitFinalDestCopy(

350 QualType type, const LValue &src,

352

353

354

355

357 return;

358

359

362

367 else

369 return;

370 }

371 } else {

375 else

377 return;

378 }

379 }

380

384 EmitCopy(type, Dest, srcAgg);

385}

386

387

388

389

390

391void AggExprEmitter::EmitCopy(QualType type, const AggValueSlot &dest,

392 const AggValueSlot &src) {

395 llvm::Value *size = llvm::ConstantInt::get(CGF.SizeTy, sz.getQuantity());

399 size);

400 return;

401 }

402

403

404

405

410}

411

412

413

414void

415AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {

416

417

420 assert(Array.isSimple() && "initializer_list array not a simple lvalue");

421 Address ArrayPtr = Array.getAddress();

422

423 const ConstantArrayType *ArrayType =

425 assert(ArrayType && "std::initializer_list constructed from non-array");

426

429 assert(Field != Record->field_end() &&

432 "Expected std::initializer_list first field to be const E *");

433

434

435 AggValueSlot Dest = EnsureSlot(E->getType());

438 llvm::Value *ArrayStart = ArrayPtr.emitRawPointer(CGF);

441 assert(Field != Record->field_end() &&

442 "Expected std::initializer_list to have two fields");

443

444 llvm::Value *Size = Builder.getInt(ArrayType->getSize());

447

449

450 } else {

451

452 assert(Field->getType()->isPointerType() &&

455 "Expected std::initializer_list second field to be const E *");

456 llvm::Value *Zero = llvm::ConstantInt::get(CGF.PtrDiffTy, 0);

457 llvm::Value *IdxEnd[] = { Zero, Size };

458 llvm::Value *ArrayEnd = Builder.CreateInBoundsGEP(

460 "arrayend");

462 }

463

464 assert(++Field == Record->field_end() &&

465 "Expected std::initializer_list to only have two fields");

466}

467

468

469

471 if (!E)

472 return true;

473

475 return true;

476

477 if (auto *ILE = dyn_cast(E)) {

478 if (ILE->getNumInits())

479 return false;

481 }

482

483 if (auto *Cons = dyn_cast_or_null(E))

484 return Cons->getConstructor()->isDefaultConstructor() &&

485 Cons->getConstructor()->isTrivial();

486

487

488 return false;

489}

490

491

492

494 LValue DestVal,

495 llvm::Value *SrcVal,

498

501

505 SrcTy = VT->getElementType();

506 assert(StoreList.size() <= VT->getNumElements() &&

507 "Cannot perform HLSL flat cast when vector source \

508 object has less elements than flattened destination \

509 object.");

510 }

511

512 for (unsigned I = 0, Size = StoreList.size(); I < Size; I++) {

513 LValue DestLVal = StoreList[I];

514 llvm::Value *Load =

515 isVector ? CGF.Builder.CreateExtractElement(SrcVal, I, "vec.load")

516 : SrcVal;

517 llvm::Value *Cast =

520 }

521}

522

523

526

529

532

533 assert(StoreList.size() <= LoadList.size() &&

534 "Cannot perform HLSL elementwise cast when flattened source object \

535 has less elements than flattened destination object.");

536

537

538 for (unsigned I = 0, E = StoreList.size(); I < E; I++) {

539 LValue DestLVal = StoreList[I];

540 LValue SrcLVal = LoadList[I];

542 assert(RVal.isScalar() && "All flattened source values should be scalars");

545 DestLVal.getType(), Loc);

547 }

548}

549

550

551

552void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,

553 QualType ArrayQTy, Expr *ExprToVisit,

554 ArrayRef<Expr *> Args, Expr *ArrayFiller) {

555 uint64_t NumInitElements = Args.size();

556

557 uint64_t NumArrayElements = AType->getNumElements();

558 for (const auto *Init : Args) {

559 if (const auto *Embed = dyn_cast(Init->IgnoreParenImpCasts())) {

560 NumInitElements += Embed->getDataElementCount() - 1;

561 if (NumInitElements > NumArrayElements) {

562 NumInitElements = NumArrayElements;

563 break;

564 }

565 }

566 }

567

568 assert(NumInitElements <= NumArrayElements);

569

570 QualType elementType =

573 CharUnits elementAlign =

575 llvm::Type *llvmElementType = CGF.ConvertTypeForMem(elementType);

576

577

578

579

580 if (NumInitElements * elementSize.getQuantity() > 16 &&

582 CodeGen::CodeGenModule &CGM = CGF.CGM;

583 ConstantEmitter Emitter(CGF);

588 if (llvm::Constant *C =

589 Emitter.tryEmitForInitializer(ExprToVisit, AS, GVArrayQTy)) {

590 auto GV = new llvm::GlobalVariable(

592 true, llvm::GlobalValue::PrivateLinkage, C,

593 "constinit",

594 nullptr, llvm::GlobalVariable::NotThreadLocal,

596 Emitter.finalize(GV);

598 GV->setAlignment(Align.getAsAlign());

599 Address GVAddr(GV, GV->getValueType(), Align);

600 EmitFinalDestCopy(ArrayQTy, CGF.MakeAddrLValue(GVAddr, GVArrayQTy));

601 return;

602 }

603 }

604

605

606

607

610 CodeGenFunction::CleanupDeactivationScope deactivation(CGF);

611

613 if (dtorKind) {

614 CodeGenFunction::AllocaTrackerRAII allocaTracker(CGF);

615

616

617

618

619 llvm::Instruction *dominatingIP =

620 Builder.CreateFlagLoad(llvm::ConstantInt::getNullValue(CGF.Int8PtrTy));

622 "arrayinit.endOfInit");

623 Builder.CreateStore(begin, endOfInit);

625 elementAlign,

628 .AddAuxAllocas(allocaTracker.Take());

629

632 }

633

634 llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1);

635

636 auto Emit = [&](Expr *Init, uint64_t ArrayIndex) {

637 llvm::Value *element = begin;

638 if (ArrayIndex > 0) {

639 element = Builder.CreateInBoundsGEP(

640 llvmElementType, begin,

641 llvm::ConstantInt::get(CGF.SizeTy, ArrayIndex), "arrayinit.element");

642

643

644

645

647 Builder.CreateStore(element, endOfInit);

648 }

649

651 Address(element, llvmElementType, elementAlign), elementType);

652 EmitInitializationToLValue(Init, elementLV);

653 return true;

654 };

655

656 unsigned ArrayIndex = 0;

657

658 for (uint64_t i = 0; i != NumInitElements; ++i) {

659 if (ArrayIndex >= NumInitElements)

660 break;

661 if (auto *EmbedS = dyn_cast(Args[i]->IgnoreParenImpCasts())) {

662 EmbedS->doForEachDataElement(Emit, ArrayIndex);

663 } else {

664 Emit(Args[i], ArrayIndex);

665 ArrayIndex++;

666 }

667 }

668

669

671

672

673

674

675 if (NumInitElements != NumArrayElements &&

676 !(Dest.isZeroed() && hasTrivialFiller &&

678

679

680

681

682

683 llvm::Value *element = begin;

684 if (NumInitElements) {

685 element = Builder.CreateInBoundsGEP(

686 llvmElementType, element,

687 llvm::ConstantInt::get(CGF.SizeTy, NumInitElements),

688 "arrayinit.start");

689 if (endOfInit.isValid()) Builder.CreateStore(element, endOfInit);

690 }

691

692

693 llvm::Value *end = Builder.CreateInBoundsGEP(

694 llvmElementType, begin,

695 llvm::ConstantInt::get(CGF.SizeTy, NumArrayElements), "arrayinit.end");

696

697 llvm::BasicBlock *entryBB = Builder.GetInsertBlock();

698 llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body");

699

700

702 llvm::PHINode *currentElement =

703 Builder.CreatePHI(element->getType(), 2, "arrayinit.cur");

704 currentElement->addIncoming(element, entryBB);

705

706

707 {

708

709

710

711

712

713 CodeGenFunction::RunCleanupsScope CleanupsScope(CGF);

715 Address(currentElement, llvmElementType, elementAlign), elementType);

716 if (ArrayFiller)

717 EmitInitializationToLValue(ArrayFiller, elementLV);

718 else

719 EmitNullInitializationToLValue(elementLV);

720 }

721

722

723 llvm::Value *nextElement = Builder.CreateInBoundsGEP(

724 llvmElementType, currentElement, one, "arrayinit.next");

725

726

727 if (endOfInit.isValid()) Builder.CreateStore(nextElement, endOfInit);

728

729

730 llvm::Value *done = Builder.CreateICmpEQ(nextElement, end,

731 "arrayinit.done");

732 llvm::BasicBlock *endBB = CGF.createBasicBlock("arrayinit.end");

733 Builder.CreateCondBr(done, endBB, bodyBB);

734 currentElement->addIncoming(nextElement, Builder.GetInsertBlock());

735

737 }

738}

739

740

741

742

743

744void AggExprEmitter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E){

746}

747

748void AggExprEmitter::VisitOpaqueValueExpr(OpaqueValueExpr *e) {

749

752 else

754}

755

756void

757AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {

759

760

761 EmitAggLoadOfLValue(E);

762 return;

763 }

764

765 AggValueSlot Slot = EnsureSlot(E->getType());

766

767

768

769 bool Destruct =

771 if (Destruct)

773

775

776 if (Destruct)

781}

782

783

784

787 if (auto castE = dyn_cast(op)) {

788 if (castE->getCastKind() == kind)

789 return castE->getSubExpr();

790 }

791 return nullptr;

792}

793

794void AggExprEmitter::VisitCastExpr(CastExpr *E) {

795 if (const auto *ECE = dyn_cast(E))

798 case CK_Dynamic: {

799

803

804 if (LV.isSimple())

806 else

808

811 break;

812 }

813

814 case CK_ToUnion: {

815

818 true);

819 break;

820 }

821

822

825 EmitInitializationToLValue(E->getSubExpr(),

827 break;

828 }

829

830 case CK_LValueToRValueBitCast: {

833 true);

834 break;

835 }

836

838 Address SourceAddress = SourceLV.getAddress().withElementType(CGF.Int8Ty);

840 llvm::Value *SizeVal = llvm::ConstantInt::get(

843 Builder.CreateMemCpy(DestAddress, SourceAddress, SizeVal);

844 break;

845 }

846

847 case CK_DerivedToBase:

848 case CK_BaseToDerived:

849 case CK_UncheckedDerivedToBase: {

850 llvm_unreachable("cannot perform hierarchy conversion in EmitAggExpr: "

851 "should have been unpacked before we got here");

852 }

853

854 case CK_NonAtomicToAtomic:

855 case CK_AtomicToNonAtomic: {

856 bool isToAtomic = (E->getCastKind() == CK_NonAtomicToAtomic);

857

858

860 QualType valueType = E->getType();

861 if (isToAtomic) std::swap(atomicType, valueType);

862

865 atomicType->castAs()->getValueType()));

866

867

868

871 }

872

874 (isToAtomic ? CK_AtomicToNonAtomic : CK_NonAtomicToAtomic);

875

876

877 if (Expr *op =

881 "peephole significantly changed types?");

882 return Visit(op);

883 }

884

885

886

887 if (isToAtomic) {

888 AggValueSlot valueDest = Dest;

890

891

894

895

896 Address valueAddr =

905 }

906

908 return;

909 }

910

911

912

913 AggValueSlot atomicSlot =

916

917 Address valueAddr = Builder.CreateStructGEP(atomicSlot.getAddress(), 0);

919 return EmitFinalDestCopy(valueType, rvalue);

920 }

921 case CK_AddressSpaceConversion:

923

924 case CK_LValueToRValue:

925

926

928 bool Destruct =

931 if (Destruct)

933 EnsureDest(E->getType());

935

936 if (Destruct)

939

940 return;

941 }

942

943 [[fallthrough]];

944

945 case CK_HLSLArrayRValue:

947 break;

948 case CK_HLSLAggregateSplatCast: {

950 QualType SrcTy = Src->getType();

953 SourceLocation Loc = E->getExprLoc();

954

956 "RHS of HLSL splat cast must be a scalar.");

959 break;

960 }

961 case CK_HLSLElementwiseCast: {

963 QualType SrcTy = Src->getType();

966 SourceLocation Loc = E->getExprLoc();

967

971 "HLSL Elementwise cast doesn't handle splatting.");

973 } else {

975 "Can't perform HLSL Aggregate cast on a complex type.");

978 Loc);

979 }

980 break;

981 }

982 case CK_NoOp:

983 case CK_UserDefinedConversion:

984 case CK_ConstructorConversion:

987 "Implicit cast types must be compatible");

989 break;

990

991 case CK_LValueBitCast:

992 llvm_unreachable("should not be emitting lvalue bitcast as rvalue");

993

994 case CK_Dependent:

995 case CK_BitCast:

996 case CK_ArrayToPointerDecay:

997 case CK_FunctionToPointerDecay:

998 case CK_NullToPointer:

999 case CK_NullToMemberPointer:

1000 case CK_BaseToDerivedMemberPointer:

1001 case CK_DerivedToBaseMemberPointer:

1002 case CK_MemberPointerToBoolean:

1003 case CK_ReinterpretMemberPointer:

1004 case CK_IntegralToPointer:

1005 case CK_PointerToIntegral:

1006 case CK_PointerToBoolean:

1007 case CK_ToVoid:

1008 case CK_VectorSplat:

1009 case CK_IntegralCast:

1010 case CK_BooleanToSignedIntegral:

1011 case CK_IntegralToBoolean:

1012 case CK_IntegralToFloating:

1013 case CK_FloatingToIntegral:

1014 case CK_FloatingToBoolean:

1015 case CK_FloatingCast:

1016 case CK_CPointerToObjCPointerCast:

1017 case CK_BlockPointerToObjCPointerCast:

1018 case CK_AnyPointerToBlockPointerCast:

1019 case CK_ObjCObjectLValueCast:

1020 case CK_FloatingRealToComplex:

1021 case CK_FloatingComplexToReal:

1022 case CK_FloatingComplexToBoolean:

1023 case CK_FloatingComplexCast:

1024 case CK_FloatingComplexToIntegralComplex:

1025 case CK_IntegralRealToComplex:

1026 case CK_IntegralComplexToReal:

1027 case CK_IntegralComplexToBoolean:

1028 case CK_IntegralComplexCast:

1029 case CK_IntegralComplexToFloatingComplex:

1030 case CK_ARCProduceObject:

1031 case CK_ARCConsumeObject:

1032 case CK_ARCReclaimReturnedObject:

1033 case CK_ARCExtendBlockObject:

1034 case CK_CopyAndAutoreleaseBlockObject:

1035 case CK_BuiltinFnToFnPtr:

1036 case CK_ZeroToOCLOpaqueType:

1037 case CK_MatrixCast:

1038 case CK_HLSLVectorTruncation:

1039 case CK_HLSLMatrixTruncation:

1040 case CK_IntToOCLSampler:

1041 case CK_FloatingToFixedPoint:

1042 case CK_FixedPointToFloating:

1043 case CK_FixedPointCast:

1044 case CK_FixedPointToBoolean:

1045 case CK_FixedPointToIntegral:

1046 case CK_IntegralToFixedPoint:

1047 llvm_unreachable("cast kind invalid for aggregate types");

1048 }

1049}

1050

1051void AggExprEmitter::VisitCallExpr(const CallExpr *E) {

1053 EmitAggLoadOfLValue(E);

1054 return;

1055 }

1056

1057 withReturnValueSlot(E, [&](ReturnValueSlot Slot) {

1059 });

1060}

1061

1062void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {

1063 withReturnValueSlot(E, [&](ReturnValueSlot Slot) {

1065 });

1066}

1067

1068void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {

1071}

1072

1073void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {

1074 CodeGenFunction::StmtExprEvaluation eval(CGF);

1076}

1077

1083

1087 const char *NameSuffix = "") {

1090 ArgTy = CT->getElementType();

1091

1094 "member pointers may only be compared for equality");

1096 CGF, LHS, RHS, MPT, false);

1097 }

1098

1099

1100 struct CmpInstInfo {

1101 const char *Name;

1102 llvm::CmpInst::Predicate FCmp;

1103 llvm::CmpInst::Predicate SCmp;

1104 llvm::CmpInst::Predicate UCmp;

1105 };

1106 CmpInstInfo InstInfo = [&]() -> CmpInstInfo {

1107 using FI = llvm::FCmpInst;

1108 using II = llvm::ICmpInst;

1109 switch (Kind) {

1111 return {"cmp.lt", FI::FCMP_OLT, II::ICMP_SLT, II::ICMP_ULT};

1113 return {"cmp.gt", FI::FCMP_OGT, II::ICMP_SGT, II::ICMP_UGT};

1115 return {"cmp.eq", FI::FCMP_OEQ, II::ICMP_EQ, II::ICMP_EQ};

1116 }

1117 llvm_unreachable("Unrecognised CompareKind enum");

1118 }();

1119

1121 return Builder.CreateFCmp(InstInfo.FCmp, LHS, RHS,

1122 llvm::Twine(InstInfo.Name) + NameSuffix);

1124 auto Inst =

1126 return Builder.CreateICmp(Inst, LHS, RHS,

1127 llvm::Twine(InstInfo.Name) + NameSuffix);

1128 }

1129

1130 llvm_unreachable("unsupported aggregate binary expression should have "

1131 "already been handled");

1132}

1133

1134void AggExprEmitter::VisitBinCmp(const BinaryOperator *E) {

1135 using llvm::BasicBlock;

1136 using llvm::PHINode;

1137 using llvm::Value;

1140 const ComparisonCategoryInfo &CmpInfo =

1143 "cannot copy non-trivially copyable aggregate");

1144

1146

1150 return CGF.ErrorUnsupported(E, "aggregate three-way comparison");

1151 }

1153

1154

1155 auto EmitOperand = [&](Expr *E) -> std::pair<Value *, Value *> {

1163 };

1164 auto LHSValues = EmitOperand(E->getLHS()),

1165 RHSValues = EmitOperand(E->getRHS());

1166

1168 Value *Cmp = EmitCompare(Builder, CGF, E, LHSValues.first, RHSValues.first,

1169 K, IsComplex ? ".r" : "");

1170 if (!IsComplex)

1171 return Cmp;

1173 Value *CmpImag = EmitCompare(Builder, CGF, E, LHSValues.second,

1174 RHSValues.second, K, ".i");

1175 return Builder.CreateAnd(Cmp, CmpImag, "and.eq");

1176 };

1177 auto EmitCmpRes = [&](const ComparisonCategoryInfo::ValueInfo *VInfo) {

1178 return Builder.getInt(VInfo->getIntValue());

1179 };

1180

1184 } else if (!CmpInfo.isPartial()) {

1185 Value *SelectOne =

1186 Builder.CreateSelect(EmitCmp(CK_Less), EmitCmpRes(CmpInfo.getLess()),

1187 EmitCmpRes(CmpInfo.getGreater()), "sel.lt");

1188 Select = Builder.CreateSelect(EmitCmp(CK_Equal),

1190 SelectOne, "sel.eq");

1191 } else {

1192 Value *SelectEq = Builder.CreateSelect(

1194 EmitCmpRes(CmpInfo.getUnordered()), "sel.eq");

1195 Value *SelectGT = Builder.CreateSelect(EmitCmp(CK_Greater),

1197 SelectEq, "sel.gt");

1198 Select = Builder.CreateSelect(

1199 EmitCmp(CK_Less), EmitCmpRes(CmpInfo.getLess()), SelectGT, "sel.lt");

1200 }

1201

1202 EnsureDest(E->getType());

1204

1205

1206

1210

1211

1212}

1213

1214void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {

1216 VisitPointerToDataMemberBinaryOperator(E);

1217 else

1219}

1220

1221void AggExprEmitter::VisitPointerToDataMemberBinaryOperator(

1222 const BinaryOperator *E) {

1224 EmitFinalDestCopy(E->getType(), LV);

1225}

1226

1227

1228

1230

1232

1233

1234 if (const DeclRefExpr *DRE = dyn_cast(E)) {

1235 const VarDecl *var = dyn_cast(DRE->getDecl());

1236 return (var && var->hasAttr());

1237 }

1238

1239

1240

1241

1242 if (const BinaryOperator *op = dyn_cast(E)) {

1243

1244

1245 if (op->isAssignmentOp() || op->isPtrMemOp())

1247

1248

1249 if (op->getOpcode() == BO_Comma)

1251

1252

1253 return false;

1254

1255

1257 = dyn_cast(E)) {

1260

1261

1263 = dyn_cast(E)) {

1264 if (const Expr *src = op->getSourceExpr())

1266

1267

1268

1269

1270

1271 } else if (const CastExpr *cast = dyn_cast(E)) {

1272 if (cast->getCastKind() == CK_LValueToRValue)

1273 return false;

1275

1276

1277

1278 } else if (const UnaryOperator *uop = dyn_cast(E)) {

1280

1281

1282 } else if (const MemberExpr *mem = dyn_cast(E)) {

1284

1285

1286 } else if (const ArraySubscriptExpr *sub = dyn_cast(E)) {

1288 }

1289

1290 return false;

1291}

1292

1293void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {

1295

1296

1299 && "Invalid assignment");

1300

1301

1302

1303

1304

1307

1310

1311

1313

1314

1315 if (LHS.getType()->isAtomicType() ||

1318 return;

1319 }

1320

1326 Dest);

1327 return;

1328 }

1329

1331

1332

1333

1334 if (LHS.getType()->isAtomicType() ||

1339 return;

1340 }

1341

1342

1346

1350

1352

1353

1354 EmitFinalDestCopy(E->getType(), LHS);

1355

1360}

1361

1362void AggExprEmitter::

1363VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {

1364 llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");

1365 llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");

1366 llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");

1367

1368

1369 CodeGenFunction::OpaqueValueMapping binding(CGF, E);

1370

1371 CodeGenFunction::ConditionalEvaluation eval(CGF);

1374

1375

1377 bool destructNonTrivialCStruct =

1378 !isExternallyDestructed &&

1380 isExternallyDestructed |= destructNonTrivialCStruct;

1382

1383 eval.begin(CGF);

1387 else

1390 eval.end(CGF);

1391

1392 assert(CGF.HaveInsertPoint() && "expression evaluation ended with no IP!");

1393 CGF.Builder.CreateBr(ContBlock);

1394

1395

1396

1397

1398

1400

1401 eval.begin(CGF);

1406 eval.end(CGF);

1407

1408 if (destructNonTrivialCStruct)

1411

1415}

1416

1417void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {

1419}

1420

1421void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {

1423 CGF.EmitVAArg(VE, ArgValue, Dest);

1424

1425

1426 if (!ArgValue.isValid()) {

1428 return;

1429 }

1430}

1431

1432void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {

1433

1434

1436 EnsureDest(E->getType());

1437

1438

1440

1442

1443

1444 if (!wasExternallyDestructed)

1446}

1447

1448void

1449AggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) {

1450 AggValueSlot Slot = EnsureSlot(E->getType());

1452}

1453

1454void AggExprEmitter::VisitCXXInheritedCtorInitExpr(

1455 const CXXInheritedCtorInitExpr *E) {

1456 AggValueSlot Slot = EnsureSlot(E->getType());

1460}

1461

1462void

1463AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {

1464 AggValueSlot Slot = EnsureSlot(E->getType());

1466

1467

1468

1469 CodeGenFunction::CleanupDeactivationScope scope(CGF);

1470

1474 i != e; ++i, ++CurField) {

1475

1477 if (CurField->hasCapturedVLAType()) {

1479 continue;

1480 }

1481

1482 EmitInitializationToLValue(*i, LV);

1483

1484

1486 CurField->getType().isDestructedType()) {

1487 assert(LV.isSimple());

1488 if (DtorKind)

1490 CurField->getType(),

1492 }

1493 }

1494}

1495

1496void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {

1497 CodeGenFunction::RunCleanupsScope cleanups(CGF);

1499}

1500

1501void AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {

1503 AggValueSlot Slot = EnsureSlot(T);

1505}

1506

1507void AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {

1509 AggValueSlot Slot = EnsureSlot(T);

1511}

1512

1513

1514

1515

1518

1519 case CK_NoOp:

1520 case CK_UserDefinedConversion:

1521 case CK_ConstructorConversion:

1522 case CK_BitCast:

1523 case CK_ToUnion:

1524 case CK_ToVoid:

1525

1526

1527 case CK_BooleanToSignedIntegral:

1528 case CK_FloatingCast:

1529 case CK_FloatingComplexCast:

1530 case CK_FloatingComplexToBoolean:

1531 case CK_FloatingComplexToIntegralComplex:

1532 case CK_FloatingComplexToReal:

1533 case CK_FloatingRealToComplex:

1534 case CK_FloatingToBoolean:

1535 case CK_FloatingToIntegral:

1536 case CK_IntegralCast:

1537 case CK_IntegralComplexCast:

1538 case CK_IntegralComplexToBoolean:

1539 case CK_IntegralComplexToFloatingComplex:

1540 case CK_IntegralComplexToReal:

1541 case CK_IntegralRealToComplex:

1542 case CK_IntegralToBoolean:

1543 case CK_IntegralToFloating:

1544

1545 case CK_IntegralToPointer:

1546 case CK_PointerToIntegral:

1547

1548 case CK_VectorSplat:

1549 case CK_MatrixCast:

1550 case CK_NonAtomicToAtomic:

1551 case CK_AtomicToNonAtomic:

1552 case CK_HLSLVectorTruncation:

1553 case CK_HLSLMatrixTruncation:

1554 case CK_HLSLElementwiseCast:

1555 case CK_HLSLAggregateSplatCast:

1556 return true;

1557

1558 case CK_BaseToDerivedMemberPointer:

1559 case CK_DerivedToBaseMemberPointer:

1560 case CK_MemberPointerToBoolean:

1561 case CK_NullToMemberPointer:

1562 case CK_ReinterpretMemberPointer:

1563

1564 return false;

1565

1566 case CK_AnyPointerToBlockPointerCast:

1567 case CK_BlockPointerToObjCPointerCast:

1568 case CK_CPointerToObjCPointerCast:

1569 case CK_ObjCObjectLValueCast:

1570 case CK_IntToOCLSampler:

1571 case CK_ZeroToOCLOpaqueType:

1572

1573 return false;

1574

1575 case CK_FixedPointCast:

1576 case CK_FixedPointToBoolean:

1577 case CK_FixedPointToFloating:

1578 case CK_FixedPointToIntegral:

1579 case CK_FloatingToFixedPoint:

1580 case CK_IntegralToFixedPoint:

1581

1582 return false;

1583

1584 case CK_AddressSpaceConversion:

1585 case CK_BaseToDerived:

1586 case CK_DerivedToBase:

1587 case CK_Dynamic:

1588 case CK_NullToPointer:

1589 case CK_PointerToBoolean:

1590

1591

1592 return false;

1593

1594 case CK_ARCConsumeObject:

1595 case CK_ARCExtendBlockObject:

1596 case CK_ARCProduceObject:

1597 case CK_ARCReclaimReturnedObject:

1598 case CK_CopyAndAutoreleaseBlockObject:

1599 case CK_ArrayToPointerDecay:

1600 case CK_FunctionToPointerDecay:

1601 case CK_BuiltinFnToFnPtr:

1602 case CK_Dependent:

1603 case CK_LValueBitCast:

1604 case CK_LValueToRValue:

1605 case CK_LValueToRValueBitCast:

1606 case CK_UncheckedDerivedToBase:

1607 case CK_HLSLArrayRValue:

1608 return false;

1609 }

1610 llvm_unreachable("Unhandled clang::CastKind enum");

1611}

1612

1613

1614

1615

1618 while (auto *CE = dyn_cast(E)) {

1620 break;

1622 }

1623

1624

1625 if (const IntegerLiteral *IL = dyn_cast(E))

1626 return IL->getValue() == 0;

1627

1628 if (const FloatingLiteral *FL = dyn_cast(E))

1629 return FL->getValue().isPosZero();

1630

1633 return true;

1634

1635 if (const CastExpr *ICE = dyn_cast(E))

1636 return ICE->getCastKind() == CK_NullToPointer &&

1639

1641 return CL->getValue() == 0;

1642

1643

1644 return false;

1645}

1646

1647

1648void

1649AggExprEmitter::EmitInitializationToLValue(Expr *E, LValue LV) {

1650 QualType type = LV.getType();

1651

1652

1654

1655 return;

1657 return EmitNullInitializationToLValue(LV);

1659

1660 return;

1661 } else if (type->isReferenceType()) {

1664 }

1665

1667}

1668

1669void AggExprEmitter::EmitNullInitializationToLValue(LValue lv) {

1670 QualType type = lv.getType();

1671

1672

1673

1675 return;

1676

1678

1680

1681

1682 if (lv.isBitField()) {

1684 } else {

1685 assert(lv.isSimple());

1687 }

1688 } else {

1689

1690

1691

1693 }

1694}

1695

1696void AggExprEmitter::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {

1697 VisitCXXParenListOrInitListExpr(E, E->getInitExprs(),

1700}

1701

1702void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {

1704 CGF.ErrorUnsupported(E, "GNU array range designator extension");

1705

1707 return Visit(E->getInit(0));

1708

1709 VisitCXXParenListOrInitListExpr(

1711}

1712

1713void AggExprEmitter::VisitCXXParenListOrInitListExpr(

1714 Expr *ExprToVisit, ArrayRef<Expr *> InitExprs,

1715 FieldDecl *InitializedFieldInUnion, Expr *ArrayFiller) {

1716#if 0

1717

1718

1719

1720

1721

1722 if (llvm::Constant *C =

1723 CGF.CGM.EmitConstantExpr(ExprToVisit, ExprToVisit->getType(), &CGF)) {

1724 llvm::GlobalVariable* GV =

1725 new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true,

1726 llvm::GlobalValue::InternalLinkage, C, "");

1727 EmitFinalDestCopy(ExprToVisit->getType(),

1729 return;

1730 }

1731#endif

1732

1733

1734

1735

1736

1737

1738

1739

1740

1744

1745 AggValueSlot Dest = EnsureSlot(ExprToVisit->getType());

1746

1748

1749

1752 EmitArrayInit(Dest.getAddress(), AType, ExprToVisit->getType(), ExprToVisit,

1753 InitExprs, ArrayFiller);

1754 return;

1756

1757

1758

1759 assert(InitExprs.size() == 0 &&

1760 "you can only use an empty initializer with VLAs");

1762 return;

1763 }

1764

1766 "Only support structs/unions here!");

1767

1768

1769

1770

1771

1772 unsigned NumInitElements = InitExprs.size();

1774

1775

1776

1777 CodeGenFunction::CleanupDeactivationScope DeactivateCleanups(CGF);

1778

1779 unsigned curInitIndex = 0;

1780

1781

1782 if (auto *CXXRD = dyn_cast(record)) {

1783 assert(NumInitElements >= CXXRD->getNumBases() &&

1784 "missing initializer for base class");

1785 for (auto &Base : CXXRD->bases()) {

1786 assert(Base.isVirtual() && "should not see vbases here");

1787 auto *BaseRD = Base.getType()->getAsCXXRecordDecl();

1790 false);

1792 V, Qualifiers(),

1797 CGF.EmitAggExpr(InitExprs[curInitIndex++], AggSlot);

1798

1800 Base.getType().isDestructedType())

1802 }

1803 }

1804

1805

1806 CodeGenFunction::FieldConstructionScope FCS(CGF, Dest.getAddress());

1807

1808 const bool ZeroInitPadding =

1810

1811 if (record->isUnion()) {

1812

1813

1814 if (!InitializedFieldInUnion) {

1815

1816

1817#ifndef NDEBUG

1818

1819

1820 for (const auto *Field : record->fields())

1821 assert(

1822 (Field->isUnnamedBitField() || Field->isAnonymousStructOrUnion()) &&

1823 "Only unnamed bitfields or anonymous class allowed");

1824#endif

1825 return;

1826 }

1827

1828

1829 FieldDecl *Field = InitializedFieldInUnion;

1830

1832 if (NumInitElements) {

1833

1834 EmitInitializationToLValue(InitExprs[0], FieldLoc);

1835 if (ZeroInitPadding) {

1839 DoZeroInitPadding(FieldSize, TotalSize, nullptr);

1840 }

1841 } else {

1842

1843 if (ZeroInitPadding)

1844 EmitNullInitializationToLValue(DestLV);

1845 else

1846 EmitNullInitializationToLValue(FieldLoc);

1847 }

1848 return;

1849 }

1850

1851

1852

1855

1856 for (const auto *field : record->fields()) {

1857

1858 if (field->getType()->isIncompleteArrayType())

1859 break;

1860

1861

1862 if (field->isUnnamedBitField())

1863 continue;

1864

1865

1866

1867

1868 if (curInitIndex == NumInitElements && Dest.isZeroed() &&

1870 break;

1871

1872 if (ZeroInitPadding)

1873 DoZeroInitPadding(PaddingStart,

1874 Layout.getFieldOffset(field->getFieldIndex()), field);

1875

1877

1878 LV.setNonGC(true);

1879

1880 if (curInitIndex < NumInitElements) {

1881

1882 EmitInitializationToLValue(InitExprs[curInitIndex++], LV);

1883 } else {

1884

1885 EmitNullInitializationToLValue(LV);

1886 }

1887

1888

1889

1890

1892 = field->getType().isDestructedType()) {

1893 assert(LV.isSimple());

1894 if (dtorKind) {

1896 field->getType(),

1898 }

1899 }

1900 }

1901 if (ZeroInitPadding) {

1904 DoZeroInitPadding(PaddingStart, TotalSize, nullptr);

1905 }

1906}

1907

1908void AggExprEmitter::DoZeroInitPadding(uint64_t &PaddingStart,

1909 uint64_t PaddingEnd,

1910 const FieldDecl *NextField) {

1911

1916 if (!Start.isZero())

1918 llvm::Constant *SizeVal = Builder.getInt64((End - Start).getQuantity());

1920 };

1921

1922 if (NextField != nullptr && NextField->isBitField()) {

1923

1924

1925 const CGRecordLayout &RL =

1927 const CGBitFieldInfo &Info = RL.getBitFieldInfo(NextField);

1929 if (StorageStart + Info.StorageSize > PaddingStart) {

1930 if (StorageStart > PaddingStart)

1931 InitBytes(PaddingStart, StorageStart);

1934 Addr = Builder.CreateConstGEP(Addr.withElementType(CGF.CharTy),

1936 Addr = Addr.withElementType(

1938 Builder.CreateStore(Builder.getIntN(Info.StorageSize, 0), Addr);

1939 PaddingStart = StorageStart + Info.StorageSize;

1940 }

1941 return;

1942 }

1943

1944 if (PaddingStart < PaddingEnd)

1945 InitBytes(PaddingStart, PaddingEnd);

1946 if (NextField != nullptr)

1947 PaddingStart =

1949}

1950

1951void AggExprEmitter::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E,

1952 llvm::Value *outerBegin) {

1953

1954 CodeGenFunction::OpaqueValueMapping binding(CGF, E->getCommonExpr());

1955

1956 Address destPtr = EnsureSlot(E->getType()).getAddress();

1958

1959 if (!numElements)

1960 return;

1961

1962

1963 llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);

1964 llvm::Value *indices[] = {zero, zero};

1965 llvm::Value *begin = Builder.CreateInBoundsGEP(destPtr.getElementType(),

1967 indices, "arrayinit.begin");

1968

1969

1970

1971 if (!outerBegin)

1972 outerBegin = begin;

1973 ArrayInitLoopExpr *InnerLoop = dyn_cast(E->getSubExpr());

1974

1975 QualType elementType =

1978 CharUnits elementAlign =

1980 llvm::Type *llvmElementType = CGF.ConvertTypeForMem(elementType);

1981

1982 llvm::BasicBlock *entryBB = Builder.GetInsertBlock();

1983 llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body");

1984

1985

1987 llvm::PHINode *index =

1988 Builder.CreatePHI(zero->getType(), 2, "arrayinit.index");

1989 index->addIncoming(zero, entryBB);

1990 llvm::Value *element =

1991 Builder.CreateInBoundsGEP(llvmElementType, begin, index);

1992

1993

1995 EHScopeStack::stable_iterator cleanup;

1997 if (outerBegin->getType() != element->getType())

1998 outerBegin = Builder.CreateBitCast(outerBegin, element->getType());

2000 elementAlign,

2003 } else {

2005 }

2006

2007

2008 {

2009

2010

2011 CodeGenFunction::RunCleanupsScope CleanupsScope(CGF);

2012 CodeGenFunction::ArrayInitLoopExprScope Scope(CGF, index);

2014 Address(element, llvmElementType, elementAlign), elementType);

2015

2016 if (InnerLoop) {

2017

2022 AggExprEmitter(CGF, elementSlot, false)

2023 .VisitArrayInitLoopExpr(InnerLoop, outerBegin);

2024 } else

2025 EmitInitializationToLValue(E->getSubExpr(), elementLV);

2026 }

2027

2028

2029 llvm::Value *nextIndex = Builder.CreateNUWAdd(

2030 index, llvm::ConstantInt::get(CGF.SizeTy, 1), "arrayinit.next");

2031 index->addIncoming(nextIndex, Builder.GetInsertBlock());

2032

2033

2034 llvm::Value *done = Builder.CreateICmpEQ(

2035 nextIndex, llvm::ConstantInt::get(CGF.SizeTy, numElements),

2036 "arrayinit.done");

2037 llvm::BasicBlock *endBB = CGF.createBasicBlock("arrayinit.end");

2038 Builder.CreateCondBr(done, endBB, bodyBB);

2039

2041

2042

2043 if (dtorKind)

2045}

2046

2047void AggExprEmitter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {

2048 AggValueSlot Dest = EnsureSlot(E->getType());

2049

2051 EmitInitializationToLValue(E->getBase(), DestLV);

2053}

2054

2055

2056

2057

2058

2059

2060

2061

2063 if (auto *MTE = dyn_cast(E))

2064 E = MTE->getSubExpr();

2066

2067

2069

2070

2071

2072 const InitListExpr *ILE = dyn_cast(E);

2074 ILE = dyn_cast(ILE->getInit(0));

2077

2078

2079

2080

2082 if (!RT->isUnionType()) {

2085

2086 unsigned ILEElement = 0;

2087 if (auto *CXXRD = dyn_cast(SD))

2088 while (ILEElement != CXXRD->getNumBases())

2089 NumNonZeroBytes +=

2091 for (const auto *Field : SD->fields()) {

2092

2093

2094 if (Field->getType()->isIncompleteArrayType() ||

2096 break;

2097 if (Field->isUnnamedBitField())

2098 continue;

2099

2100 const Expr *E = ILE->getInit(ILEElement++);

2101

2102

2103 if (Field->getType()->isReferenceType())

2106 else

2108 }

2109

2110 return NumNonZeroBytes;

2111 }

2112 }

2113

2114

2116 for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i)

2118 return NumNonZeroBytes;

2119}

2120

2121

2122

2123

2126

2127

2129 return;

2130

2131

2133 if (const RecordType *RT = CGF.getContext()

2137 if (RD->hasUserDeclaredConstructor())

2138 return;

2139 }

2140

2141

2144 return;

2145

2146

2147

2149 if (NumNonZeroBytes*4 > Size)

2150 return;

2151

2152

2153 llvm::Constant *SizeVal = CGF.Builder.getInt64(Size.getQuantity());

2154

2157

2158

2160}

2161

2162

2163

2164

2165

2166

2167

2168

2171 "Invalid aggregate expression to emit");

2173 "slot has bits but no address");

2174

2175

2177

2178 AggExprEmitter(*this, Slot, Slot.isIgnored()).Visit(const_cast<Expr*>(E));

2179}

2180

2191

2195 return AggExprEmitter(*this, Dest, Dest.isIgnored())

2196 .EmitFinalDestCopy(Type, Src, SrcKind);

2197}

2198

2203

2204

2207

2208

2209

2210

2217

2218

2220}

2221

2224

2225

2226

2227 if (IsVirtual)

2229

2230

2233

2234

2235

2236

2239 getContext().getASTRecordLayout(BaseRD).getSize() <=

2242

2243

2245}

2246

2249 bool isVolatile) {

2250 assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");

2251

2254

2257 assert((Record->hasTrivialCopyConstructor() ||

2258 Record->hasTrivialCopyAssignment() ||

2259 Record->hasTrivialMoveConstructor() ||

2260 Record->hasTrivialMoveAssignment() ||

2261 Record->hasAttr() || Record->isUnion()) &&

2262 "Trying to aggregate-copy a type without a trivial copy/move "

2263 "constructor or assignment operator");

2264

2265 if (Record->isEmpty())

2266 return;

2267 }

2268 }

2269

2272 if (getTargetHooks().emitCUDADeviceBuiltinSurfaceDeviceCopy(*this, Dest,

2273 Src))

2274 return;

2276 if (getTargetHooks().emitCUDADeviceBuiltinTextureDeviceCopy(*this, Dest,

2277 Src))

2278 return;

2279 }

2280 }

2281

2283 if (CGM.getHLSLRuntime().emitBufferCopy(*this, DestPtr, SrcPtr, Ty))

2284 return;

2285

2286

2287

2288

2289

2290

2291

2292

2293

2294

2295

2296

2297

2298

2299

2301 if (MayOverlap)

2303 else

2305

2306 llvm::Value *SizeVal = nullptr;

2308

2309 if (auto *VAT = dyn_cast_or_null(

2315 SizeVal = Builder.CreateNUWMul(

2316 SizeVal,

2318 }

2319 }

2320 if (!SizeVal) {

2322 }

2323

2324

2325

2326

2327

2328

2329

2330

2331

2332

2333

2334

2335

2336

2339

2340

2342

2344 if (Record->hasObjectMember()) {

2345 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr,

2346 SizeVal);

2347 return;

2348 }

2351 if (const auto *Record = BaseType->getAsRecordDecl()) {

2352 if (Record->hasObjectMember()) {

2353 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr,

2354 SizeVal);

2355 return;

2356 }

2357 }

2358 }

2359

2360 auto *Inst = Builder.CreateMemCpy(DestPtr, SrcPtr, SizeVal, isVolatile);

2362

2363

2364

2365

2366 if (llvm::MDNode *TBAAStructTag = CGM.getTBAAStructInfo(Ty))

2367 Inst->setMetadata(llvm::LLVMContext::MD_tbaa_struct, TBAAStructTag);

2368

2369 if (CGM.getCodeGenOpts().NewStructPathTBAA) {

2372 CGM.DecorateInstructionWithTBAA(Inst, TBAAInfo);

2373 }

2374}

Defines the clang::ASTContext interface.

CompareKind

Definition CGExprAgg.cpp:1078

@ CK_Greater

Definition CGExprAgg.cpp:1080

@ CK_Less

Definition CGExprAgg.cpp:1079

@ CK_Equal

Definition CGExprAgg.cpp:1081

static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF)

GetNumNonZeroBytesInInit - Get an approximate count of the number of non-zero bytes that will be stor...

Definition CGExprAgg.cpp:2062

static Expr * findPeephole(Expr *op, CastKind kind, const ASTContext &ctx)

Attempt to look through various unimportant expressions to find a cast of the given kind.

Definition CGExprAgg.cpp:785

static bool isBlockVarRef(const Expr *E)

Is the value of the given expression possibly a reference to or into a __block variable?

Definition CGExprAgg.cpp:1229

static bool isSimpleZero(const Expr *E, CodeGenFunction &CGF)

isSimpleZero - If emitting this value will obviously just cause a store of zero to memory,...

Definition CGExprAgg.cpp:1616

static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")

Definition CGExprAgg.cpp:1084

static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, LValue DestVal, LValue SrcVal, SourceLocation Loc)

Definition CGExprAgg.cpp:524

static bool castPreservesZero(const CastExpr *CE)

Determine whether the given cast kind is known to always convert values with all zero bits in their v...

Definition CGExprAgg.cpp:1516

static void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E, CodeGenFunction &CGF)

CheckAggExprForMemSetUse - If the initializer is large and has a lot of zeros in it,...

Definition CGExprAgg.cpp:2124

static void EmitHLSLScalarElementwiseAndSplatCasts(CodeGenFunction &CGF, LValue DestVal, llvm::Value *SrcVal, QualType SrcTy, SourceLocation Loc)

Definition CGExprAgg.cpp:493

static bool isTrivialFiller(Expr *e)

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the C++ template declaration subclasses.

tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="")

Clean up any erroneous/redundant code in the given Ranges in Code.

llvm::MachO::Record Record

static bool isVector(QualType QT, QualType ElementType)

This helper function returns true if QT is a vector type that has element type ElementType.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

const ConstantArrayType * getAsConstantArrayType(QualType T) const

CharUnits getTypeAlignInChars(QualType T) const

Return the ABI-specified alignment of a (complete) type T, in characters.

const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const

Get or compute information about the layout of the specified record (struct/union/class) D,...

QualType getBaseElementType(const ArrayType *VAT) const

Return the innermost element type of an array type.

ComparisonCategories CompCategories

Types and expressions required to build C++2a three-way comparisons using operator<=>,...

QualType removeAddrSpaceQualType(QualType T) const

Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...

int64_t toBits(CharUnits CharSize) const

Convert a size in characters to a size in bits.

const ArrayType * getAsArrayType(QualType T) const

Type Query functions.

uint64_t getTypeSize(QualType T) const

Return the size of the specified (complete) type T, in bits.

CharUnits getTypeSizeInChars(QualType T) const

Return the size of the specified (complete) type T, in characters.

static bool hasSameType(QualType T1, QualType T2)

Determine whether the given types T1 and T2 are equivalent.

QualType getSizeType() const

Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.

CharUnits toCharUnitsFromBits(int64_t BitSize) const

Convert a size in bits to a size in characters.

QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const

Return the uniqued reference to the type for an address space qualified type with the specified type ...

unsigned getTargetAddressSpace(LangAS AS) const

static bool hasSameUnqualifiedType(QualType T1, QualType T2)

Determine whether the given types are equivalent after cvr-qualifiers have been removed.

ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...

uint64_t getFieldOffset(unsigned FieldNo) const

getFieldOffset - Get the offset of the given field index, in bits.

CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const

getBaseClassOffset - Get the offset, in chars, for the given base class.

CharUnits getNonVirtualSize() const

getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...

AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...

Expr * getCond() const

getCond - Return the expression representing the condition for the ?

Expr * getTrueExpr() const

getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...

Expr * getFalseExpr() const

getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...

llvm::APInt getArraySize() const

OpaqueValueExpr * getCommonExpr() const

Get the common subexpression shared by all initializations (the source array).

Expr * getSubExpr() const

Get the initializer to use for each array element.

ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.

QualType getElementType() const

A builtin binary operation expression such as "x + y" or "x <= y".

CXXTemporary * getTemporary()

const Expr * getSubExpr() const

Expr * getExpr()

Get the initialization expression that will be used.

bool constructsVBase() const

Determine whether this constructor is actually constructing a base class (rather than a complete obje...

CXXConstructorDecl * getConstructor() const

Get the constructor that this expression will call.

bool inheritedFromVBase() const

Determine whether the inherited constructor is inherited from a virtual base of the object we constru...

MutableArrayRef< Expr * > getInitExprs()

FieldDecl * getInitializedFieldInUnion()

Represents a C++ struct/union/class.

bool isTriviallyCopyable() const

Determine whether this class is considered trivially copyable per (C++11 [class]p6).

bool isEmpty() const

Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).

Expr * getSemanticForm()

Get an equivalent semantic form for this expression.

QualType getCallReturnType(const ASTContext &Ctx) const

getCallReturnType - Get the return type of the call expr.

CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...

CastKind getCastKind() const

CharUnits - This is an opaque type for sizes expressed in character units.

bool isZero() const

isZero - Test whether the quantity equals zero.

llvm::Align getAsAlign() const

getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

CharUnits alignmentOfArrayElement(CharUnits elementSize) const

Given that this is the alignment of the first element of an array, return the minimum alignment of an...

static CharUnits fromQuantity(QuantityType Quantity)

fromQuantity - Construct a CharUnits quantity from a raw integer type.

static CharUnits Zero()

Zero - Construct a CharUnits quantity of zero.

Expr * getChosenSubExpr() const

getChosenSubExpr - Return the subexpression chosen according to the condition.

Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...

llvm::Value * getBasePointer() const

llvm::Value * emitRawPointer(CodeGenFunction &CGF) const

Return the pointer contained in this class after authenticating it and adding offset to it if necessa...

CharUnits getAlignment() const

llvm::Type * getElementType() const

Return the type of the values stored in this address.

Address withElementType(llvm::Type *ElemTy) const

Return address with different element type, but same pointer and alignment.

void setVolatile(bool flag)

static AggValueSlot ignored()

ignored - Returns an aggregate value slot indicating that the aggregate value is being ignored.

Address getAddress() const

CharUnits getPreferredSize(ASTContext &Ctx, QualType Type) const

Get the preferred size to use when storing a value to this slot.

NeedsGCBarriers_t requiresGCollection() const

void setExternallyDestructed(bool destructed=true)

void setZeroed(bool V=true)

IsZeroed_t isZeroed() const

Qualifiers getQualifiers() const

static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)

IsAliased_t isPotentiallyAliased() const

static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)

forAddr - Make a slot for an aggregate value.

IsDestructed_t isExternallyDestructed() const

Overlap_t mayOverlap() const

llvm::Value * emitRawPointer(CodeGenFunction &CGF) const

llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)

Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")

virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)

Emit a comparison between two member pointers. Returns an i1.

void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E)

virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, llvm::Value *Size)=0

const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const

Return the BitFieldInfo that corresponds to the field FD.

CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...

void CreateCoercedStore(llvm::Value *Src, Address Dst, llvm::TypeSize DstSize, bool DstIsVolatile)

Create a store to.

void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)

EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.

RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())

void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest)

AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD)

Determine whether a field initialization may overlap some other object.

Definition CGExprAgg.cpp:2200

void callCStructMoveConstructor(LValue Dst, LValue Src)

void EmitNullInitialization(Address DestPtr, QualType Ty)

EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...

static bool hasScalarEvaluationKind(QualType T)

llvm::Type * ConvertType(QualType T)

void EmitAggFinalDestCopy(QualType Type, AggValueSlot Dest, const LValue &Src, ExprValueKind SrcKind)

EmitAggFinalDestCopy - Emit copy of the specified aggregate into destination address.

Definition CGExprAgg.cpp:2192

void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, llvm::Value *arrayEnd, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)

pushRegularPartialArrayCleanup - Push an EH cleanup to destroy already-constructed elements of the gi...

void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)

void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)

EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.

bool hasVolatileMember(QualType T)

hasVolatileMember - returns true if aggregate type has a volatile member.

llvm::SmallVector< DeferredDeactivateCleanup > DeferredDeactivationCleanupStack

RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr, AggValueSlot Slot=AggValueSlot::ignored())

Generate code to get an argument from the passed in pointer and update it accordingly.

RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())

llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)

createBasicBlock - Create an LLVM basic block.

void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)

See CGDebugInfo::addInstToCurrentSourceAtom.

AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *RD, const CXXRecordDecl *BaseRD, bool IsVirtual)

Determine whether a base class initialization may overlap some other object.

Definition CGExprAgg.cpp:2222

const LangOptions & getLangOpts() const

RValue EmitReferenceBindingToExpr(const Expr *E)

Emits a reference binding to the passed in expression.

LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E)

void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)

pushDestroy - Push the standard destructor for the given type as at least a normal cleanup.

@ TCK_Store

Checking the destination of a store. Must be suitably sized and aligned.

@ TCK_Load

Checking the operand of a load. Must be suitably sized and aligned.

void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin, Address arrayEndPointer, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)

pushIrregularPartialArrayCleanup - Push a NormalAndEHCleanup to destroy already-constructed elements ...

Destroyer * getDestroyer(QualType::DestructionKind destructionKind)

LValue EmitPseudoObjectLValue(const PseudoObjectExpr *e)

void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)

EmitAggregateCopy - Emit an aggregate copy.

Definition CGExprAgg.cpp:2247

const TargetInfo & getTarget() const

void EmitIgnoredExpr(const Expr *E)

EmitIgnoredExpr - Emit an expression in a context which ignores the result.

RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot(), llvm::CallBase **CallOrInvoke=nullptr)

RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)

EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...

void pushDestroyAndDeferDeactivation(QualType::DestructionKind dtorKind, Address addr, QualType type)

void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)

DeactivateCleanupBlock - Deactivates the given cleanup block.

void callCStructCopyAssignmentOperator(LValue Dst, LValue Src)

void pushFullExprCleanup(CleanupKind kind, As... A)

pushFullExprCleanup - Push a cleanup to be run at the end of the current full-expression.

LValue EmitAggExprToLValue(const Expr *E)

EmitAggExprToLValue - Emit the computation of the specified expression of aggregate type into a tempo...

Definition CGExprAgg.cpp:2181

RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)

AggValueSlot CreateAggTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)

CreateAggTemp - Create a temporary memory object for the given aggregate type.

llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)

emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...

void callCStructCopyConstructor(LValue Dst, LValue Src)

bool HaveInsertPoint() const

HaveInsertPoint - True if an insertion point is defined.

RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot=AggValueSlot::ignored())

CGDebugInfo * getDebugInfo()

llvm::Value * getTypeSize(QualType Ty)

Returns calculated size of the specified type.

bool EmitLifetimeStart(llvm::Value *Addr)

Emit a lifetime.begin marker if some criteria are satisfied.

LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)

EmitLValueForFieldInitialization - Like EmitLValueForField, except that if the Field is a reference,...

Address GetAddressOfDirectBaseInCompleteClass(Address Value, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, bool BaseIsVirtual)

GetAddressOfBaseOfCompleteClass - Convert the given pointer to a complete class to the given direct b...

llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)

CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...

LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)

Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.

const TargetCodeGenInfo & getTargetHooks() const

void EmitLifetimeEnd(llvm::Value *Addr)

RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name="tmp")

CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen without...

void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)

Increment the profiler's counter for the given statement by StepV.

void callCStructMoveAssignmentOperator(LValue Dst, LValue Src)

ASTContext & getContext() const

void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)

EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...

void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)

Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())

EmitCompoundStmt - Emit a compound statement {..} node.

RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)

EmitAnyExpr - Emit code to compute the specified expression which can have any type.

bool needsEHCleanup(QualType::DestructionKind kind)

Determines whether an EH cleanup is required to destroy a type with the given destruction kind.

CleanupKind getCleanupKind(QualType::DestructionKind kind)

llvm::Type * ConvertTypeForMem(QualType T)

RValue EmitAtomicExpr(AtomicExpr *E)

CodeGenTypes & getTypes() const

void FlattenAccessAndTypeLValue(LValue LVal, SmallVectorImpl< LValue > &AccessList)

RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)

void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType, Address Ptr)

Emits all the code to cause the given temporary to be cleaned up.

bool LValueIsSuitableForInlineAtomic(LValue Src)

An LValue is a candidate for having its loads and stores be made atomic if we are operating under /vo...

LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)

Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.

void EmitInheritedCXXConstructorCall(const CXXConstructorDecl *D, bool ForVirtualBase, Address This, bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E)

Emit a call to a constructor inherited from a base class, passing the current constructor's arguments...

RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)

CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...

void EmitInitializationToLValue(const Expr *E, LValue LV, AggValueSlot::IsZeroed_t IsZeroed=AggValueSlot::IsNotZeroed)

EmitInitializationToLValue - Emit an initializer to an LValue.

void EmitAggExpr(const Expr *E, AggValueSlot AS)

EmitAggExpr - Emit the computation of the specified expression of aggregate type.

Definition CGExprAgg.cpp:2169

static bool hasAggregateEvaluationKind(QualType T)

LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)

void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV)

void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit)

uint64_t getProfileCount(const Stmt *S)

Get the profiler's count for the given statement.

void ErrorUnsupported(const Stmt *S, const char *Type)

ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.

LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)

EmitLValue - Emit code to compute a designator that specifies the location of the expression.

llvm::LLVMContext & getLLVMContext()

llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)

Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...

void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)

EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...

llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)

void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)

EmitBlock - Emit the given block.

void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)

Emit type info if type of an expression is a variably modified type.

CGHLSLRuntime & getHLSLRuntime()

Return a reference to the configured HLSL runtime.

llvm::Module & getModule() const

bool isPaddedAtomicType(QualType type)

void ErrorUnsupported(const Stmt *S, const char *Type)

Print out an error that codegen doesn't support the specified stmt yet.

CGCXXABI & getCXXABI() const

ASTContext & getContext() const

bool shouldZeroInitPadding() const

CGObjCRuntime & getObjCRuntime()

Return a reference to the configured Objective-C runtime.

llvm::Constant * EmitNullConstant(QualType T)

Return the result of value-initializing the given type, i.e.

LangAS GetGlobalConstantAddressSpace() const

Return the AST address space of constant literal, which is used to emit the constant literal as globa...

bool isPointerZeroInitializable(QualType T)

Check if the pointer type can be zero-initialized (in the C++ sense) with an LLVM zeroinitializer.

const CGRecordLayout & getCGRecordLayout(const RecordDecl *)

getCGRecordLayout - Return record layout info for the given record decl.

bool isZeroInitializable(QualType T)

IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...

stable_iterator stable_begin() const

Create a stable reference to the top of the EH stack.

iterator find(stable_iterator save) const

Turn a stable reference to a scope depth into a unstable pointer to the EH stack.

LValue - This represents an lvalue references.

Address getAddress() const

TBAAAccessInfo getTBAAInfo() const

RValue - This trivial value class is used to represent the result of an expression that is evaluated.

llvm::Value * getAggregatePointer(QualType PointeeType, CodeGenFunction &CGF) const

static RValue get(llvm::Value *V)

static RValue getAggregate(Address addr, bool isVolatile=false)

Convert an Address to an RValue.

Address getAggregateAddress() const

getAggregateAddr() - Return the Value* of the address of the aggregate.

llvm::Value * getScalarVal() const

getScalarVal() - Return the Value* of this scalar value.

std::pair< llvm::Value *, llvm::Value * > getComplexVal() const

getComplexVal - Return the real/imag components of this complex value.

const ComparisonCategoryInfo & getInfoForType(QualType Ty) const

Return the comparison category information as specified by getCategoryForType(Ty).

bool isPartial() const

True iff the comparison is not totally ordered.

const ValueInfo * getLess() const

const ValueInfo * getUnordered() const

const CXXRecordDecl * Record

The declaration for the comparison category type from the standard library.

const ValueInfo * getGreater() const

const ValueInfo * getEqualOrEquiv() const

Complex values, per C99 6.2.5p11.

const Expr * getInitializer() const

llvm::APInt getSize() const

Return the constant array size as an APInt.

A reference to a declared variable, function, enum, etc.

InitListExpr * getUpdater() const

This represents one expression.

Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY

Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...

Expr * IgnoreParens() LLVM_READONLY

Skip past any parentheses which might surround this expression until reaching a fixed point.

bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const

HasSideEffects - This routine returns true for all those expressions which have any effect other than...

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

Represents a member of a struct/union/class.

bool isBitField() const

Determines whether this field is a bitfield.

unsigned getFieldIndex() const

Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...

const RecordDecl * getParent() const

Returns the parent of this field declaration, which is the struct in which this field is defined.

const Expr * getSubExpr() const

Describes an C or C++ initializer list.

bool isTransparent() const

Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...

FieldDecl * getInitializedFieldInUnion()

If this initializes a union, specifies which field in the union to initialize.

unsigned getNumInits() const

bool hadArrayRangeDesignator() const

Expr * getArrayFiller()

If this initializer list initializes an array with more elements than there are initializers in the l...

const Expr * getInit(unsigned Init) const

ArrayRef< Expr * > inits()

capture_init_iterator capture_init_end()

Retrieve the iterator pointing one past the last initialization argument for this lambda expression.

Expr *const * const_capture_init_iterator

Const iterator that walks over the capture initialization arguments.

capture_init_iterator capture_init_begin()

Retrieve the first initialization argument for this lambda expression (which initializes the first ca...

CXXRecordDecl * getLambdaClass() const

Retrieve the class that corresponds to the lambda.

Expr * getSubExpr() const

Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.

MemberExpr - [C99 6.5.2.3] Structure and Union Members.

A pointer to member type per C++ 8.3.3 - Pointers to members.

OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.

Expr * getSourceExpr() const

The source expression of an opaque value expression is the expression which originally generated the ...

Expr * getSelectedExpr() const

const Expr * getSubExpr() const

A (possibly-)qualified type.

bool isVolatileQualified() const

Determine whether this type is volatile-qualified.

bool isTriviallyCopyableType(const ASTContext &Context) const

Return true if this is a trivially copyable type (C++0x [basic.types]p9)

LangAS getAddressSpace() const

Return the address space of this type.

DestructionKind isDestructedType() const

Returns a nonzero value if objects of this type require non-trivial work to clean up after.

@ PCK_Struct

The type is a struct containing a field whose type is neither PCK_Trivial nor PCK_VolatileTrivial.

Represents a struct/union/class.

bool hasObjectMember() const

field_range fields() const

specific_decl_iterator< FieldDecl > field_iterator

RecordDecl * getDefinitionOrSelf() const

field_iterator field_begin() const

Encodes a location in the source.

CompoundStmt * getSubStmt()

StmtVisitor - This class implements a simple visitor for Stmt subclasses.

Expr * getReplacement() const

uint64_t getPointerWidth(LangAS AddrSpace) const

Return the width of pointers on this target, for the specified address space.

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

bool isConstantArrayType() const

RecordDecl * getAsRecordDecl() const

Retrieves the RecordDecl this type refers to.

bool isPointerType() const

bool isReferenceType() const

bool isScalarType() const

bool isVariableArrayType() const

bool isCUDADeviceBuiltinSurfaceType() const

Check if the type is the CUDA device builtin surface type.

bool isIntegralOrEnumerationType() const

Determine whether this type is an integral or enumeration type.

RecordDecl * castAsRecordDecl() const

bool isAnyComplexType() const

bool hasSignedIntegerRepresentation() const

Determine whether this type has an signed integer representation of some sort, e.g....

bool isMemberPointerType() const

bool isCUDADeviceBuiltinTextureType() const

Check if the type is the CUDA device builtin texture type.

bool hasFloatingRepresentation() const

Determine whether this type has a floating-point representation of some sort, e.g....

bool isVectorType() const

bool isRealFloatingType() const

Floating point categories.

const T * getAsCanonical() const

If this type is canonically the specified type, return its canonical type cast to that specified type...

const T * getAs() const

Member-template getAs'.

bool isNullPtrType() const

bool isRecordType() const

UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...

Expr * getSubExpr() const

Represents a variable declaration or definition.

Represents a GCC generic vector type.

@ Type

The l-value was considered opaque, so the alignment was determined from a type.

@ EHCleanup

Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const AstTypeMatcher< AtomicType > atomicType

bool GE(InterpState &S, CodePtr OpPC)

The JSON file list parser is used to communicate input to InstallAPI.

bool isa(CodeGen::Address addr)

@ Result

The result type of a method or function.

const FunctionProtoType * T

LangAS

Defines the address space values used by the address space qualifier of QualType.

CastKind

CastKind - The kind of operation required for a conversion.

U cast(CodeGen::Address addr)

Diagnostic wrappers for TextAPI types for error reporting.

cl::opt< bool > EnableSingleByteCoverage

CharUnits StorageOffset

The offset of the bitfield storage from the start of the struct.

unsigned StorageSize

The storage size in bits which should be used when accessing this bitfield.

llvm::IntegerType * Int8Ty

i8, i16, i32, and i64

llvm::IntegerType * CharTy

char

llvm::IntegerType * SizeTy

llvm::PointerType * Int8PtrTy

llvm::IntegerType * PtrDiffTy

CharUnits getPointerAlign() const