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

1

2

3

4

5

6

7

8

9

10

11

12

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

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

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

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

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

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

32using namespace clang;

33using namespace CodeGen;

34

35

36

37

38

39namespace llvm {

41}

42

43namespace {

44class AggExprEmitter : public StmtVisitor {

48 bool IsResultUnused;

49

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

53 }

57 }

58

59

60

61

62

63

64

65 void withReturnValueSlot(const Expr *E,

67

68 void DoZeroInitPadding(uint64_t &PaddingStart, uint64_t PaddingEnd,

70

71public:

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

74 IsResultUnused(IsResultUnused) { }

75

76

77

78

79

80

81

82

83 void EmitAggLoadOfLValue(const Expr *E);

84

85

86

88 CodeGenFunction::ExprValueKind SrcValueKind =

89 CodeGenFunction::EVK_NonRValue);

93

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

96 Expr *ArrayFiller);

97

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

102 }

103

104 bool TypeRequiresGCollection(QualType T);

105

106

107

108

109

113 }

114

115 void VisitStmt(Stmt *S) {

117 }

120 Visit(GE->getResultExpr());

121 }

124 }

127 }

131 return Visit(E->getReplacement());

132 }

133

136

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

140 llvm::TypeSize::getFixed(

144 return;

145 }

146 return Visit(E->getSubExpr());

147 }

148

149

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

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

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

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

156 EmitAggLoadOfLValue(E);

157 }

159 EmitAggLoadOfLValue(E);

160 }

161

162

164 void VisitCallExpr(const CallExpr *E);

165 void VisitStmtExpr(const StmtExpr *E);

167 void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *BO);

172 Visit(E->getSemanticForm());

173 }

174

177 EmitAggLoadOfLValue(E);

178 }

179

182 void VisitChooseExpr(const ChooseExpr *CE);

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

185 FieldDecl *InitializedFieldInUnion,

186 Expr *ArrayFiller);

188 llvm::Value *outerBegin = nullptr);

190 void VisitNoInitExpr(NoInitExpr *E) { }

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

194 }

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

198 }

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

209

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

214 }

215

217 bool NeedsDestruction =

220 if (NeedsDestruction)

223 if (NeedsDestruction)

226 }

227

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

231 Expr *ArrayFiller);

232

234 void EmitNullInitializationToLValue(LValue Address);

235

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

240 }

242 Visit(E->getSelectedExpr());

243 }

244};

245}

246

247

248

249

250

251

252

253

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

256

257

260 return;

261 }

262

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

264}

265

266

267bool AggExprEmitter::TypeRequiresGCollection(QualType T) {

268

270 if (!RecordTy) return false;

271

272

274 if (isa(Record) &&

275 (cast(Record)->hasNonTrivialCopyConstructor() ||

276 !cast(Record)->hasTrivialDestructor()))

277 return false;

278

279

281}

282

283void AggExprEmitter::withReturnValueSlot(

286 bool RequiresDestruction =

289

290

291

292

293

294

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

297

300

302 llvm::Value *LifetimeSizePtr = nullptr;

303 llvm::IntrinsicInst *LifetimeStartInst = nullptr;

304 if (!UseTemp) {

306 } else {

307 RetAddr = CGF.CreateMemTemp(RetTy, "tmp", &RetAllocaAddr);

308 llvm::TypeSize Size =

311 if (LifetimeSizePtr) {

312 LifetimeStartInst =

313 castllvm::IntrinsicInst(std::prev(Builder.GetInsertPoint()));

314 assert(LifetimeStartInst->getIntrinsicID() ==

315 llvm::Intrinsic::lifetime_start &&

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

317

321 }

322 }

323

327

328 if (!UseTemp)

329 return;

330

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

334

335 if (!RequiresDestruction && LifetimeStartInst) {

336

337

338

341 }

342}

343

344

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

348 EmitFinalDestCopy(type, srcLV, CodeGenFunction::EVK_RValue);

349}

350

351

352void AggExprEmitter::EmitFinalDestCopy(

354 CodeGenFunction::ExprValueKind SrcValueKind) {

355

356

357

358

360 return;

361

362

365

366 if (SrcValueKind == CodeGenFunction::EVK_RValue) {

370 else

372 return;

373 }

374 } else {

378 else

380 return;

381 }

382 }

383

387 EmitCopy(type, Dest, srcAgg);

388}

389

390

391

392

393

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

402 size);

403 return;

404 }

405

406

407

408

413}

414

415

416

417void

419

420

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

424 Address ArrayPtr = Array.getAddress();

425

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

429

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

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

436

437

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

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

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

446

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

450

452

453 } else {

454

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

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

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

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

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

463 "arrayend");

465 }

466

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

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

469}

470

471

472

474 if (E)

475 return true;

476

477 if (isa(E))

478 return true;

479

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

481 if (ILE->getNumInits())

