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

1

2

3

4

5

6

7

8

9

10

11

12

16

23

24using namespace clang;

26

27

28

29

32

33

34

35

36

37

38

39

40

41

42

43

45 return false;

46

47

48

50 return false;

51

52

54 return false;

55

56 return true;

57}

58

61 LValue &lhs) {

64

66 for (const auto *nd : indirectField->chain()) {

69 }

70 } else {

72 }

73}

74

81 "Must have member initializer!");

82 assert(memberInit->getInit() && "Must have initializer!");

83

85

86

89

92

93

94

98

100

101

102

103

104

105

108 if (array && constructor->isDefaulted() &&

111

112

114 unsigned srcArgIndex =

122

123

126 lhs.isVolatileQualified());

127

128

130 "Arrays of non-record types shouldn't need EH cleanup");

131 return;

132 }

133 }

134

136}

137

143

144namespace {

145

147 const CXXRecordDecl *baseClass;

148 bool baseIsVirtual;

149 CallBaseDtor(const CXXRecordDecl *base, bool baseIsVirtual)

150 : baseClass(base), baseIsVirtual(baseIsVirtual) {}

151

152 void emit(CIRGenFunction &cgf, Flags flags) override {

153 const CXXRecordDecl *derivedClass =

155

156 const CXXDestructorDecl *d = baseClass->getDestructor();

157

158

160 assert(cgf.currSrcLoc && "expected source location");

163 baseIsVirtual);

165 false, addr, thisTy);

166 }

167};

168

169

170

171struct DynamicThisUseChecker

172 : ConstEvaluatedExprVisitor {

173 using super = ConstEvaluatedExprVisitor;

174

175 bool usesThis = false;

176

177 DynamicThisUseChecker(const ASTContext &c) : super(c) {}

178

179

180

181

182

183

184 void VisitCXXThisExpr(const CXXThisExpr *e) { usesThis = true; }

185};

186}

187

189 DynamicThisUseChecker checker(c);

190 checker.Visit(init);

191 return checker.usesThis;

192}

193

194

195

196

197

198

202

204

205

208 if (baseIsVirtual)

210 else

212

213 return builder.createBaseClassAddr(loc, thisAddr, convertType(base),

215 true);

216}

217

221 assert(curFuncDecl && "loading 'this' without a func declaration?");

223

224 assert(baseInit->isBaseInitializer() && "Must have base initializer!");

225

227

230

232

233

234

235

238

239

240

242 loc, thisPtr, classDecl, baseClassDecl, isBaseVirtual);

247

249

251}

252

253

254

260 return;

261 }

262

264

265

266

267

268

269

270

271

272 bool constructVBases = ctorType != Ctor_Base &&

275 if (constructVBases &&

276 cgm.getTarget().getCXXABI().hasConstructorVariants()) {

278 "emitCtorPrologue: virtual base without variants");

279 return;

280 }

281

282

283 auto allInits = cd->inits();

284

285

286 auto virtualBaseEnd = std::find_if(

288 return !(Init->isBaseInitializer() && Init->isBaseVirtual());

289 });

290

291 auto nonVirtualBaseEnd = std::find_if(virtualBaseEnd, allInits.end(),

293 return !Init->isBaseInitializer();

294 });

295

296

297 auto virtualBaseInits = llvm::make_range(allInits.begin(), virtualBaseEnd);

298 auto nonVirtualBaseInits =

299 llvm::make_range(virtualBaseEnd, nonVirtualBaseEnd);

300 auto memberInits = llvm::make_range(nonVirtualBaseEnd, allInits.end());

301

302 const mlir::Value oldThisValue = cxxThisValue;

303

305 if (cgm.getCodeGenOpts().StrictVTablePointers &&

306 cgm.getCodeGenOpts().OptimizationLevel > 0 &&

308

309

311 "emitCtorPrologue: strict vtable pointers for vbase");

312 }

314 };

315

316

318 if (!constructVBases)

319 continue;

320 emitInitializer(virtualBaseInit);

321 }

322

324

325

327 assert(!nonVirtualBaseInit->isBaseVirtual());

328 emitInitializer(nonVirtualBaseInit);

329 }

330

332

334

335

337

338

339

340

343 assert(!member->isBaseInitializer());

344 assert(member->isAnyMemberInitializer() &&

345 "Delegating initializer on non-delegating constructor");

347 }

348}

349

352 CharUnits nonVirtualOffset, mlir::Value virtualOffset,

354 mlir::Type baseValueTy = {}, bool assumeNotNull = true) {

355

356 assert(!nonVirtualOffset.isZero() || virtualOffset != nullptr);

357

358

359 mlir::Value baseOffset;

360 if (!nonVirtualOffset.isZero()) {

361 if (virtualOffset) {

363 loc,

364 "applyNonVirtualAndVirtualOffset: virtual and non-virtual offset");

366 } else {

367 assert(baseValueTy && "expected base type");

368

370 loc, addr, baseValueTy, nonVirtualOffset.getQuantity(),

371 assumeNotNull);

372 }

