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

1

2

3

4

5

6

7

8

9

10

11

12

17

21#include

22

23using namespace clang;

25

26namespace {

27

28

29

30

32

34

35

36 if (const DeclRefExpr *dre = dyn_cast(e)) {

37 const VarDecl *var = dyn_cast(dre->getDecl());

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

39 }

40

41

42

43

44 if (const BinaryOperator *op = dyn_cast(e)) {

45

46

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

49

50

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

53

54

55 return false;

56

57

59 dyn_cast(e)) {

62

63

64 } else if (const OpaqueValueExpr *op = dyn_cast(e)) {

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

67

68

69

70

71

72 } else if (const CastExpr *cast = dyn_cast(e)) {

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

74 return false;

76

77

78

79 } else if (const UnaryOperator *uop = dyn_cast(e)) {

81

82

83 } else if (const MemberExpr *mem = dyn_cast(e)) {

85

86

87 } else if (const ArraySubscriptExpr *sub = dyn_cast(e)) {

89 }

90

91 return false;

92}

93

94class AggExprEmitter : public StmtVisitor {

95

96 CIRGenFunction &cgf;

97 AggValueSlot dest;

98

99

100

101

102

103

104

105 void withReturnValueSlot(const Expr *e,

106 llvm::function_ref<RValue(ReturnValueSlot)> fn);

107

108 AggValueSlot ensureSlot(mlir::Location loc, QualType t) {

109 if (!dest.isIgnored())

110 return dest;

111 return cgf.createAggTemp(t, loc, "agg.tmp.ensured");

112 }

113

114 void ensureDest(mlir::Location loc, QualType ty) {

115 if (!dest.isIgnored())

116 return;

117 dest = cgf.createAggTemp(ty, loc, "agg.tmp.ensured");

118 }

119

120public:

121 AggExprEmitter(CIRGenFunction &cgf, AggValueSlot dest)

122 : cgf(cgf), dest(dest) {}

123

124

125

126

127 void emitAggLoadOfLValue(const Expr *e);

128

129 void emitArrayInit(Address destPtr, cir::ArrayType arrayTy, QualType arrayQTy,

130 Expr *exprToVisit, ArrayRef<Expr *> args,

131 Expr *arrayFiller);

132

133

134 void emitFinalDestCopy(QualType type, const LValue &src);

135

136 void emitCopy(QualType type, const AggValueSlot &dest,

137 const AggValueSlot &src);

138

139 void emitInitializationToLValue(Expr *e, LValue lv);

140

141 void emitNullInitializationToLValue(mlir::Location loc, LValue lv);

142

143 void Visit(Expr *e) { StmtVisitor::Visit(e); }

144

145 void VisitArraySubscriptExpr(ArraySubscriptExpr *e) {

146 emitAggLoadOfLValue(e);

147 }

148

149 void VisitCallExpr(const CallExpr *e);

150 void VisitStmtExpr(const StmtExpr *e) {

151 CIRGenFunction::StmtExprEvaluation eval(cgf);

152 Address retAlloca =

154 (void)cgf.emitCompoundStmt(*e->getSubStmt(), &retAlloca, dest);

155 }

156

157 void VisitBinAssign(const BinaryOperator *e) {

158

159

160 assert(cgf.getContext().hasSameUnqualifiedType(e->getLHS()->getType(),

162 "Invalid assignment");

163

167 "block var reference with side effects");

168 return;

169 }

170

171 LValue lhs = cgf.emitLValue(e->getLHS());

172

173

174

176

177

182

183

186

187 cgf.emitAggExpr(e->getRHS(), lhsSlot);

188

189

190 emitFinalDestCopy(e->getType(), lhs);

191

192 if (!dest.isIgnored() && !dest.isExternallyDestructed() &&

196 }

197

198 void VisitDeclRefExpr(DeclRefExpr *e) { emitAggLoadOfLValue(e); }

199

200 void VisitInitListExpr(InitListExpr *e);

201 void VisitCXXConstructExpr(const CXXConstructExpr *e);

202

203 void visitCXXParenListOrInitListExpr(Expr *e, ArrayRef<Expr *> args,

204 FieldDecl *initializedFieldInUnion,

205 Expr *arrayFiller);

206 void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die) {

207 CIRGenFunction::CXXDefaultInitExprScope Scope(cgf, die);

209 }