482 return false;

484 }

485

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

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

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

489

490

491 return false;

492}

493

494

495

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

499 uint64_t NumInitElements = Args.size();

500

501 uint64_t NumArrayElements = AType->getNumElements();

502 for (const auto *Init : Args) {

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

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

505 if (NumInitElements > NumArrayElements) {

506 NumInitElements = NumArrayElements;

507 break;

508 }

509 }

510 }

511

512 assert(NumInitElements <= NumArrayElements);

513

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

520

521

522

523

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

532 if (llvm::Constant *C =

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

534 auto GV = new llvm::GlobalVariable(

536 true, llvm::GlobalValue::PrivateLinkage, C,

537 "constinit",

538 nullptr, llvm::GlobalVariable::NotThreadLocal,

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

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

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

545 return;

546 }

547 }

548

549

550

551

554 CodeGenFunction::CleanupDeactivationScope deactivation(CGF);

555

557 if (dtorKind) {

558 CodeGenFunction::AllocaTrackerRAII allocaTracker(CGF);

559

560

561

562

563 llvm::Instruction *dominatingIP =

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

566 "arrayinit.endOfInit");

567 Builder.CreateStore(begin, endOfInit);

569 elementAlign,

572 .AddAuxAllocas(allocaTracker.Take());

573

576 }

577

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

579

581 llvm::Value *element = begin;

582 if (ArrayIndex > 0) {

583 element = Builder.CreateInBoundsGEP(

584 llvmElementType, begin,

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

586

587

588

589

591 Builder.CreateStore(element, endOfInit);

592 }

593

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

596 EmitInitializationToLValue(Init, elementLV);

597 return true;

598 };

599

600 unsigned ArrayIndex = 0;

601

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

603 if (ArrayIndex >= NumInitElements)

604 break;

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

606 EmbedS->doForEachDataElement(Emit, ArrayIndex);

607 } else {

608 Emit(Args[i], ArrayIndex);

609 ArrayIndex++;

610 }

611 }

612

613

615

616

617

618

619 if (NumInitElements != NumArrayElements &&

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

622

623

624

625

626

627 llvm::Value *element = begin;

628 if (NumInitElements) {

629 element = Builder.CreateInBoundsGEP(

630 llvmElementType, element,

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

632 "arrayinit.start");

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

634 }

635

636

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

638 llvmElementType, begin,

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

640

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

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

643

644

646 llvm::PHINode *currentElement =

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

648 currentElement->addIncoming(element, entryBB);

649

650

651 {

652

653

654

655

656

657 CodeGenFunction::RunCleanupsScope CleanupsScope(CGF);

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

660 if (ArrayFiller)

661 EmitInitializationToLValue(ArrayFiller, elementLV);

662 else

663 EmitNullInitializationToLValue(elementLV);

664 }

665

666

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

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

669

670

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

672

673

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

675 "arrayinit.done");

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

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

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

679

681 }

682}

683

684

685

686

687

689 Visit(E->getSubExpr());

690}

691

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

693

696 else

698}

699

700void

704

705

706 EmitAggLoadOfLValue(E);

707 return;

708 }

709

711

712

713

714 bool Destruct =

716 if (Destruct)

718

720

721 if (Destruct)

726}

727

728

729

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

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

734 return castE->getSubExpr();

735 }

736 return nullptr;

737}

738

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

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

742 switch (E->getCastKind()) {

743 case CK_Dynamic: {

744

745 assert(isa(E) && "CK_Dynamic without a dynamic_cast?");

747 CodeGenFunction::TCK_Load);

748

751 else

753

756 break;

757 }

758

759 case CK_ToUnion: {

760

763 true);

764 break;

765 }

766

767

770 EmitInitializationToLValue(E->getSubExpr(),

772 break;

773 }

774

775 case CK_LValueToRValueBitCast: {

778 true);

779 break;

780 }

781

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

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

789 break;

790 }

791

792 case CK_DerivedToBase:

793 case CK_BaseToDerived:

794 case CK_UncheckedDerivedToBase: {

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

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

797 }

798

799 case CK_NonAtomicToAtomic:

800 case CK_AtomicToNonAtomic: {

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

802

803

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

807

811

812

813

815 return Visit(E->getSubExpr());

816 }

817

819 (isToAtomic ? CK_AtomicToNonAtomic : CK_NonAtomicToAtomic);

820

821

822 if (Expr *op =

826 "peephole significantly changed types?");

827 return Visit(op);

828 }

829

830

831

832 if (isToAtomic) {

835

836

839

840

850 }

851

853 return;

854 }

855

856

857

860 CGF.EmitAggExpr(E->getSubExpr(), atomicSlot);

861

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

864 return EmitFinalDestCopy(valueType, rvalue);

865 }

866 case CK_AddressSpaceConversion:

867 return Visit(E->getSubExpr());