373 } else {

374 baseOffset = virtualOffset;

375 }

376

377

378

379

383 mlir::Value adjusted = cir::PtrStrideOp::create(

384 cgf.getBuilder(), loc, charPtrType, charPtr, baseOffset);

386

387

388

389 CharUnits alignment;

390 if (virtualOffset) {

391 assert(nearestVBase && "virtual offset without vbase?");

393 nearestVBase);

394 } else {

396 }

398

399 return Address(ptr, alignment);

400}

401

403 const VPtr &vptr) {

404

405 mlir::Value vtableAddressPoint =

406 cgm.getCXXABI().getVTableAddressPointInStructor(

408

409 if (!vtableAddressPoint)

410 return;

411

412

413 mlir::Value virtualOffset{};

415

416 mlir::Type baseValueTy;

417 if (cgm.getCXXABI().isVirtualOffsetNeededForVTableField(*this, vptr)) {

418

419

420 virtualOffset = cgm.getCXXABI().getVirtualBaseClassOffset(

423 } else {

424

426 baseValueTy =

428 }

429

430

432 if (!nonVirtualOffset.isZero() || virtualOffset) {

434 loc, *this, classAddr, nonVirtualOffset, virtualOffset,

436 }

437

438

439

440

441

443 auto vtablePtr = cir::VTableGetVPtrOp::create(

444 builder, loc, builder.getPtrToVPtrType(), classAddr.getPointer());

446 builder.createStore(loc, vtableAddressPoint, vtableField);

449}

450

453

455 return;

456

457

458 if (cgm.getCXXABI().doStructorsInitializeVPtrs(rd))

461

463 cgm.getCXXABI().initializeHiddenVirtualInheritanceMembers(*this, rd);

464}

465

471 nullptr,

473 false, vtableClass, vbases,

474 vptrsResult);

475 return vptrsResult;

476}

477

480 CharUnits offsetFromNearestVBase,

481 bool baseIsNonVirtualPrimaryBase,

485

486

487 if (!baseIsNonVirtualPrimaryBase) {

488

489 VPtr vptr = {base, nearestVBase, offsetFromNearestVBase, vtableClass};

490 vptrs.push_back(vptr);

491 }

492

494

495 for (const auto &nextBase : rd->bases()) {

496 const auto *baseDecl =

498 ->getDefinitionOrSelf();

499

500

501 if (!baseDecl->isDynamicClass())

502 continue;

503

505 CharUnits baseOffsetFromNearestVBase;

506 bool baseDeclIsNonVirtualPrimaryBase;

508

509 if (nextBase.isVirtual()) {

510

511 if (!vbases.insert(baseDecl).second)

512 continue;

513

516

517 nextBaseDecl = baseDecl;

520 baseDeclIsNonVirtualPrimaryBase = false;

521 } else {

523

524 nextBaseDecl = nearestVBase;

526 baseOffsetFromNearestVBase =

528 baseDeclIsNonVirtualPrimaryBase = layout.getPrimaryBase() == baseDecl;

529 }

530

532 baseOffsetFromNearestVBase,

533 baseDeclIsNonVirtualPrimaryBase, vtableClass, vbases,

534 vptrs);

535 }

536}

537

539 assert(curFuncDecl && "loading 'this' without a func declaration?");

541

542

544

545

546

549 }

550

552}

553

555 Expr *init) {

561 } else {

564 }

565 break;

568 break;

576 break;

577 }

578 }

579

580

581

583 (void)dtorKind;

585}

586

588 const Expr *e, Address base, mlir::Value memberPtr,

591

592 cir::GetRuntimeMemberOp op = builder.createGetIndirectMember(

594

597 CharUnits memberAlign = cgm.getNaturalTypeAlignment(memberType, baseInfo);

598 memberAlign = cgm.getDynamicOffsetAlignment(

600 memberAlign);

601

603 memberAlign);

604}

605

610

611

613 return std::min(actualBaseAlign, expectedTargetAlign);

614

618

619

620

621

622

623

624

625

626

627

628

629

630

631

632

633

634

635

636

637 if (actualBaseAlign >= expectedBaseAlign)

638 return expectedTargetAlign;

639

640

641

642

643 return std::min(actualBaseAlign, expectedTargetAlign);

644}

645

646

647

652

653

654

659

661 expectedVBaseAlign);

662}

663

664

665

666

667

668

669

670

671

675 bool zeroInitialize) {

679 newPointerIsChecked, zeroInitialize);

680}