210 void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *e) {

211

212

213 bool wasExternallyDestructed = dest.isExternallyDestructed();

215

216

217 dest.setExternallyDestructed();

218

220

221

222 if (!wasExternallyDestructed)

223 cgf.emitCXXTemporary(e->getTemporary(), e->getType(), dest.getAddress());

224 }

226 void VisitExprWithCleanups(ExprWithCleanups *e);

227

228

229 void VisitCastExpr(CastExpr *e) {

231 case CK_LValueToRValue:

232

233

236 "AggExprEmitter: volatile lvalue-to-rvalue cast");

237 [[fallthrough]];

238 case CK_NoOp:

239 case CK_UserDefinedConversion:

240 case CK_ConstructorConversion:

241 assert(cgf.getContext().hasSameUnqualifiedType(e->getSubExpr()->getType(),

243 "Implicit cast types must be compatible");

245 break;

246 default:

248 std::string("AggExprEmitter: VisitCastExpr: ") +

250 break;

251 }

252 }

253 void VisitStmt(Stmt *s) {

254 cgf.cgm.errorNYI(s->getSourceRange(),

255 std::string("AggExprEmitter::VisitStmt: ") +

256 s->getStmtClassName());

257 }

258 void VisitParenExpr(ParenExpr *pe) { Visit(pe->getSubExpr()); }

259 void VisitGenericSelectionExpr(GenericSelectionExpr *ge) {

261 }

262 void VisitCoawaitExpr(CoawaitExpr *e) {

263 cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitCoawaitExpr");

264 }

265 void VisitCoyieldExpr(CoyieldExpr *e) {

266 cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitCoyieldExpr");

267 }

268 void VisitUnaryCoawait(UnaryOperator *e) {

269 cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitUnaryCoawait");

270 }

271 void VisitUnaryExtension(UnaryOperator *e) { Visit(e->getSubExpr()); }

272 void VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e) {

274 "AggExprEmitter: VisitSubstNonTypeTemplateParmExpr");

275 }

276 void VisitConstantExpr(ConstantExpr *e) {

277 cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitConstantExpr");

278 }

279 void VisitMemberExpr(MemberExpr *e) { emitAggLoadOfLValue(e); }

280 void VisitUnaryDeref(UnaryOperator *e) { emitAggLoadOfLValue(e); }

281 void VisitStringLiteral(StringLiteral *e) { emitAggLoadOfLValue(e); }

282 void VisitCompoundLiteralExpr(CompoundLiteralExpr *e);

283

284 void VisitPredefinedExpr(const PredefinedExpr *e) {

286 "AggExprEmitter: VisitPredefinedExpr");

287 }

288 void VisitBinaryOperator(const BinaryOperator *e) {

290 "AggExprEmitter: VisitBinaryOperator");

291 }

292 void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *e) {

294 "AggExprEmitter: VisitPointerToDataMemberBinaryOperator");

295 }

296 void VisitBinComma(const BinaryOperator *e) {

297 cgf.emitIgnoredExpr(e->getLHS());

299 }

300 void VisitBinCmp(const BinaryOperator *e) {

301 cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitBinCmp");

302 }

303 void VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *e) {

305 "AggExprEmitter: VisitCXXRewrittenBinaryOperator");

306 }

307 void VisitObjCMessageExpr(ObjCMessageExpr *e) {

309 "AggExprEmitter: VisitObjCMessageExpr");

310 }

311 void VisitObjCIVarRefExpr(ObjCIvarRefExpr *e) {

313 "AggExprEmitter: VisitObjCIVarRefExpr");

314 }

315

316 void VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *e) {

317 AggValueSlot dest = ensureSlot(cgf.getLoc(e->getExprLoc()), e->getType());

318 LValue destLV = cgf.makeAddrLValue(dest.getAddress(), e->getType());

319 emitInitializationToLValue(e->getBase(), destLV);

321 }