868

869 case CK_LValueToRValue:

870

871

873 bool Destruct =

876 if (Destruct)

879 Visit(E->getSubExpr());

880

881 if (Destruct)

884

885 return;

886 }

887

888 [[fallthrough]];

889

890 case CK_HLSLArrayRValue:

891 Visit(E->getSubExpr());

892 break;

893

894 case CK_NoOp:

895 case CK_UserDefinedConversion:

896 case CK_ConstructorConversion:

899 "Implicit cast types must be compatible");

900 Visit(E->getSubExpr());

901 break;

902

903 case CK_LValueBitCast:

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

905

906 case CK_Dependent:

907 case CK_BitCast:

908 case CK_ArrayToPointerDecay:

909 case CK_FunctionToPointerDecay:

910 case CK_NullToPointer:

911 case CK_NullToMemberPointer:

912 case CK_BaseToDerivedMemberPointer:

913 case CK_DerivedToBaseMemberPointer:

914 case CK_MemberPointerToBoolean:

915 case CK_ReinterpretMemberPointer:

916 case CK_IntegralToPointer:

917 case CK_PointerToIntegral:

918 case CK_PointerToBoolean:

919 case CK_ToVoid:

920 case CK_VectorSplat:

921 case CK_IntegralCast:

922 case CK_BooleanToSignedIntegral:

923 case CK_IntegralToBoolean:

924 case CK_IntegralToFloating:

925 case CK_FloatingToIntegral:

926 case CK_FloatingToBoolean:

927 case CK_FloatingCast:

928 case CK_CPointerToObjCPointerCast:

929 case CK_BlockPointerToObjCPointerCast:

930 case CK_AnyPointerToBlockPointerCast:

931 case CK_ObjCObjectLValueCast:

932 case CK_FloatingRealToComplex:

933 case CK_FloatingComplexToReal:

934 case CK_FloatingComplexToBoolean:

935 case CK_FloatingComplexCast:

936 case CK_FloatingComplexToIntegralComplex:

937 case CK_IntegralRealToComplex:

938 case CK_IntegralComplexToReal:

939 case CK_IntegralComplexToBoolean:

940 case CK_IntegralComplexCast:

941 case CK_IntegralComplexToFloatingComplex:

942 case CK_ARCProduceObject:

943 case CK_ARCConsumeObject:

944 case CK_ARCReclaimReturnedObject:

945 case CK_ARCExtendBlockObject:

946 case CK_CopyAndAutoreleaseBlockObject:

947 case CK_BuiltinFnToFnPtr:

948 case CK_ZeroToOCLOpaqueType:

949 case CK_MatrixCast:

950 case CK_HLSLVectorTruncation:

951

952 case CK_IntToOCLSampler:

953 case CK_FloatingToFixedPoint:

954 case CK_FixedPointToFloating:

955 case CK_FixedPointCast:

956 case CK_FixedPointToBoolean:

957 case CK_FixedPointToIntegral:

958 case CK_IntegralToFixedPoint:

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

960 }

961}

962

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

964 if (E->getCallReturnType(CGF.getContext())->isReferenceType()) {

965 EmitAggLoadOfLValue(E);

966 return;

967 }

968

971 });

972}

973

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

977 });

978}

979

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

982 Visit(E->getRHS());

983}

984

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

986 CodeGenFunction::StmtExprEvaluation eval(CGF);

988}

989

994};

995

999 const char *NameSuffix = "") {

1002 ArgTy = CT->getElementType();

1003

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

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

1009 }

1010

1011

1012 struct CmpInstInfo {

1013 const char *Name;

1014 llvm::CmpInst::Predicate FCmp;

1015 llvm::CmpInst::Predicate SCmp;

1016 llvm::CmpInst::Predicate UCmp;

1017 };

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

1019 using FI = llvm::FCmpInst;

1020 using II = llvm::ICmpInst;

1021 switch (Kind) {

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

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

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

1028 }

1029 llvm_unreachable("Unrecognised CompareKind enum");

1030 }();

1031

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

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

1036 auto Inst =

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

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

1040 }

1041

1042 llvm_unreachable("unsupported aggregate binary expression should have "

1043 "already been handled");

1044}

1045

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

1047 using llvm::BasicBlock;

1048 using llvm::PHINode;

1049 using llvm::Value;

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

1056

1058

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

1063 }

1065

1066

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

1075 };

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

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

1078

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

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

1082 if (!IsComplex)

1083 return Cmp;

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

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

1088 };

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

1091 };

1092

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

1097 Value *SelectOne =

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

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

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

1102 SelectOne, "sel.eq");

1103 } else {

1104 Value *SelectEq = Builder.CreateSelect(

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

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

1109 SelectEq, "sel.gt");

1110 Select = Builder.CreateSelect(

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

1112 }

1113

1116

1117

1118

1122

1123

1124}