681

682

683

684

685

686

687

688

689

690

693 const CXXConstructExpr *e, bool newPointerIsChecked, bool zeroInitialize) {

694

695

696

697

698

699

700 auto arrayTy = mlir::castcir::ArrayType(arrayBase.getElementType());

701 mlir::Type elementType = arrayTy.getElementType();

702

703

704 while (auto maybeArrayTy = mlir::dyn_castcir::ArrayType(elementType))

705 elementType = maybeArrayTy.getElementType();

706 cir::PointerType ptrToElmType = builder.getPointerTo(elementType);

707

708

709 if (auto constantCount = numElements.getDefiningOpcir::ConstantOp()) {

710 if (auto constIntAttr = constantCount.getValueAttrcir::IntAttr()) {

711

712 if (constIntAttr.getUInt() == 0)

713 return;

714

715 arrayTy = cir::ArrayType::get(elementType, constIntAttr.getUInt());

716

717 }

718

719 if (constantCount.use_empty())

720 constantCount.erase();

721 } else {

722

723 cgm.errorNYI(e->getSourceRange(), "dynamic-length array expression");

724 }

725

726

727

728

729

730

731

732

733

734

738

739

740 if (zeroInitialize)

742

743

744

745

746

747

748

749

750 {

752

753

754

758 }

759

760

761 mlir::Value arrayOp =

762 builder.createPtrBitcast(arrayBase.getPointer(), arrayTy);

763 cir::ArrayCtor::create(

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

766 mlir::BlockArgument arg =

767 b.getInsertionBlock()->addArgument(ptrToElmType, loc);

768 Address curAddr = Address(arg, elementType, eltAlignment);

775 false,

776 false, currAVS, e);

777 cir::YieldOp::create(builder, loc);

778 });

779 }

780}

781

786

787 FunctionArgList::const_iterator i = args.begin(), e = args.end();

788 assert(i != e && "no parameters to constructor");

789

790

793 ++i;

794

795

796

797 if (cgm.getCXXABI().needsVTTParameter(curGD)) {

798 cgm.errorNYI(loc, "emitDelegateCXXConstructorCall: VTT parameter");

799 return;

800 }

801

802

803 for (; i != e; ++i) {

804 const VarDecl *param = *i;

805

807 }

808

810

812 true, thisAddr, delegateArgs, loc);

813}

814

817 assert(assignOp->isCopyAssignmentOperator() ||

818 assignOp->isMoveAssignmentOperator());

819 const Stmt *rootS = assignOp->getBody();

821 "Body of an implicit assignment operator should be compound stmt.");

823

825

828

829

830

831

832

833

835 for (Stmt *s : rootCS->body())

836 if (emitStmt(s, true).failed())

837 cgm.errorNYI(s->getSourceRange(),

838 std::string("emitImplicitAssignmentOperatorBody: ") +

839 s->getStmtClassName());

840}

841

844

846 cgm.getTypes().arrangeCXXMethodDeclaration(callOperator);

847 cir::FuncOp calleePtr = cgm.getAddrOfFunction(

848 GlobalDecl(callOperator), cgm.getTypes().getFunctionType(calleeFnInfo));

849

850

855

856

857

858

859

860

863 RValue rv = emitCall(calleeFnInfo, callee, returnSlot, callArgs);

864

865

866 if (!resultType->isVoidType() && returnSlot.isNull()) {

867 if (getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType())

869 "emitForwardingCallToLambda: ObjCAutoRefCount");

871 } else {

873 "emitForwardingCallToLambda: return slot is not null");

874 }

875}

876

879

880

882

888

889

892

894

895

901 void *InsertPos = nullptr;

902 FunctionDecl *correspondingCallOpSpecialization =

904 assert(correspondingCallOpSpecialization);

906 }

908}

909

912

913

914

915

916 cgm.errorNYI(md->getSourceRange(), "emitLambdaStaticInvokeBody: variadic");

917 }

918

920}

921

924 const auto *record = type->castAsCXXRecordDecl();

926

927

928

931 false, addr, type);

932}

933

934namespace {

935mlir::Value loadThisForDtorDelete(CIRGenFunction &cgf,

940}

941

942

943struct CallDtorDelete final : EHScopeStack::Cleanup {

944 CallDtorDelete() {}

945

946 void emit(CIRGenFunction &cgf, Flags flags) override {

948 const CXXRecordDecl *classDecl = dtor->getParent();

950 loadThisForDtorDelete(cgf, dtor),

952 }

953};

954

956 const FieldDecl *field;

958

959public:

961 : field(field), destroyer(destroyer) {}

962

963 void emit(CIRGenFunction &cgf, Flags flags) override {

964

968 LValue thisLV = cgf.makeAddrLValue(thisValue, recordTy);

970 assert(lv.isSimple());

971

973 cgf.emitDestroy(lv.getAddress(), field->getType(), destroyer);

974 }

975};