322 void VisitAbstractConditionalOperator(const AbstractConditionalOperator *e) {

324 "AggExprEmitter: VisitAbstractConditionalOperator");

325 }

326 void VisitChooseExpr(const ChooseExpr *e) { Visit(e->getChosenSubExpr()); }

327 void VisitCXXParenListInitExpr(CXXParenListInitExpr *e) {

328 visitCXXParenListOrInitListExpr(e, e->getInitExprs(),

331 }

332

333 void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *e,

334 llvm::Value *outerBegin = nullptr) {

336 "AggExprEmitter: VisitArrayInitLoopExpr");

337 }

338 void VisitImplicitValueInitExpr(ImplicitValueInitExpr *e) {

340 "AggExprEmitter: VisitImplicitValueInitExpr");

341 }

342 void VisitNoInitExpr(NoInitExpr *e) {

343 cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitNoInitExpr");

344 }

345 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *dae) {

346 CIRGenFunction::CXXDefaultArgExprScope scope(cgf, dae);

348 }

349 void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *e) {

351 "AggExprEmitter: VisitCXXInheritedCtorInitExpr");

352 }

353 void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *e) {

355 "AggExprEmitter: VisitCXXStdInitializerListExpr");

356 }

357 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) {

359 "AggExprEmitter: VisitCXXScalarValueInitExpr");

360 }

361 void VisitCXXTypeidExpr(CXXTypeidExpr *e) {

362 cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitCXXTypeidExpr");

363 }

364 void VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *e) {

366 }

367 void VisitOpaqueValueExpr(OpaqueValueExpr *e) {

369 "AggExprEmitter: VisitOpaqueValueExpr");

370 }

371

372 void VisitPseudoObjectExpr(PseudoObjectExpr *e) {

374 "AggExprEmitter: VisitPseudoObjectExpr");

375 }

376

377 void VisitVAArgExpr(VAArgExpr *e) {

378 cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitVAArgExpr");

379 }

380

381 void VisitCXXThrowExpr(const CXXThrowExpr *e) {

382 cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitCXXThrowExpr");

383 }

384 void VisitAtomicExpr(AtomicExpr *e) {

385 cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitAtomicExpr");

386 }

387};

388

389}

390

392 if (!e)

393 return true;

394

396 return true;

397

398 if (auto *ile = dyn_cast(e)) {

399 if (ile->getNumInits())

400 return false;

402 }

403

404 if (const auto *cons = dyn_cast_or_null(e))

405 return cons->getConstructor()->isDefaultConstructor() &&

406 cons->getConstructor()->isTrivial();

407

408 return false;

409}

410

411

412

413void AggExprEmitter::emitAggLoadOfLValue(const Expr *e) {

415

416

418

419 emitFinalDestCopy(e->getType(), lv);

420}

421

422void AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {

424

425

426 emitAggLoadOfLValue(e);

427 return;

428 }

429

431

432

433

434 bool destruct =

436 if (destruct)

438

440

441 if (destruct)

445}

446

447void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy,

448 QualType arrayQTy, Expr *e,

449 ArrayRef<Expr *> args, Expr *arrayFiller) {

450 CIRGenBuilderTy &builder = cgf.getBuilder();

452

453 const uint64_t numInitElements = args.size();

454

455 const QualType elementType =

457

459 cgf.cgm.errorNYI(loc, "initialized array requires destruction");

460 return;

461 }

462

464

465 const mlir::Type cirElementType = cgf.convertType(elementType);

466 const cir::PointerType cirElementPtrType =

468