1125

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

1127 if (E->getOpcode() == BO_PtrMemD || E->getOpcode() == BO_PtrMemI)

1128 VisitPointerToDataMemberBinaryOperator(E);

1129 else

1131}

1132

1133void AggExprEmitter::VisitPointerToDataMemberBinaryOperator(

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

1137}

1138

1139

1140

1142

1144

1145

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

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

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

1149 }

1150

1151

1152

1153

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

1155

1156

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

1159

1160

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

1163

1164

1165 return false;

1166

1167

1169 = dyn_cast(E)) {

1172

1173

1175 = dyn_cast(E)) {

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

1178

1179

1180

1181

1182

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

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

1185 return false;

1187

1188

1189

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

1192

1193

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

1196

1197

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

1200 }

1201

1202 return false;

1203}

1204

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

1206

1207

1210 && "Invalid assignment");

1211

1212

1213

1214

1215

1218

1219 EnsureDest(E->getRHS()->getType());

1220 Visit(E->getRHS());

1221

1222

1224

1225

1229 return;

1230 }

1231

1232 EmitCopy(E->getLHS()->getType(),

1234 needsGC(E->getLHS()->getType()),

1237 Dest);

1238 return;

1239 }

1240

1242

1243

1244

1247 EnsureDest(E->getRHS()->getType());

1248 Visit(E->getRHS());

1250 return;

1251 }

1252

1253

1257

1261

1263

1264

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

1266

1271}

1272

1273void AggExprEmitter::

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

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

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

1278

1279

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

1281

1282 CodeGenFunction::ConditionalEvaluation eval(CGF);

1285

1286

1288 bool destructNonTrivialCStruct =

1289 !isExternallyDestructed &&

1291 isExternallyDestructed |= destructNonTrivialCStruct;

1293

1294 eval.begin(CGF);

1298 else

1300 Visit(E->getTrueExpr());

1301 eval.end(CGF);

1302

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

1304 CGF.Builder.CreateBr(ContBlock);

1305

1306

1307

1308

1309

1311

1312 eval.begin(CGF);

1316 Visit(E->getFalseExpr());

1317 eval.end(CGF);

1318

1319 if (destructNonTrivialCStruct)

1322

1326}

1327

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

1330}

1331

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

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

1335

1336

1337 if (!ArgValue.isValid()) {

1339 return;

1340 }

1341}

1342

1344

1345

1348

1349

1351

1352 Visit(E->getSubExpr());

1353

1354

1355 if (!wasExternallyDestructed)

1357}

1358

1359void

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

1363}

1364

1365void AggExprEmitter::VisitCXXInheritedCtorInitExpr(

1369 E->getConstructor(), E->constructsVBase(), Slot.getAddress(),

1370 E->inheritedFromVBase(), E);

1371}

1372

1373void

1374AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {

1377

1378

1379

1380 CodeGenFunction::CleanupDeactivationScope scope(CGF);

1381

1384 e = E->capture_init_end();

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

1386

1388 if (CurField->hasCapturedVLAType()) {

1390 continue;

1391 }

1392

1393 EmitInitializationToLValue(*i, LV);

1394

1395

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

1399 if (DtorKind)

1401 CurField->getType(),

1403 }

1404 }

1405}

1406

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

1408 CodeGenFunction::RunCleanupsScope cleanups(CGF);

1409 Visit(E->getSubExpr());

1410}

1411

1416}

1417

1422}

1423

1424

1425

1426

1429

1430 case CK_NoOp:

1431 case CK_UserDefinedConversion:

1432 case CK_ConstructorConversion:

1433 case CK_BitCast:

1434 case CK_ToUnion:

1435 case CK_ToVoid:

1436

1437

1438 case CK_BooleanToSignedIntegral:

1439 case CK_FloatingCast:

1440 case CK_FloatingComplexCast:

1441 case CK_FloatingComplexToBoolean:

1442 case CK_FloatingComplexToIntegralComplex:

1443 case CK_FloatingComplexToReal:

1444 case CK_FloatingRealToComplex:

1445 case CK_FloatingToBoolean:

1446 case CK_FloatingToIntegral:

1447 case CK_IntegralCast:

1448 case CK_IntegralComplexCast:

1449 case CK_IntegralComplexToBoolean:

1450 case CK_IntegralComplexToFloatingComplex:

1451 case CK_IntegralComplexToReal:

1452 case CK_IntegralRealToComplex:

1453 case CK_IntegralToBoolean:

1454 case CK_IntegralToFloating:

1455

1456 case CK_IntegralToPointer:

1457 case CK_PointerToIntegral:

1458

1459 case CK_VectorSplat:

1460 case CK_MatrixCast:

1461 case CK_NonAtomicToAtomic:

1462 case CK_AtomicToNonAtomic:

1463 case CK_HLSLVectorTruncation:

1464 return true;