976}

977

978

979

980

981

982

983

987 "Should not emit dtor epilogue for non-exported trivial dtor!");

988

989

990

993 "operator delete missing - EnterDtorCleanups");

995 cgm.errorNYI(dd->getSourceRange(), "deleting destructor with vtt");

996 } else {

999 "deleting destructor with destroying operator delete");

1000 } else {

1002 }

1003 }

1004 return;

1005 }

1006

1008

1009

1010 if (classDecl->isUnion())

1011 return;

1012

1013

1016

1017

1018

1020 auto *baseClassDecl = base.getType()->castAsCXXRecordDecl();

1021

1022 if (baseClassDecl->hasTrivialDestructor()) {

1023

1024

1025

1027 } else {

1029 true);

1030 }

1031 }

1032

1033 return;

1034 }

1035

1038

1039

1041

1042 if (base.isVirtual())

1043 continue;

1044

1045 CXXRecordDecl *baseClassDecl = base.getType()->getAsCXXRecordDecl();

1046

1049 else

1051 false);

1052 }

1053

1055

1056

1060 if (!dtorKind)

1061 continue;

1062

1063

1064 const RecordType *rt = type->getAsUnionType();

1065 if (rt && rt->getDecl()->isAnonymousStructOrUnion())

1066 continue;

1067

1070 ehStack.pushCleanup(cleanupKind, field,

1072 }

1073}

1074

1078

1080

1087

1089

1093 "emitDelegatingCXXConstructorCall: exception");

1094 return;

1095 }

1096}

1097

1100 bool forVirtualBase, bool delegating,

1102 cgm.getCXXABI().emitDestructorCall(*this, dd, type, forVirtualBase,

1103 delegating, thisAddr, thisTy);

1104}

1105

1107 bool delegating) {

1108 if (cgm.getCXXABI().needsVTTParameter(gd))

1109 return nullptr;

1110

1113

1114 uint64_t subVTTIndex;

1115

1116 if (delegating) {

1117

1119 } else if (rd == base) {

1120

1121

1122 assert(cgm.getCXXABI().needsVTTParameter(curGD) &&

1123 "doing no-op VTT offset in base dtor/ctor?");

1124 assert(!forVirtualBase && "Can't have same class as virtual base!");

1125 subVTTIndex = 0;

1126 } else {

1130

1131 subVTTIndex =

1132 cgm.getVTables().getSubVTTIndex(rd, BaseSubobject(base, baseOffset));

1133 assert(subVTTIndex != 0 && "Sub-VTT index must be greater than zero!");

1134 }

1135

1137 if (cgm.getCXXABI().needsVTTParameter(curGD)) {

1138

1140 return builder.createVTTAddrPoint(loc, vtt.getType(), vtt, subVTTIndex);

1141 } else {

1142

1143 cir::GlobalOp vtt = cgm.getVTables().getAddrOfVTT(rd);

1144 return builder.createVTTAddrPoint(

1145 loc, builder.getPointerTo(cgm.voidPtrTy),

1146 mlir::FlatSymbolRefAttr::get(vtt.getSymNameAttr()), subVTTIndex);

1147 }

1148}

1149

1152 llvm::iterator_rangeCastExpr::path\_const\_iterator path,

1153 bool nullCheckValue) {

1154 assert(!path.empty() && "Base path should not be empty!");

1155

1157 mlir::Type derivedValueTy = convertType(derivedTy);

1159 cgm.computeNonVirtualBaseClassOffset(derived, path);

1160

1161

1162

1163

1164 return builder.createDerivedClassAddr(loc, baseAddr, derivedValueTy,

1166 !nullCheckValue);

1167}

1168

1171 llvm::iterator_rangeCastExpr::path\_const\_iterator path,

1173 assert(!path.empty() && "Base path should not be empty!");

1174

1177

1178 if ((*path.begin())->isVirtual()) {

1179 vBase = (*start)->getType()->castAsCXXRecordDecl();

1180 ++start;

1181 }

1182

1183

1184

1185

1186 CharUnits nonVirtualOffset = cgm.computeNonVirtualBaseClassOffset(

1187 vBase ? vBase : derived, {start, path.end()});

1188

1189

1190

1191

1192 if (vBase && derived->hasAttr()) {

1195 nonVirtualOffset += vBaseOffset;

1196 vBase = nullptr;

1197 }

1198

1199

1200 mlir::Type baseValueTy = convertType((path.end()[-1])->getType());

1202

1203

1204

1205 if (nonVirtualOffset.isZero() && !vBase) {

1207 return builder.createBaseClassAddr(getLoc(loc), value, baseValueTy, 0,

1208 true);

1209 }