469 auto begin = cir::CastOp::create(builder, loc, cirElementPtrType,

470 cir::CastKind::array_to_ptrdecay,

472

473 const CharUnits elementSize =

475 const CharUnits elementAlign =

477

478

479

480

481

482

483 mlir::Value element = begin;

484

485

486

487 mlir::Value one;

488

489

490 for (uint64_t i = 0; i != numInitElements; ++i) {

491

492 if (i > 0) {

495 }

496

497 const Address address = Address(element, cirElementType, elementAlign);

498 const LValue elementLV = cgf.makeAddrLValue(address, elementType);

499 emitInitializationToLValue(args[i], elementLV);

500 }

501

502 const uint64_t numArrayElements = arrayTy.getSize();

503

504

505 const bool hasTrivialFiller = isTrivialFiller(arrayFiller);

506

507

508

509

510 if (numInitElements != numArrayElements &&

511 !(dest.isZeroed() && hasTrivialFiller &&

513

514 if (numInitElements) {

516 element = cir::PtrStrideOp::create(builder, loc, cirElementPtrType,

517 element, one);

518 }

519

520

521

523 cirElementPtrType, cgf.getPointerAlign(), loc, "arrayinit.temp");

524 LValue tmpLV = cgf.makeAddrLValue(tmpAddr, elementPtrType);

526

527

528 cir::ConstantOp numArrayElementsConst = builder.getConstInt(

529 loc, mlir::castcir::IntType(cgf.ptrDiffTy), numArrayElements);

530 mlir::Value end = cir::PtrStrideOp::create(builder, loc, cirElementPtrType,

531 begin, numArrayElementsConst);

532

534 loc,

535

536 [&](mlir::OpBuilder &b, mlir::Location loc) {

537 cir::LoadOp currentElement = builder.createLoad(loc, tmpAddr);

538 cir::CmpOp cmp = cir::CmpOp::create(builder, loc, cir::CmpOpKind::ne,

539 currentElement, end);

541 },

542

543 [&](mlir::OpBuilder &b, mlir::Location loc) {

544 cir::LoadOp currentElement = builder.createLoad(loc, tmpAddr);

545

547

548

550 Address(currentElement, cirElementType, elementAlign),

551 elementType);

552 if (arrayFiller)

553 emitInitializationToLValue(arrayFiller, elementLV);

554 else

555 emitNullInitializationToLValue(loc, elementLV);

556

557

559 cgf.cgm.errorNYI(loc, "update destructed array element for EH");

560 return;

561 }

562

563

564 cir::ConstantOp one = builder.getConstInt(

565 loc, mlir::castcir::IntType(cgf.ptrDiffTy), 1);

566 auto nextElement = cir::PtrStrideOp::create(

567 builder, loc, cirElementPtrType, currentElement, one);

569

571 });

572 }

573}

574

575

576void AggExprEmitter::emitFinalDestCopy(QualType type, const LValue &src) {

577

578

579

580

582 return;

583

587

591 emitCopy(type, dest, srcAgg);

592}

593

594

595

596

597

598void AggExprEmitter::emitCopy(QualType type, const AggValueSlot &dest,

599 const AggValueSlot &src) {

601

602

603

604

610}

611

612void AggExprEmitter::emitInitializationToLValue(Expr *e, LValue lv) {

613 const QualType type = lv.getType();

614

619 return emitNullInitializationToLValue(loc, lv);

620 }

621

623 return;

624

625 if (type->isReferenceType()) {

628 }

629

633 break;

639

640 return;

642 if (lv.isSimple())

644 else

646 return;

647 }

648}

649

650void AggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *e) {

653}

654

655void AggExprEmitter::emitNullInitializationToLValue(mlir::Location loc,

656 LValue lv) {

657 const QualType type = lv.getType();

658

659

660

662 return;

663

665

667 if (lv.isSimple()) {

669 return;

670 }

671

673 return;

674 }

675

676

677

678

680}

681

682void AggExprEmitter::VisitLambdaExpr(LambdaExpr *e) {

683 CIRGenFunction::SourceLocRAIIObject loc{cgf, cgf.getLoc(e->getSourceRange())};

685 [[maybe_unused]] LValue slotLV =

687

688

689

691

692 for (auto [curField, capture, captureInit] : llvm::zip(

694

695 llvm::StringRef fieldName = curField->getName();

696 if (capture.capturesVariable()) {

697 assert(!curField->isBitField() && "lambdas don't have bitfield members!");

698 ValueDecl *v = capture.getCapturedVar();

699 fieldName = v->getName();

701 } else if (capture.capturesThis()) {

703 } else {

706 }

707

708

709 LValue lv =

711 if (curField->hasCapturedVLAType())

713

714 emitInitializationToLValue(captureInit, lv);

715

716

718 curField->getType().isDestructedType())

720 }

721}