1465

1466 case CK_BaseToDerivedMemberPointer:

1467 case CK_DerivedToBaseMemberPointer:

1468 case CK_MemberPointerToBoolean:

1469 case CK_NullToMemberPointer:

1470 case CK_ReinterpretMemberPointer:

1471

1472 return false;

1473

1474 case CK_AnyPointerToBlockPointerCast:

1475 case CK_BlockPointerToObjCPointerCast:

1476 case CK_CPointerToObjCPointerCast:

1477 case CK_ObjCObjectLValueCast:

1478 case CK_IntToOCLSampler:

1479 case CK_ZeroToOCLOpaqueType:

1480

1481 return false;

1482

1483 case CK_FixedPointCast:

1484 case CK_FixedPointToBoolean:

1485 case CK_FixedPointToFloating:

1486 case CK_FixedPointToIntegral:

1487 case CK_FloatingToFixedPoint:

1488 case CK_IntegralToFixedPoint:

1489

1490 return false;

1491

1492 case CK_AddressSpaceConversion:

1493 case CK_BaseToDerived:

1494 case CK_DerivedToBase:

1495 case CK_Dynamic:

1496 case CK_NullToPointer:

1497 case CK_PointerToBoolean:

1498

1499

1500 return false;

1501

1502 case CK_ARCConsumeObject:

1503 case CK_ARCExtendBlockObject:

1504 case CK_ARCProduceObject:

1505 case CK_ARCReclaimReturnedObject:

1506 case CK_CopyAndAutoreleaseBlockObject:

1507 case CK_ArrayToPointerDecay:

1508 case CK_FunctionToPointerDecay:

1509 case CK_BuiltinFnToFnPtr:

1510 case CK_Dependent:

1511 case CK_LValueBitCast:

1512 case CK_LValueToRValue:

1513 case CK_LValueToRValueBitCast:

1514 case CK_UncheckedDerivedToBase:

1515 case CK_HLSLArrayRValue:

1516 return false;

1517 }

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

1519}

1520

1521

1522

1523

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

1528 break;

1530 }

1531

1532

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

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

1535

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

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

1538

1539 if ((isa(E) || isa(E)) &&

1541 return true;

1542

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

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

1547

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

1550

1551

1552 return false;

1553}

1554

1555

1556void

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

1559

1560

1562

1563 return;

1564 } else if (isa(E) || isa(E)) {

1565 return EmitNullInitializationToLValue(LV);

1566 } else if (isa(E)) {

1567

1568 return;

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

1572 }

1573

1575}

1576

1577void AggExprEmitter::EmitNullInitializationToLValue(LValue lv) {

1579

1580

1581

1583 return;

1584

1586

1588

1589

1592 } else {

1595 }

1596 } else {

1597

1598

1599

1601 }

1602}

1603

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

1606 E->getInitializedFieldInUnion(),

1607 E->getArrayFiller());

1608}

1609

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

1611 if (E->hadArrayRangeDesignator())

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

1613

1614 if (E->isTransparent())

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

1616

1617 VisitCXXParenListOrInitListExpr(

1618 E, E->inits(), E->getInitializedFieldInUnion(), E->getArrayFiller());

1619}

1620

1621void AggExprEmitter::VisitCXXParenListOrInitListExpr(

1623 FieldDecl *InitializedFieldInUnion, Expr *ArrayFiller) {

1624#if 0

1625

1626

1627

1628

1629

1630 if (llvm::Constant *C =

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

1632 llvm::GlobalVariable* GV =

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

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

1635 EmitFinalDestCopy(ExprToVisit->getType(),

1637 return;

1638 }

1639#endif

1640

1642

1644

1645

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

1649 InitExprs, ArrayFiller);

1650 return;

1652

1653

1654

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

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

1658 return;

1659 }

1660

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

1663

1664

1665

1666

1667

1668 unsigned NumInitElements = InitExprs.size();

1670

1671

1672

1674 CodeGenFunction::CleanupDeactivationScope DeactivateCleanups(CGF);

1675

1676 unsigned curInitIndex = 0;

1677

1678

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

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

1681 "missing initializer for base class");

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

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

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

1687 false);

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

1695

1697 Base.getType().isDestructedType())

1699 }

1700 }

1701

1702

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

1704

1705 const bool ZeroInitPadding =

1707