1210

1212

1213

1214 mlir::Value virtualOffset = nullptr;

1215 if (vBase) {

1216 virtualOffset = cgm.getCXXABI().getVirtualBaseClassOffset(

1217 getLoc(loc), *this, value, derived, vBase);

1218 }

1219

1220

1222 getLoc(loc), *this, value, nonVirtualOffset, virtualOffset, derived,

1223 vBase, baseValueTy, not nullCheckValue);

1224

1225

1227

1228 return value;

1229}

1230

1231

1234 if (cgm.getCodeGenOpts().WholeProgramVTables)

1235 return false;

1236

1237 if (cgm.getCodeGenOpts().VirtualFunctionElimination)

1238 return true;

1239

1241

1242 return false;

1243}

1244

1247 auto vtablePtr = cir::VTableGetVPtrOp::create(

1248 builder, loc, builder.getPtrToVPtrType(), thisAddr.getPointer());

1250

1251 auto vtable = builder.createLoad(loc, vtablePtrAddr);

1253

1254 if (cgm.getCodeGenOpts().OptimizationLevel > 0 &&

1255 cgm.getCodeGenOpts().StrictVTablePointers) {

1257 }

1258

1259 return vtable;

1260}

1261

1264 bool forVirtualBase,

1265 bool delegating,

1271 mlir::Value thisPtr = thisAddr.getPointer();

1272

1274

1276

1277

1278

1279

1281

1283

1285

1287 0);

1288

1292}

1293

1297

1299

1300

1301

1302

1303

1305

1307

1308 bool passPrototypeArgs = true;

1309

1310

1313 "emitCXXConstructorCall: inherited constructor");

1314 return;

1315 }

1316

1317

1319 cgm.getCXXABI().addImplicitConstructorArgs(*this, d, type, forVirtualBase,

1320 delegating, args);

1321

1322

1325 args, d, type, extraArgs.prefix, extraArgs.suffix, passPrototypeArgs);

1327 cir::CIRCallOpInterface c;

1329

1330 if (cgm.getCodeGenOpts().OptimizationLevel != 0 && !crd->isDynamicClass() &&

1331 type != Ctor_Base && cgm.getCodeGenOpts().StrictVTablePointers)

1333}

static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)

Helper to write bytecode and bail out if 32-bit offsets become invalid.

static bool baseInitializerUsesThis(ASTContext &c, const Expr *init)

Definition CIRGenClass.cpp:188

static Address applyNonVirtualAndVirtualOffset(mlir::Location loc, CIRGenFunction &cgf, Address addr, CharUnits nonVirtualOffset, mlir::Value virtualOffset, const CXXRecordDecl *derivedClass, const CXXRecordDecl *nearestVBase, mlir::Type baseValueTy={}, bool assumeNotNull=true)

Definition CIRGenClass.cpp:350

static void emitMemberInitializer(CIRGenFunction &cgf, const CXXRecordDecl *classDecl, CXXCtorInitializer *memberInit, const CXXConstructorDecl *constructor, FunctionArgList &args)

Definition CIRGenClass.cpp:75

static bool isInitializerOfDynamicClass(const CXXCtorInitializer *baseInit)

Definition CIRGenClass.cpp:138

static void emitLValueForAnyFieldInitialization(CIRGenFunction &cgf, CXXCtorInitializer *memberInit, LValue &lhs)

Definition CIRGenClass.cpp:59

Defines the clang::Expr interface and subclasses for C++ expressions.

C Language Family Type Representation.

__device__ __2f16 float __ockl_bool s

__device__ __2f16 float c

mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)

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

const ConstantArrayType * getAsConstantArrayType(QualType T) const

const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const

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

QualType getPointerType(QualType T) const

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

QualType getBaseElementType(const ArrayType *VAT) const

Return the innermost element type of an array type.

CanQualType getCanonicalTagType(const TagDecl *TD) const

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

CharUnits getNonVirtualAlignment() const

getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...

CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const

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

CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const

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

const CXXRecordDecl * getPrimaryBase() const

getPrimaryBase - Get the primary base for this record.

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

const CXXRecordDecl * getBase() const

getBase - Returns the base class declaration.

CharUnits getBaseOffset() const

getBaseOffset - Returns the base class offset.

mlir::Value getPointer() const

mlir::Type getElementType() const

Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const

Return address with different element type, a bitcast pointer, and the same alignment.

clang::CharUnits getAlignment() const

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

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

Address getAddress() const

Address createBaseClassAddr(mlir::Location loc, Address addr, mlir::Type destType, unsigned offset, bool assumeNotNull)

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

virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, FunctionArgList &args) const =0

static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())

A scope within which we are constructing the fields of an object which might use a CXXDefaultInitExpr...

Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.