722

723void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *e) {

724 CIRGenFunction::RunCleanupsScope cleanups(cgf);

726}

727

728void AggExprEmitter::VisitCallExpr(const CallExpr *e) {

731 return;

732 }

733

734 withReturnValueSlot(

735 e, [&](ReturnValueSlot slot) { return cgf.emitCallExpr(e, slot); });

736}

737

738void AggExprEmitter::withReturnValueSlot(

739 const Expr *e, llvm::function_ref<RValue(ReturnValueSlot)> fn) {

740 QualType retTy = e->getType();

741

743 bool requiresDestruction =

745 if (requiresDestruction)

748 "withReturnValueSlot: return value requiring destruction is NYI");

749

750

751

752

753

754

757

760

763 fn(ReturnValueSlot(retAddr));

764}

765

766void AggExprEmitter::VisitInitListExpr(InitListExpr *e) {

768 llvm_unreachable("GNU array range designator extension");

769

771 return Visit(e->getInit(0));

772

773 visitCXXParenListOrInitListExpr(

775}

776

777void AggExprEmitter::visitCXXParenListOrInitListExpr(

778 Expr *e, ArrayRef<Expr *> args, FieldDecl *initializedFieldInUnion,

779 Expr *arrayFiller) {

780

782 const AggValueSlot dest = ensureSlot(loc, e->getType());

783

785 cir::ArrayType arrayTy =

788 arrayFiller);

789 return;

792 "visitCXXParenListOrInitListExpr variable array type");

793 return;

794 }

795

798 "visitCXXParenListOrInitListExpr array type");

799 return;

800 }

801

802 assert(e->getType()->isRecordType() && "Only support structs/unions here!");

803

804

805

806

807

808 unsigned numInitElements = args.size();

810

811

812

814

815 unsigned curInitIndex = 0;

816

817

818 if (auto *cxxrd = dyn_cast(record)) {

819 assert(numInitElements >= cxxrd->getNumBases() &&

820 "missing initializer for base class");

821 for (auto &base : cxxrd->bases()) {

822 assert(!base.isVirtual() && "should not see vbases here");

823 CXXRecordDecl *baseRD = base.getType()->getAsCXXRecordDecl();

825 loc, dest.getAddress(), cxxrd, baseRD,

826 false);

832 cgf.emitAggExpr(args[curInitIndex++], aggSlot);

833 if (base.getType().isDestructedType()) {

835 "push deferred deactivation cleanup");

836 return;

837 }

838 }

839 }

840

841

842 CIRGenFunction::FieldConstructionScope fcScope(cgf, dest.getAddress());

843

845

846 if (record->isUnion()) {

848 "visitCXXParenListOrInitListExpr union type");

849 return;

850 }

851

852

853

854 for (const FieldDecl *field : record->fields()) {

855

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

857 break;

858

859

860 if (field->isUnnamedBitField())

861 continue;

862

863

864

865

866 if (curInitIndex == numInitElements && dest.isZeroed() &&

868 break;

869 LValue lv =

871

873

874 if (curInitIndex < numInitElements) {

875

876 CIRGenFunction::SourceLocRAIIObject loc{

877 cgf, cgf.getLoc(record->getSourceRange())};

878 emitInitializationToLValue(args[curInitIndex++], lv);

879 } else {

880

882 }

883

884

885

886

887 if (field->getType().isDestructedType()) {

889 "visitCXXParenListOrInitListExpr destructor");

890 return;

891 }

892

893

894

895

896 }

897}

898

899

902

903

904

905 if (isVirtual)

907

908

909

910

913 getContext().getASTRecordLayout(baseRD).getSize() <=

916

917

919}

920

922 AggExprEmitter(*this, slot).Visit(const_cast<Expr *>(e));

923}

924

927 bool isVolatile) {

928

929

930 assert(!ty->isAnyComplexType() && "Unexpected copy of complex");

931

934

937 assert((record->hasTrivialCopyConstructor() ||

938 record->hasTrivialCopyAssignment() ||

939 record->hasTrivialMoveConstructor() ||

940 record->hasTrivialMoveAssignment() ||

941 record->hasAttr() || record->isUnion()) &&

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

943 "constructor or assignment operator");

944

945 if (record->isEmpty())

946 return;

947 }