1708 if (record->isUnion()) {

1709

1710

1711 if (!InitializedFieldInUnion) {

1712

1713

1714#ifndef NDEBUG

1715

1716

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

1718 assert(

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

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

1721#endif

1722 return;

1723 }

1724

1725

1727

1729 if (NumInitElements) {

1730

1731 EmitInitializationToLValue(InitExprs[0], FieldLoc);

1732 if (ZeroInitPadding) {

1736 DoZeroInitPadding(FieldSize, TotalSize, nullptr);

1737 }

1738 } else {

1739

1740 if (ZeroInitPadding)

1741 EmitNullInitializationToLValue(DestLV);

1742 else

1743 EmitNullInitializationToLValue(FieldLoc);

1744 }

1745 return;

1746 }

1747

1748

1749

1752

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

1754

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

1756 break;

1757

1758

1759 if (field->isUnnamedBitField())

1760 continue;

1761

1762

1763

1764

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

1767 break;

1768

1769 if (ZeroInitPadding)

1770 DoZeroInitPadding(PaddingStart,

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

1772

1774

1776

1777 if (curInitIndex < NumInitElements) {

1778

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

1780 } else {

1781

1782 EmitNullInitializationToLValue(LV);

1783 }

1784

1785

1786

1787

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

1791 if (dtorKind) {

1795 }

1796 }

1797 }

1798 if (ZeroInitPadding) {

1801 DoZeroInitPadding(PaddingStart, TotalSize, nullptr);

1802 }

1803}

1804

1805void AggExprEmitter::DoZeroInitPadding(uint64_t &PaddingStart,

1806 uint64_t PaddingEnd,

1808

1813 if (!Start.isZero())

1814 Addr = Builder.CreateConstGEP(Addr, Start.getQuantity());

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

1817 };

1818

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

1820

1821

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

1827 if (StorageStart > PaddingStart)

1828 InitBytes(PaddingStart, StorageStart);

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

1836 PaddingStart = StorageStart + Info.StorageSize;

1837 }

1838 return;

1839 }

1840

1841 if (PaddingStart < PaddingEnd)

1842 InitBytes(PaddingStart, PaddingEnd);

1843 if (NextField != nullptr)

1844 PaddingStart =

1846}

1847

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

1849 llvm::Value *outerBegin) {

1850

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

1852

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

1854 uint64_t numElements = E->getArraySize().getZExtValue();

1855

1856 if (!numElements)

1857 return;

1858

1859

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

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

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

1864 indices, "arrayinit.begin");

1865

1866

1867

1868 if (!outerBegin)

1869 outerBegin = begin;

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

1871

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

1878

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

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

1881

1882

1884 llvm::PHINode *index =

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

1886 index->addIncoming(zero, entryBB);

1887 llvm::Value *element =

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

1889

1890

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

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

1897 elementAlign,

1900 } else {

1902 }

1903

1904

1905 {

1906

1907

1908 CodeGenFunction::RunCleanupsScope CleanupsScope(CGF);

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

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

1912

1913 if (InnerLoop) {

1914

1919 AggExprEmitter(CGF, elementSlot, false)

1920 .VisitArrayInitLoopExpr(InnerLoop, outerBegin);

1921 } else

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

1923 }

1924

1925

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

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

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

1929

1930

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

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

1933 "arrayinit.done");

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

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

1936

1938

1939

1940 if (dtorKind)

1942}

1943

1946

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

1949 VisitInitListExpr(E->getUpdater());

1950}

1951

1952

1953

1954

1955

1956

1957

1958

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

1961 E = MTE->getSubExpr();

1963

1964

1966

1967

1968

1969 const InitListExpr *ILE = dyn_cast(E);

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

1974

1975

1976

1977

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

1982

1983 unsigned ILEElement = 0;

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

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

1986 NumNonZeroBytes +=

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

1989

1990

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

1993 break;

1994 if (Field->isUnnamedBitField())

1995 continue;

1996

1998

1999

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

2003 else

2005 }

2006

2007 return NumNonZeroBytes;

2008 }

2009 }

2010

2011

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

2015 return NumNonZeroBytes;

2016}

2017

2018

2019

2020

2023

2024

2026 return;

2027

2028

2032 const CXXRecordDecl *RD = cast(RT->getDecl());

2034 return;

2035 }

2036

2037

2040 return;

2041

2042

2043

2045 if (NumNonZeroBytes*4 > Size)

2046 return;

2047

2048

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

2050

2053

2054

2056}

2057

2058

2059

2060

2061

2062

2063

2064

2065void CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot) {

2067 "Invalid aggregate expression to emit");

2069 "slot has bits but no address");

2070

2071

2073

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

2075}

2076

2085 return LV;

2086}

2087

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

2092 .EmitFinalDestCopy(Type, Src, SrcKind);

2093}

2094

2099

2100

2103

2104

2105

2106

2113

2114

2116}

2117

2120

2121

2122

2123 if (IsVirtual)

2125

2126

2129

2130

2131

2132

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

2138

2139

2141}

2142

2145 bool isVolatile) {

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

2147

2150

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

2155 Record->hasTrivialCopyAssignment() ||

2156 Record->hasTrivialMoveConstructor() ||

2157 Record->hasTrivialMoveAssignment() ||

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

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

2160 "constructor or assignment operator");

2161

2162 if (Record->isEmpty())

2163 return;