static bool isConstructorDelegationValid(const clang::CXXConstructorDecl *ctor)

Checks whether the given constructor is a valid subject for the complete-to-base constructor delegati...

Definition CIRGenClass.cpp:30

void emitLambdaDelegatingInvokeBody(const CXXMethodDecl *md)

Definition CIRGenClass.cpp:877

void emitCallArgs(CallArgList &args, PrototypeWrapper prototype, llvm::iterator_range< clang::CallExpr::const_arg_iterator > argRange, AbstractCallee callee=AbstractCallee(), unsigned paramsToSkip=0)

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

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

Return the cir::TypeEvaluationKind of QualType type.

clang::GlobalDecl curGD

The GlobalDecl for the current function being compiled or the global variable currently being initial...

Address emitCXXMemberDataPointerAddress(const Expr *e, Address base, mlir::Value memberPtr, const MemberPointerType *memberPtrType, LValueBaseInfo *baseInfo)

Definition CIRGenClass.cpp:587

const clang::LangOptions & getLangOpts() const

mlir::Value cxxStructorImplicitParamValue

void emitForwardingCallToLambda(const CXXMethodDecl *lambdaCallOperator, CallArgList &callArgs)

Definition CIRGenClass.cpp:842

mlir::Value loadCXXThis()

Load the value for 'this'.

LValue makeNaturalAlignPointeeAddrLValue(mlir::Value v, clang::QualType t)

Given a value of type T* that may not be to a complete object, construct an l-vlaue withi the natural...

void emitDeleteCall(const FunctionDecl *deleteFD, mlir::Value ptr, QualType deleteTy)

clang::CharUnits cxxThisAlignment

const clang::Decl * curFuncDecl

Address loadCXXThisAddress()

Definition CIRGenClass.cpp:538

Address getAddrOfLocalVar(const clang::VarDecl *vd)

Return the address of a local variable.

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

Emit an aggregate copy.

LValue makeNaturalAlignAddrLValue(mlir::Value val, QualType ty)

mlir::Value getVTTParameter(GlobalDecl gd, bool forVirtualBase, bool delegating)

Return the VTT parameter that should be passed to a base constructor/destructor with virtual bases.

Definition CIRGenClass.cpp:1106

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

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

void initializeVTablePointers(mlir::Location loc, const clang::CXXRecordDecl *rd)

Definition CIRGenClass.cpp:451

void initializeVTablePointer(mlir::Location loc, const VPtr &vptr)

Definition CIRGenClass.cpp:402

Address getAddressOfBaseClass(Address value, const CXXRecordDecl *derived, llvm::iterator_range< CastExpr::path_const_iterator > path, bool nullCheckValue, SourceLocation loc)

Definition CIRGenClass.cpp:1169

void emitDelegateCXXConstructorCall(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, const FunctionArgList &args, clang::SourceLocation loc)

Definition CIRGenClass.cpp:782

void emitBaseInitializer(mlir::Location loc, const CXXRecordDecl *classDecl, CXXCtorInitializer *baseInit)

Definition CIRGenClass.cpp:218

void emitExprAsInit(const clang::Expr *init, const clang::ValueDecl *d, LValue lvalue, bool capturedByInit=false)

Emit an expression as an initializer for an object (variable, field, etc.) at the given location.

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

Computes the length of an array in elements, as well as the base element type and a properly-typed fi...

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

VPtrsVector getVTablePointers(const clang::CXXRecordDecl *vtableClass)

Definition CIRGenClass.cpp:467

CleanupKind getCleanupKind(QualType::DestructionKind kind)

AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *fd)

mlir::Operation * curFn

The current function or global initializer that is generated code for.

Address getAddressOfDerivedClass(mlir::Location loc, Address baseAddr, const CXXRecordDecl *derived, llvm::iterator_range< CastExpr::path_const_iterator > path, bool nullCheckValue)

Definition CIRGenClass.cpp:1150

EHScopeStack ehStack

Tracks function scope overall cleanup handling.

void enterDtorCleanups(const CXXDestructorDecl *dtor, CXXDtorType type)

Enter the cleanups necessary to complete the given phase of destruction for a destructor.

Definition CIRGenClass.cpp:984

void emitImplicitAssignmentOperatorBody(FunctionArgList &args)

Definition CIRGenClass.cpp:815

mlir::Type convertTypeForMem(QualType t)

void emitCtorPrologue(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, FunctionArgList &args)

This routine generates necessary code to initialize base classes and non-static data members belongin...

Definition CIRGenClass.cpp:255

mlir::Value loadCXXVTT()

Load the VTT parameter to base constructors/destructors have virtual bases.

static Destroyer destroyCXXObject