948 }

949

951

952

953

954

955

956

957

958

959

960

961

962

963

964

965

967 if (mayOverlap)

968 typeInfo = getContext().getTypeInfoDataSizeInChars(ty);

969 else

970 typeInfo = getContext().getTypeInfoInChars(ty);

971

973

974

975

976

977

978

980 cgm.errorNYI("emitAggregateCopy: GC");

981

982 [[maybe_unused]] cir::CopyOp copyOp =

984

986}

987

988

993

994

995

996

1003

1004

1006}

1007

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)

Definition CIRGenExprAggregate.cpp:391

__device__ __2f16 float __ockl_bool s

cir::ConditionOp createCondition(mlir::Value condition)

Create a loop condition.

cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base, mlir::Value stride)

cir::PointerType getPointerTo(mlir::Type ty)

cir::DoWhileOp createDoWhile(mlir::Location loc, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> condBuilder, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> bodyBuilder)

Create a do-while operation.

cir::ConstantOp getConstantInt(mlir::Location loc, mlir::Type ty, int64_t value)

cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value={})

Create a yield operation.

QualType getPointerType(QualType T) const

Return the uniqued reference to the type for a pointer to the specified type.

const ArrayType * getAsArrayType(QualType T) const

Type Query functions.

CharUnits getTypeSizeInChars(QualType T) const

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

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

ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.

QualType getElementType() const

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

mlir::Value getPointer() const

mlir::Type getElementType() const

clang::CharUnits getAlignment() const

IsZeroed_t isZeroed() const

Overlap_t mayOverlap() const

static AggValueSlot forAddr(Address addr, clang::Qualifiers quals, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)

IsDestructed_t isExternallyDestructed() const

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

Address getAddress() const

void setExternallyDestructed(bool destructed=true)

IsAliased_t isPotentiallyAliased() const

void setVolatile(bool flag)

cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)

cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false)

static bool hasScalarEvaluationKind(clang::QualType type)

mlir::Type convertType(clang::QualType t)

static cir::TypeEvaluationKind getEvaluationKind(clang::QualType type)

Return the cir::TypeEvaluationKind of QualType type.

CIRGenTypes & getTypes() const

const clang::LangOptions & getLangOpts() const

cir::AllocaOp createTempAlloca(mlir::Type ty, mlir::Location loc, const Twine &name="tmp", mlir::Value arraySize=nullptr, bool insertIntoFnEntryBlock=false)

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

RValue emitCallExpr(const clang::CallExpr *e, ReturnValueSlot returnValue=ReturnValueSlot())

LValue emitLValue(const clang::Expr *e)

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

void emitAggregateCopy(LValue dest, LValue src, QualType eltTy, AggValueSlot::Overlap_t mayOverlap, bool isVolatile=false)

Emit an aggregate copy.

Definition CIRGenExprAggregate.cpp:925

mlir::Location getLoc(clang::SourceLocation srcLoc)

Helpers to convert Clang's SourceLocation to a MLIR Location.

void emitNullInitialization(mlir::Location loc, Address destPtr, QualType ty)

RValue emitReferenceBindingToExpr(const Expr *e)

Emits a reference binding to the passed in expression.

AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *fd)

Definition CIRGenExprAggregate.cpp:990

void emitCXXConstructExpr(const clang::CXXConstructExpr *e, AggValueSlot dest)

LValue emitAggExprToLValue(const Expr *e)

Definition CIRGenExprAggregate.cpp:1008

void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, clang::QualType ty, LValueBaseInfo baseInfo, bool isInit=false, bool isNontemporal=false)

static bool hasAggregateEvaluationKind(clang::QualType type)

void emitScalarInit(const clang::Expr *init, mlir::Location loc, LValue lvalue, bool capturedByInit=false)

LValue emitLValueForFieldInitialization(LValue base, const clang::FieldDecl *field, llvm::StringRef fieldName)

Like emitLValueForField, excpet that if the Field is a reference, this will return the address of the...