2164 }

2165 }

2166

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

2170 Src))

2171 return;

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

2174 Src))

2175 return;

2176 }

2177 }

2178

2179

2180

2181

2182

2183

2184

2185

2186

2187

2188

2189

2190

2191

2192

2194 if (MayOverlap)

2196 else

2198

2199 llvm::Value *SizeVal = nullptr;

2201

2202 if (auto *VAT = dyn_cast_or_null(

2208 SizeVal = Builder.CreateNUWMul(

2209 SizeVal,

2211 }

2212 }

2213 if (!SizeVal) {

2215 }

2216

2217

2218

2219

2220

2221

2222

2223

2224

2225

2226

2227

2228

2229

2232

2233

2235

2238 if (Record->hasObjectMember()) {

2240 SizeVal);

2241 return;

2242 }

2248 SizeVal);

2249 return;

2250 }

2251 }

2252 }

2253

2255

2256

2257

2258

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

2261

2266 }

2267}

Defines the clang::ASTContext interface.

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

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

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.

static bool isBlockVarRef(const Expr *E)

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

static bool isTrivialFiller(Expr *E)

Determine if E is a trivial array filler, that is, one that is equivalent to zero-initialization.

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

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

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

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...

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

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

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

Defines the C++ template declaration subclasses.

llvm::MachO::Record Record

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,...

bool hasSameType(QualType T1, QualType T2) const

Determine whether the given types T1 and T2 are equivalent.

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<=>,...

CanQualType getSizeType() const

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

QualType removeAddrSpaceQualType(QualType T) const

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

TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const

TypeInfoChars getTypeInfoInChars(const Type *T) const

int64_t toBits(CharUnits CharSize) const

Convert a size in characters to a size in bits.

bool hasSameUnqualifiedType(QualType T1, QualType T2) const

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

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.

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

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...

Represents a loop initializing the elements of an array.

ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.

Represents an array type, per C99 6.7.5.2 - Array Declarators.

QualType getElementType() const

AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...

QualType getValueType() const

Gets the type contained by this atomic type, i.e.

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

Represents binding an expression to a temporary.

Represents a call to a C++ constructor.

A default argument (C++ [dcl.fct.default]).

A use of a default initializer in a constructor or in aggregate initialization.

Expr * getExpr()

Get the initialization expression that will be used.

Represents a call to an inherited base class constructor from an inheriting constructor.

Represents a list-initialization with parenthesis.

Represents a C++ struct/union/class.

bool isTriviallyCopyable() const

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

bool hasUserDeclaredConstructor() const

Determine whether this class has any user-declared constructors.

bool isEmpty() const

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

A rewritten comparison expression that was originally written using operator syntax.

An expression "T()" which creates an rvalue of a non-class type T.

Implicit construction of a std::initializer_list object from an array temporary within list-initia...

A C++ throw-expression (C++ [except.throw]).

A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

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.

ChooseExpr - GNU builtin-in function __builtin_choose_expr.

Expr * getChosenSubExpr() const

getChosenSubExpr - Return the subexpression chosen according to the condition.

Represents a 'co_await' expression.

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

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.

llvm::PointerType * getType() const

Return the type of the pointer value.

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

A scoped helper to set the current debug location to the specified location or preferred location of ...

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

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

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

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.

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

CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...

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 EmitNullInitialization(Address DestPtr, QualType Ty)

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

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

Create a store to.

llvm::Value * EmitLifetimeStart(llvm::TypeSize Size, llvm::Value *Addr)

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

DeactivateCleanupBlock - Deactivates the given cleanup block.

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

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

LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)

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

LValue EmitAggExprToLValue(const Expr *E)

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

void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr)

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)

static bool hasScalarEvaluationKind(QualType T)

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

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...

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

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

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

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

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

bool hasVolatileMember(QualType T)

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

void callCStructCopyAssignmentOperator(LValue Dst, LValue Src)

void callCStructMoveConstructor(LValue Dst, LValue Src)

llvm::SmallVector< DeferredDeactivateCleanup > DeferredDeactivationCleanupStack

void callCStructCopyConstructor(LValue Dst, LValue Src)

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

createBasicBlock - Create an LLVM basic block.

const LangOptions & getLangOpts() const

LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)

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

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

EmitBlock - Emit the given block.

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

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...

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...

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

void EmitIgnoredExpr(const Expr *E)

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

llvm::Type * ConvertTypeForMem(QualType T)

LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)

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

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...

Destroyer * getDestroyer(QualType::DestructionKind destructionKind)

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

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

const TargetInfo & getTarget() const

llvm::Value * getTypeSize(QualType Ty)

Returns calculated size of the specified type.

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

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

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.

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

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

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

bool HaveInsertPoint() const

HaveInsertPoint - True if an insertion point is defined.

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

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

AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD)

Determine whether a field initialization may overlap some other object.

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