void emitCXXConstructorCall(const clang::CXXConstructorDecl *d, clang::CXXCtorType type, bool forVirtualBase, bool delegating, AggValueSlot thisAVS, const clang::CXXConstructExpr *e)

Definition CIRGenClass.cpp:1262

mlir::Value getVTablePtr(mlir::Location loc, Address thisAddr, const clang::CXXRecordDecl *vtableClass)

Return the Value of the vtable pointer member pointed to by thisAddr.

Definition CIRGenClass.cpp:1245

llvm::SmallPtrSet< const clang::CXXRecordDecl *, 4 > VisitedVirtualBasesSetTy

void emitReturnOfRValue(mlir::Location loc, RValue rv, QualType ty)

bool shouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *rd)

Returns whether we should perform a type checked load when loading a virtual function for virtual cal...

Definition CIRGenClass.cpp:1232

RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, mlir::Location loc)

const clang::Decl * curCodeDecl

This is the inner-most code context, which includes blocks.

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

void emitInitializerForField(clang::FieldDecl *field, LValue lhs, clang::Expr *init)

Definition CIRGenClass.cpp:554

LValue emitLValueForField(LValue base, const clang::FieldDecl *field)

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

Emit the computation of the specified expression of scalar type.

bool needsEHCleanup(QualType::DestructionKind kind)

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

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.

Definition CIRGenClass.cpp:199

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.

void emitDestroy(Address addr, QualType type, Destroyer *destroyer)

Immediately perform the destruction of the given object.

Destroyer * getDestroyer(clang::QualType::DestructionKind kind)

void Destroyer(CIRGenFunction &cgf, Address addr, QualType ty)

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

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

void emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)

Definition CIRGenClass.cpp:1098

llvm::SmallVector< VPtr, 4 > VPtrsVector

void emitLambdaStaticInvokeBody(const CXXMethodDecl *md)

Definition CIRGenClass.cpp:910

void emitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, const clang::ArrayType *arrayType, Address arrayBegin, const CXXConstructExpr *e, bool newPointerIsChecked, bool zeroInitialize=false)

Emit a loop to call a particular constructor for each of several members of an array.

Definition CIRGenClass.cpp:672

void emitDelegateCallArg(CallArgList &args, const clang::VarDecl *param, clang::SourceLocation loc)

We are performing a delegate call; that is, the current function is delegating to another one.

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

mlir::LogicalResult emitStmt(const clang::Stmt *s, bool useCurrentScope, llvm::ArrayRef< const Attr * > attrs={})

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 emitDelegatingCXXConstructorCall(const CXXConstructorDecl *ctor, const FunctionArgList &args)

Definition CIRGenClass.cpp:1075

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

DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)

Helpers to emit "not yet implemented" error diagnostics.

clang::ASTContext & getASTContext() const

CharUnits getDynamicOffsetAlignment(CharUnits actualBaseAlign, const CXXRecordDecl *baseDecl, CharUnits expectedTargetAlign)

TODO: Add TBAAAccessInfo.

Definition CIRGenClass.cpp:607

CharUnits getVBaseAlignment(CharUnits derivedAlign, const CXXRecordDecl *derived, const CXXRecordDecl *vbase)

Returns the assumed alignment of a virtual base of a class.

Definition CIRGenClass.cpp:649

CIRGenCXXABI & getCXXABI() const

void add(RValue rvalue, clang::QualType type)

Information for lazily generating a cleanup.

Type for representing both the decl and type of parameters to a function.

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

static RValue get(mlir::Value v)

Contains the address where the return value of a function can be stored, and whether the address is v...

Represents a base class of a C++ class.

Represents a call to a C++ constructor.

CXXConstructorDecl * getConstructor() const

Get the constructor that this expression will (ultimately) call.

Represents a C++ constructor within a class.

init_iterator init_begin()

Retrieve an iterator to the first initializer.

bool isDelegatingConstructor() const

Determine whether this constructor is a delegating constructor.

bool isCopyOrMoveConstructor(unsigned &TypeQuals) const

Determine whether this is a copy or move constructor.

InheritedConstructor getInheritedConstructor() const

Get the constructor that this inheriting constructor is based on.

Represents a C++ base or member initializer.

Expr * getInit() const

Get the initializer.

SourceLocation getSourceLocation() const

Determine the source location of the initializer.

bool isAnyMemberInitializer() const

bool isBaseInitializer() const

Determine whether this initializer is initializing a base class.

bool isIndirectMemberInitializer() const

const Type * getBaseClass() const

If this is a base class initializer, returns the type of the base class.

FieldDecl * getAnyMember() const

IndirectFieldDecl * getIndirectMember() const

bool isBaseVirtual() const

Returns whether the base is virtual or not.

Represents a C++ destructor within a class.

const FunctionDecl * getOperatorDelete() const

