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