EmitAggregateCopy - Emit an aggregate copy.

const TargetCodeGenInfo & getTargetHooks() const

RValue EmitReferenceBindingToExpr(const Expr *E)

Emits a reference binding to the passed in expression.

void EmitAggExpr(const Expr *E, AggValueSlot AS)

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

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

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

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())

ASTContext & getContext() const

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

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

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

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

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...

void callCStructMoveAssignmentOperator(LValue Dst, LValue Src)

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)

void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest)

llvm::Type * ConvertType(QualType T)

CodeGenTypes & getTypes() const

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

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

uint64_t getProfileCount(const Stmt *S)

Get the profiler's count for the given statement.

LValue EmitPseudoObjectLValue(const PseudoObjectExpr *e)

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)

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

EmitInitializationToLValue - Emit an initializer to an LValue.

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

llvm::LLVMContext & getLLVMContext()

bool LValueIsSuitableForInlineAtomic(LValue Src)

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

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

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

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...

RValue EmitAtomicExpr(AtomicExpr *E)

LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E)

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

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

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

llvm::MDNode * getTBAAStructInfo(QualType QTy)

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.

TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, TBAAAccessInfo SrcInfo)

mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the purposes of memory transfer call...

const LangOptions & getLangOpts() const

const llvm::DataLayout & getDataLayout() const

CGCXXABI & getCXXABI() const

void DecorateInstructionWithTBAA(llvm::Instruction *Inst, TBAAAccessInfo TBAAInfo)

DecorateInstructionWithTBAA - Decorate the instruction with a TBAA tag.

ASTContext & getContext() const

const CodeGenOptions & getCodeGenOpts() 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...

A saved depth on the scope stack.

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

void setNonGC(bool Value)

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.

An abstract representation of an aligned address.

llvm::Value * getPointer() const

static RawAddress invalid()

ReturnValueSlot - Contains the address where the return value of a function can be stored,...

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.

CompoundLiteralExpr - [C99 6.5.2.5].

Represents the canonical version of C arrays with a specified constant size.

ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...

Represents a 'co_yield' expression.

specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...

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

Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...

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.

Represents a C11 generic selection.

Represents an implicitly-generated value initialization of an object of a given type.

Describes an C or C++ initializer list.

bool isTransparent() const

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

unsigned getNumInits() const

const Expr * getInit(unsigned Init) const

A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...

Expr *const * const_capture_init_iterator

Const iterator that walks over the capture initialization arguments.

Represents a prvalue temporary that is written into memory so that a reference can bind to it.

MemberExpr - [C99 6.5.2.3] Structure and Union Members.

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

Represents a place-holder for an object not to be initialized by anything.

ObjCIvarRefExpr - A reference to an ObjC instance variable.

An expression that sends a message to the given Objective-C object or class.

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 ...

ParenExpr - This represents a parenthesized expression, e.g.

const Expr * getSubExpr() const

[C99 6.4.2.2] - A predefined identifier such as func.

PseudoObjectExpr - An expression which accesses a pseudo-object l-value.

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.

bool isPODType(const ASTContext &Context) const

Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).

@ PCK_Struct

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

The collection of all-type qualifiers we support.

Represents a struct/union/class.

bool hasObjectMember() const

field_range fields() const

field_iterator field_begin() const

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

RecordDecl * getDecl() const

Scope - A scope is a transient data structure that is used while parsing the program.

StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).

RetTy Visit(PTR(Stmt) S, ParamTys... P)

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

Stmt - This represents one statement.

StringLiteral - This represents a string literal expression, e.g.

Represents a reference to a non-type template parameter that has been substituted with a template arg...

uint64_t getPointerWidth(LangAS AddrSpace) const

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

The base class of the type hierarchy.

CXXRecordDecl * getAsCXXRecordDecl() const

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

bool isConstantArrayType() const

bool isPointerType() const

const T * castAs() const

Member-template castAs.

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.

bool isAnyComplexType() const

bool hasSignedIntegerRepresentation() const

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

bool isMemberPointerType() const

bool isAtomicType() 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 isRealFloatingType() const

Floating point categories.

const T * getAs() const

Member-template getAs'.

bool isNullPtrType() const

bool isRecordType() const

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

Represents a call to the builtin function __builtin_va_arg.

Represents a variable declaration or definition.

@ 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

Matches atomic types.

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.

bool Zero(InterpState &S, CodePtr OpPC)

bool GE(InterpState &S, CodePtr OpPC)

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

LangAS

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

CastKind

CastKind - The kind of operation required for a conversion.

ExprValueKind

The categorization of expression values, currently following the C++11 scheme.

const FunctionProtoType * T

U cast(CodeGen::Address addr)

Diagnostic wrappers for TextAPI types for error reporting.

cl::opt< bool > EnableSingleByteCoverage

Structure with information about how a bitfield should be accessed.

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