mlir::Value emitScalarExpr(const clang::Expr *e, bool ignoreResultAssign=false)

Emit the computation of the specified expression of scalar type.

Address getAddressOfDirectBaseInCompleteClass(mlir::Location loc, Address value, const CXXRecordDecl *derived, const CXXRecordDecl *base, bool baseIsVirtual)

Convert the given pointer to a complete class to the given direct base.

CIRGenBuilderTy & getBuilder()

AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *rd, const CXXRecordDecl *baseRD, bool isVirtual)

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

Definition CIRGenExprAggregate.cpp:900

void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)

LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)

mlir::Value emitStoreThroughBitfieldLValue(RValue src, LValue dstresult)

std::optional< mlir::Location > currSrcLoc

Use to track source locations across nested visitor traversals.

clang::ASTContext & getContext() const

void emitStoreThroughLValue(RValue src, LValue dst, bool isInit=false)

Store the specified rvalue into the specified lvalue, where both are guaranteed to the have the same ...

Address createMemTemp(QualType t, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr, mlir::OpBuilder::InsertPoint ip={})

Create a temporary memory object of the given type, with appropriate alignmen and cast it to the defa...

void emitAggExpr(const clang::Expr *e, AggValueSlot slot)

Definition CIRGenExprAggregate.cpp:921

DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)

Helpers to emit "not yet implemented" error diagnostics.

const clang::LangOptions & getLangOpts() const

mlir::Value emitNullConstant(QualType t, mlir::Location loc)

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

llvm::DenseMap< const clang::FieldDecl *, llvm::StringRef > lambdaFieldToName

Keep a map between lambda fields and names, this needs to be per module since lambdas might get gener...

bool isZeroInitializable(clang::QualType ty)

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

Address getAddress() const

static RValue get(mlir::Value v)

CXXTemporary * getTemporary()

const Expr * getSubExpr() const

Expr * getExpr()

Get the initialization expression that will be used.

MutableArrayRef< Expr * > getInitExprs()

FieldDecl * getInitializedFieldInUnion()

Represents a C++ struct/union/class.

SourceRange getSourceRange() const LLVM_READONLY

SourceRange getSourceRange() const LLVM_READONLY

Retrieve the source range of the expression.

SourceRange getSourceRange() const LLVM_READONLY

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

static const char * getCastKindName(CastKind CK)

CharUnits alignmentOfArrayElement(CharUnits elementSize) const

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

Expr * getChosenSubExpr() const

getChosenSubExpr - Return the subexpression chosen according to the condition.

const Expr * getInitializer() const

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

InitListExpr * getUpdater() const

This represents one expression.

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.

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

Expr * getResultExpr()

Return the result expression of this controlling expression.

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.

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

llvm::iterator_range< capture_init_iterator > capture_inits()

Retrieve the initialization expressions for this lambda's captures.

capture_range captures() const

Retrieve this lambda's captures.

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.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

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

const Expr * getSubExpr() const

A (possibly-)qualified type.

bool isVolatileQualified() const

Determine whether this type is volatile-qualified.

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

Represents a struct/union/class.

field_range fields() const

CompoundStmt * getSubStmt()

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

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

CXXRecordDecl * getAsCXXRecordDecl() const

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

bool isConstantArrayType() const

bool isReferenceType() const

bool isVariableArrayType() const

RecordDecl * castAsRecordDecl() const

bool isAnyComplexType() const

bool isRecordType() const

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

Expr * getSubExpr() const

Represents a variable declaration or definition.

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

constexpr Variable var(Literal L)

Returns the variable of L.

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

bool isa(CodeGen::Address addr)

U cast(CodeGen::Address addr)

static bool emitLifetimeMarkers()

static bool aggValueSlotDestructedFlag()

static bool aggValueSlotGC()

static bool aggValueSlotAlias()

static bool opLoadStoreAtomic()

static bool aggEmitFinalDestCopyRValue()

static bool aggValueSlotVolatile()

static bool opScopeCleanupRegion()

static bool atomicTypes()

static bool cudaSupport()

static bool requiresCleanups()

clang::CharUnits getPointerAlign() const