Expr * getOperatorDeleteThisArg() const

Represents a static or instance method of a struct/union/class.

const CXXRecordDecl * getParent() const

Return the parent of this method declaration, which is the class in which this method is defined.

QualType getThisType() const

Return the type of the this pointer.

QualType getFunctionObjectParameterType() const

Represents a C++ struct/union/class.

bool isGenericLambda() const

Determine whether this class describes a generic lambda function object (i.e.

bool hasTrivialDestructor() const

Determine whether this class has a trivial destructor (C++ [class.dtor]p3)

base_class_range vbases()

bool isAbstract() const

Determine whether this class has a pure virtual function.

bool isDynamicClass() const

CXXMethodDecl * getLambdaCallOperator() const

Retrieve the lambda call operator of the closure type if this is a closure type.

unsigned getNumVBases() const

Retrieves the number of virtual base classes of this class.

const CXXBaseSpecifier *const * path_const_iterator

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

CharUnits alignmentAtOffset(CharUnits offset) const

Given that this is a non-zero alignment value, what is the alignment at the given offset?

bool isZero() const

isZero - Test whether the quantity equals zero.

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

Zero - Construct a CharUnits quantity of zero.

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

SourceLocation getBeginLoc() const LLVM_READONLY

This represents one expression.

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.

Represents a function declaration or definition.

bool isFunctionTemplateSpecialization() const

Determine whether this function is a function template specialization.

FunctionTemplateDecl * getDescribedFunctionTemplate() const

Retrieves the function template that is described by this function declaration.

bool isDestroyingOperatorDelete() const

Determine whether this is a destroying operator delete.

ArrayRef< ParmVarDecl * > parameters() const

bool isTrivial() const

Whether this function is "trivial" in some specialized C++ senses.

bool isVariadic() const

Whether this function is variadic.

const TemplateArgumentList * getTemplateSpecializationArgs() const

Retrieve the template arguments used to produce this function template specialization from the primar...

bool isDefaulted() const

Whether this function is defaulted.

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

Represents a prototype with parameter type info, e.g.

bool isVariadic() const

Whether this function prototype is variadic.

Declaration of a template function.

FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)

Return the specialization with the provided arguments if it exists, otherwise return the insertion po...

QualType getReturnType() const

GlobalDecl - represents a global declaration.

CXXCtorType getCtorType() const

const Decl * getDecl() const

Represents a field injected from an anonymous union/struct into the parent scope.

ArrayRef< NamedDecl * > chain() const

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

CXXRecordDecl * getMostRecentCXXRecordDecl() const

Note: this can trigger extra deserialization when external AST sources are used.

QualType getPointeeType() const

StringRef getName() const

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

A (possibly-)qualified type.

DestructionKind isDestructedType() const

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

The collection of all-type qualifiers we support.

field_range fields() const

Encodes a location in the source.

Stmt - This represents one statement.

SourceRange getSourceRange() const LLVM_READONLY

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

bool isCompleteDefinition() const

Return true if this decl has its body fully specified.

A template argument list.

ArrayRef< TemplateArgument > asArray() const

Produce this as an array ref.

SourceLocation getBeginLoc() const LLVM_READONLY

The base class of the type hierarchy.

CXXRecordDecl * castAsCXXRecordDecl() const

const T * castAs() const

Member-template castAs.

bool isRecordType() const

Represents a variable declaration or definition.

@ Type

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

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const AstTypeMatcher< ArrayType > arrayType

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

CanQual< Type > CanQualType

Represents a canonical, potentially-qualified type.

CXXCtorType

C++ constructor types.

@ Ctor_Base

Base object ctor.

@ Ctor_Complete

Complete object ctor.

bool isa(CodeGen::Address addr)

CXXDtorType

C++ destructor types.

@ Dtor_Base

Base object dtor.

@ Dtor_Complete

Complete object dtor.

@ Dtor_Deleting

Deleting dtor.

U cast(CodeGen::Address addr)

static bool addressSpace()

static bool useEHCleanupForArray()

static bool aggValueSlotGC()

static bool isMemcpyEquivalentSpecialMember()

static bool hiddenVisibility()

static bool runCleanupsScope()

static bool opCallArgEvaluationOrder()

static bool createInvariantGroup()

static bool isTrivialCtorOrDtor()

static bool assignMemcpyizer()

static bool ctorMemcpyizer()

static bool requiresCleanups()

static bool generateDebugInfo()

static bool incrementProfileCounter()

Similar to AddedStructorArgs, but only notes the number of additional arguments.

const clang::CXXRecordDecl * vtableClass

clang::CharUnits offsetFromNearestVBase

const clang::CXXRecordDecl * nearestVBase

clang::BaseSubobject base

cir::PointerType uInt8PtrTy