clang: lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
22
27#include "llvm/Support/ErrorHandling.h"
28
29using namespace clang;
31
32namespace {
33
34class CIRGenItaniumCXXABI : public CIRGenCXXABI {
35protected:
36
37 llvm::DenseMap<const CXXRecordDecl *, cir::GlobalOp> vtables;
38
39public:
40 CIRGenItaniumCXXABI(CIRGenModule &cgm) : CIRGenCXXABI(cgm) {
43 }
44
45 AddedStructorArgs getImplicitConstructorArgs(CIRGenFunction &cgf,
46 const CXXConstructorDecl *d,
48 bool forVirtualBase,
49 bool delegating) override;
50
51 bool needsVTTParameter(clang::GlobalDecl gd) override;
52
53 AddedStructorArgCounts
54 buildStructorSignature(GlobalDecl gd,
55 llvm::SmallVectorImpl &argTys) override;
56
57 void emitInstanceFunctionProlog(SourceLocation loc,
58 CIRGenFunction &cgf) override;
59
60 void addImplicitStructorParams(CIRGenFunction &cgf, QualType &resTy,
61 FunctionArgList ¶ms) override;
63 const CXXDestructorDecl *dd,
65 bool forVirtualBase,
66 bool delegating) override;
67 void emitCXXConstructors(const clang::CXXConstructorDecl *d) override;
68 void emitCXXDestructors(const clang::CXXDestructorDecl *d) override;
69 void emitCXXStructor(clang::GlobalDecl gd) override;
70
71 void emitDestructorCall(CIRGenFunction &cgf, const CXXDestructorDecl *dd,
73 bool delegating, Address thisAddr,
74 QualType thisTy) override;
75 void registerGlobalDtor(const VarDecl *vd, cir::FuncOp dtor,
76 mlir::Value addr) override;
77 void emitVirtualObjectDelete(CIRGenFunction &cgf, const CXXDeleteExpr *de,
78 Address ptr, QualType elementType,
79 const CXXDestructorDecl *dtor) override;
80
81 void emitRethrow(CIRGenFunction &cgf, bool isNoReturn) override;
82 void emitThrow(CIRGenFunction &cgf, const CXXThrowExpr *e) override;
83
84 void emitBeginCatch(CIRGenFunction &cgf,
85 const CXXCatchStmt *catchStmt) override;
86
87 bool useThunkForDtorVariant(const CXXDestructorDecl *dtor,
89
90
91
92 return false;
93 }
94
95 bool isVirtualOffsetNeededForVTableField(CIRGenFunction &cgf,
96 CIRGenFunction::VPtr vptr) override;
97
98 cir::GlobalOp getAddrOfVTable(const CXXRecordDecl *rd,
99 CharUnits vptrOffset) override;
100 CIRGenCallee getVirtualFunctionPointer(CIRGenFunction &cgf,
101 clang::GlobalDecl gd, Address thisAddr,
102 mlir::Type ty,
103 SourceLocation loc) override;
104 mlir::Value emitVirtualDestructorCall(CIRGenFunction &cgf,
105 const CXXDestructorDecl *dtor,
107 DeleteOrMemberCallExpr e) override;
108 mlir::Value getVTableAddressPoint(BaseSubobject base,
109 const CXXRecordDecl *vtableClass) override;
110 mlir::Value getVTableAddressPointInStructorWithVTT(
111 CIRGenFunction &cgf, const CXXRecordDecl *vtableClass, BaseSubobject base,
112 const CXXRecordDecl *nearestVBase);
113
114 mlir::Value getVTableAddressPointInStructor(
115 CIRGenFunction &cgf, const clang::CXXRecordDecl *vtableClass,
116 clang::BaseSubobject base,
117 const clang::CXXRecordDecl *nearestVBase) override;
118 void emitVTableDefinitions(CIRGenVTables &cgvt,
119 const CXXRecordDecl *rd) override;
120 void emitVirtualInheritanceTables(const CXXRecordDecl *rd) override;
121
122 mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc,
123 QualType ty) override;
124 CatchTypeInfo
125 getAddrOfCXXCatchHandlerType(mlir::Location loc, QualType ty,
126 QualType catchHandlerType) override {
127 auto rtti = dyn_castcir::GlobalViewAttr(getAddrOfRTTIDescriptor(loc, ty));
128 assert(rtti && "expected GlobalViewAttr");
129 return CatchTypeInfo{rtti, 0};
130 }
131
132 bool doStructorsInitializeVPtrs(const CXXRecordDecl *vtableClass) override {
133 return true;
134 }
135
136 size_t getSrcArgforCopyCtor(const CXXConstructorDecl *,
137 FunctionArgList &args) const override {
138 assert(!args.empty() && "expected the arglist to not be empty!");
139 return args.size() - 1;
140 }
141
142 void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc) override;
143
144 mlir::Value
145 getVirtualBaseClassOffset(mlir::Location loc, CIRGenFunction &cgf,
146 Address thisAddr, const CXXRecordDecl *classDecl,
147 const CXXRecordDecl *baseClassDecl) override;
148
149
150
151
152
153
154 mlir::Value emitDynamicCast(CIRGenFunction &cgf, mlir::Location loc,
155 QualType srcRecordTy, QualType destRecordTy,
156 cir::PointerType destCIRTy, bool isRefCast,
157 Address src) override;
158
159 Address initializeArrayCookie(CIRGenFunction &cgf, Address newPtr,
160 mlir::Value numElements, const CXXNewExpr *e,
161 QualType elementType) override;
162
163protected:
164 CharUnits getArrayCookieSizeImpl(QualType elementType) override;
165
166
167
168
169 virtual bool shouldRTTIBeUnique() const { return true; }
170
171public:
172
173 enum RTTIUniquenessKind {
174
175
176 RUK_Unique,
177
178
179
180 RUK_NonUniqueHidden,
181
182
183
184
185 RUK_NonUniqueVisible
186 };
187
188
189
190 RTTIUniquenessKind
191 classifyRTTIUniqueness(QualType canTy, cir::GlobalLinkageKind linkage) const;
192};
193
194}
195
196void CIRGenItaniumCXXABI::emitInstanceFunctionProlog(SourceLocation loc,
198
201 "emitInstanceFunctionProlog: Naked");
202 }
203
204
205
206 setCXXABIThisValue(cgf, loadIncomingCXXThis(cgf));
207
208
209 if (getStructorImplicitParamDecl(cgf)) {
213 setStructorImplicitParamValue(cgf, val);
214 }
215
216
217
218
219
220
221
222
223
224 if (hasThisReturn(cgf.curGD)) {
226 "emitInstanceFunctionProlog: hasThisReturn");
227 }
228}
229
230CIRGenCXXABI::AddedStructorArgCounts
231CIRGenItaniumCXXABI::buildStructorSignature(
232 GlobalDecl gd, llvm::SmallVectorImpl &argTys) {
233 clang::ASTContext &astContext = cgm.getASTContext();
234
235
236
237
238
243 argTys.insert(argTys.begin() + 1,
246 return AddedStructorArgCounts::withPrefix(1);
247 }
248
249 return AddedStructorArgCounts{};
250}
251
252
253namespace {
254enum class StructorCIRGen { Emit, RAUW, Alias, COMDAT };
255}
256
260 return StructorCIRGen::Emit;
261
262
263
265 return StructorCIRGen::Emit;
266
268 if (const auto *dd = dyn_cast(md)) {
270 } else {
273 }
274
276
278 return StructorCIRGen::RAUW;
279
280
282 return StructorCIRGen::RAUW;
283
285
288 return StructorCIRGen::COMDAT;
289 return StructorCIRGen::Emit;
290 }
291
292 return StructorCIRGen::Alias;
293}
294
299
300
301 StringRef mangledName = cgm.getMangledName(aliasDecl);
302 auto globalValue = dyn_cast_or_nullcir::CIRGlobalValueInterface(
304 if (globalValue && !globalValue.isDeclaration())
305 return;
306
307 auto entry = cast_or_nullcir::FuncOp(cgm.getGlobalValue(mangledName));
308
309
311
312
313 cgm.emitAliasForGlobal(mangledName, entry, aliasDecl, aliasee, linkage);
314}
315
316void CIRGenItaniumCXXABI::emitCXXStructor(GlobalDecl gd) {
319 const auto *cd = dyn_cast(md);
320
323 GlobalDecl baseDecl =
325 ;
326
327 if (cirGenType == StructorCIRGen::Alias ||
328 cirGenType == StructorCIRGen::COMDAT) {
330 return;
331 }
332
333 if (cirGenType == StructorCIRGen::RAUW) {
335 mlir::Operation *aliasee = cgm.getAddrOfGlobal(baseDecl);
337 return;
338 }
339 }
340
342
344}
345
346void CIRGenItaniumCXXABI::addImplicitStructorParams(CIRGenFunction &cgf,
347 QualType &resTy,
348 FunctionArgList ¶ms) {
351
352
353 if (needsVTTParameter(cgf.curGD)) {
355
356
360 astContext, nullptr, md->getLocation(),
361 &astContext.Idents.get("vtt"), t, ImplicitParamKind::CXXVTT);
362 params.insert(params.begin() + 1, vttDecl);
363 getStructorImplicitParamDecl(cgf) = vttDecl;
364 }
365}
366
367void CIRGenItaniumCXXABI::emitCXXConstructors(const CXXConstructorDecl *d) {
368
370
371
372
374
375
376
378
380 }
381}
382
383void CIRGenItaniumCXXABI::emitCXXDestructors(const CXXDestructorDecl *d) {
384
385
387
388
389
391
392
393
394
397}
398
399CIRGenCXXABI::AddedStructorArgs CIRGenItaniumCXXABI::getImplicitConstructorArgs(
400 CIRGenFunction &cgf, const CXXConstructorDecl *d, CXXCtorType type,
401 bool forVirtualBase, bool delegating) {
402 if (!needsVTTParameter(GlobalDecl(d, type)))
403 return AddedStructorArgs{};
404
405
406
407
408 mlir::Value vtt =
410 QualType vttTy =
413 return AddedStructorArgs::withPrefix({{vtt, vttTy}});
414}
415
416
417
418
419bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
421
422
423 if (!md->getParent()->getNumVBases())
424 return false;
425
426
428 return true;
429
430
432 return true;
433
434 return false;
435}
436
437void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt,
438 const CXXRecordDecl *rd) {
439 cir::GlobalOp vtable = getAddrOfVTable(rd, CharUnits());
440 if (vtable.hasInitializer())
441 return;
442
444 const VTableLayout &vtLayout = vtContext.getVTableLayout(rd);
446 mlir::Attribute rtti =
449
450
451
452
455
456
457 vtable.setLinkage(linkage);
458
460 vtable.setComdat(true);
461
462
464
465
466
467
475 "emitVTableDefinitions: __fundamental_type_info");
476 }
477
478 [[maybe_unused]] auto vtableAsGlobalValue =
479 dyn_castcir::CIRGlobalValueInterface(*vtable);
480 assert(vtableAsGlobalValue && "VTable must support CIRGlobalValueInterface");
481
482
483
484
485
486
490 "emitVTableDefinitions: WholeProgramVTables");
491 }
492
496 }
497}
498
499mlir::Value CIRGenItaniumCXXABI::emitVirtualDestructorCall(
500 CIRGenFunction &cgf, const CXXDestructorDecl *dtor, CXXDtorType dtorType,
501 Address thisAddr, DeleteOrMemberCallExpr expr) {
502 auto *callExpr = dyn_cast<const CXXMemberCallExpr *>(expr);
503 auto *delExpr = dyn_cast<const CXXDeleteExpr *>(expr);
504 assert((callExpr != nullptr) ^ (delExpr != nullptr));
507
508 GlobalDecl globalDecl(dtor, dtorType);
509 const CIRGenFunctionInfo *fnInfo =
513
514 QualType thisTy =
515 callExpr ? callExpr->getObjectType() : delExpr->getDestroyedType();
516
518 thisTy, nullptr, QualType(), nullptr);
519 return nullptr;
520}
521
522void CIRGenItaniumCXXABI::emitVirtualInheritanceTables(
523 const CXXRecordDecl *rd) {
524 CIRGenVTables &vtables = cgm.getVTables();
525 cir::GlobalOp vtt = vtables.getAddrOfVTT(rd);
527}
528
529namespace {
530class CIRGenItaniumRTTIBuilder {
531 CIRGenModule &cgm;
532 const CIRGenItaniumCXXABI &cxxABI;
533
534
535 SmallVector<mlir::Attribute, 16> fields;
536
537
538 cir::GlobalOp getAddrOfTypeName(mlir::Location loc, QualType ty,
539 cir::GlobalLinkageKind linkage);
540
541
542 mlir::Attribute getAddrOfExternalRTTIDescriptor(mlir::Location loc,
543 QualType ty);
544
545
546 void buildVTablePointer(mlir::Location loc, const Type *ty);
547
548
549
550 void buildSIClassTypeInfo(mlir::Location loc, const CXXRecordDecl *rd);
551
552
553
554
555 void buildVMIClassTypeInfo(mlir::Location loc, const CXXRecordDecl *rd);
556
557public:
558 CIRGenItaniumRTTIBuilder(const CIRGenItaniumCXXABI &abi, CIRGenModule &cgm)
559 : cgm(cgm), cxxABI(abi) {}
560
561
562
563 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty);
564
565
566 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty,
567 cir::GlobalLinkageKind linkage,
568 mlir::SymbolTable::Visibility visibility);
569};
570}
571
572
573namespace {
574
575
576enum {
577
578 PTI_Const = 0x1,
579
580
581 PTI_Volatile = 0x2,
582
583
584 PTI_Restrict = 0x4,
585
586
587 PTI_Incomplete = 0x8,
588
589
590
591 PTI_ContainingClassIncomplete = 0x10,
592
593
594
595
596
597 PTI_Noexcept = 0x40,
598};
599
600
601enum {
602
603 VMI_NonDiamondRepeat = 0x1,
604
605
606 VMI_DiamondShaped = 0x2
607};
608
609
610enum {
611
612 BCTI_Virtual = 0x1,
613
614
615 BCTI_Public = 0x2
616};
617
618
619
620
621static bool typeInfoIsInStandardLibrary(const BuiltinType *ty) {
622
623
624
625
626
627
628
629
630
631
632
633
634
635
637 case BuiltinType::WasmExternRef:
638 case BuiltinType::HLSLResource:
639 llvm_unreachable("NYI");
640 case BuiltinType::Void:
641 case BuiltinType::NullPtr:
642 case BuiltinType::Bool:
643 case BuiltinType::WChar_S:
644 case BuiltinType::WChar_U:
645 case BuiltinType::Char_U:
646 case BuiltinType::Char_S:
647 case BuiltinType::UChar:
648 case BuiltinType::SChar:
649 case BuiltinType::Short:
650 case BuiltinType::UShort:
651 case BuiltinType::Int:
652 case BuiltinType::UInt:
653 case BuiltinType::Long:
654 case BuiltinType::ULong:
655 case BuiltinType::LongLong:
656 case BuiltinType::ULongLong:
657 case BuiltinType::Half:
658 case BuiltinType::Float:
659 case BuiltinType::Double:
660 case BuiltinType::LongDouble:
661 case BuiltinType::Float16:
662 case BuiltinType::Float128:
663 case BuiltinType::Ibm128:
664 case BuiltinType::Char8:
665 case BuiltinType::Char16:
666 case BuiltinType::Char32:
667 case BuiltinType::Int128:
668 case BuiltinType::UInt128:
669 return true;
670
671#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
672 case BuiltinType::Id:
673#include "clang/Basic/OpenCLImageTypes.def"
674#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
675#include "clang/Basic/OpenCLExtensionTypes.def"
676 case BuiltinType::OCLSampler:
677 case BuiltinType::OCLEvent:
678 case BuiltinType::OCLClkEvent:
679 case BuiltinType::OCLQueue:
680 case BuiltinType::OCLReserveID:
681#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
682#include "clang/Basic/AArch64ACLETypes.def"
683#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
684#include "clang/Basic/PPCTypes.def"
685#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
686#include "clang/Basic/RISCVVTypes.def"
687#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
688#include "clang/Basic/AMDGPUTypes.def"
689 case BuiltinType::ShortAccum:
690 case BuiltinType::Accum:
691 case BuiltinType::LongAccum:
692 case BuiltinType::UShortAccum:
693 case BuiltinType::UAccum:
694 case BuiltinType::ULongAccum:
695 case BuiltinType::ShortFract:
696 case BuiltinType::Fract:
697 case BuiltinType::LongFract:
698 case BuiltinType::UShortFract:
699 case BuiltinType::UFract:
700 case BuiltinType::ULongFract:
701 case BuiltinType::SatShortAccum:
702 case BuiltinType::SatAccum:
703 case BuiltinType::SatLongAccum:
704 case BuiltinType::SatUShortAccum:
705 case BuiltinType::SatUAccum:
706 case BuiltinType::SatULongAccum:
707 case BuiltinType::SatShortFract:
708 case BuiltinType::SatFract:
709 case BuiltinType::SatLongFract:
710 case BuiltinType::SatUShortFract:
711 case BuiltinType::SatUFract:
712 case BuiltinType::SatULongFract:
713 case BuiltinType::BFloat16:
714 return false;
715
716 case BuiltinType::Dependent:
717#define BUILTIN_TYPE(Id, SingletonId)
718#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
719#include "clang/AST/BuiltinTypes.def"
720 llvm_unreachable("asking for RRTI for a placeholder type!");
721
722 case BuiltinType::ObjCId:
723 case BuiltinType::ObjCClass:
724 case BuiltinType::ObjCSel:
725 llvm_unreachable("FIXME: Objective-C types are unsupported!");
726 }
727
728 llvm_unreachable("Invalid BuiltinType Kind!");
729}
730
731static bool typeInfoIsInStandardLibrary(const PointerType *pointerTy) {
733 const auto *builtinTy = dyn_cast(pointeeTy);
734 if (!builtinTy)
735 return false;
736
737
740
741 if (!quals.empty())
742 return false;
743
744 return typeInfoIsInStandardLibrary(builtinTy);
745}
746
747
748
749static bool isStandardLibraryRttiDescriptor(QualType ty) {
750
751 if (const auto *builtinTy = dyn_cast(ty))
752 return typeInfoIsInStandardLibrary(builtinTy);
753
754
755
756 if (const auto *pointerTy = dyn_cast(ty))
757 return typeInfoIsInStandardLibrary(pointerTy);
758
759 return false;
760}
761
762
763
764
765
766static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
768
769
770
772 return false;
773
774 if (const auto *recordTy = dyn_cast(ty)) {
775 const auto *rd =
778 return false;
779
781 return false;
782
783
784
785
786
787 bool isDLLImport = rd->hasAttr();
788
789
790 if (cgm.getTriple().isOSCygMing())
791 return false;
792
795 return true;
796
797 return !isDLLImport || cgm.getTriple().isWindowsItaniumEnvironment();
798 }
799
800 if (isDLLImport)
801 return true;
802 }
803
804 return false;
805}
806
807
808
809struct SeenBases {
810 llvm::SmallPtrSet<const CXXRecordDecl *, 16> nonVirtualBases;
811 llvm::SmallPtrSet<const CXXRecordDecl *, 16> virtualBases;
812};
813
814
815
816static unsigned computeVmiClassTypeInfoFlags(const CXXBaseSpecifier *base,
817 SeenBases &bases) {
818
819 unsigned flags = 0;
821
823
824 if (!bases.virtualBases.insert(baseDecl).second) {
825
826
827 flags |= VMI_DiamondShaped;
828 } else {
829 if (bases.nonVirtualBases.count(baseDecl))
830 flags |= VMI_NonDiamondRepeat;
831 }
832 } else {
833
834 if (!bases.nonVirtualBases.insert(baseDecl).second) {
835
836
837 flags |= VMI_NonDiamondRepeat;
838 } else {
839 if (bases.virtualBases.count(baseDecl))
840 flags |= VMI_NonDiamondRepeat;
841 }
842 }
843
844
845 for (const auto &bs : baseDecl->bases())
846 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
847
848 return flags;
849}
850
851static unsigned computeVmiClassTypeInfoFlags(const CXXRecordDecl *rd) {
852 unsigned flags = 0;
853 SeenBases bases;
854
855
856 for (const auto &bs : rd->bases())
857 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
858
859 return flags;
860}
861
862
863
864
865
866static bool canUseSingleInheritance(const CXXRecordDecl *rd) {
867
869 return false;
870
871
873
874
876 return false;
877
878
880 return false;
881
882
884 return baseDecl->isEmpty() ||
886}
887
888
889static bool isIncompleteClassType(const RecordType *recordTy) {
890 return !recordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
891}
892
893
894
895
896
897
898
899
900
901
902
903
904static bool containsIncompleteClassType(QualType ty) {
905 if (const auto *recordTy = dyn_cast(ty)) {
906 if (isIncompleteClassType(recordTy))
907 return true;
908 }
909
910 if (const auto *pointerTy = dyn_cast(ty))
911 return containsIncompleteClassType(pointerTy->getPointeeType());
912
913 if (const auto *memberPointerTy = dyn_cast(ty)) {
914
915 if (!memberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
916 return true;
917
918 return containsIncompleteClassType(memberPointerTy->getPointeeType());
919 }
920
921 return false;
922}
923
924const char *vTableClassNameForType(const CIRGenModule &cgm, const Type *ty) {
925
926 static const char *const classTypeInfo =
927 "_ZTVN10__cxxabiv117__class_type_infoE";
928
929 static const char *const siClassTypeInfo =
930 "_ZTVN10__cxxabiv120__si_class_type_infoE";
931
932 static const char *const vmiClassTypeInfo =
933 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
934
936#define TYPE(Class, Base)
937#define ABSTRACT_TYPE(Class, Base)
938#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
939#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
940#define DEPENDENT_TYPE(Class, Base) case Type::Class:
941#include "clang/AST/TypeNodes.inc"
942 llvm_unreachable("Non-canonical and dependent types shouldn't get here");
943
944 case Type::LValueReference:
945 case Type::RValueReference:
946 llvm_unreachable("References shouldn't get here");
947
948 case Type::Auto:
949 case Type::DeducedTemplateSpecialization:
950 llvm_unreachable("Undeduced type shouldn't get here");
951
952 case Type::Pipe:
953 llvm_unreachable("Pipe types shouldn't get here");
954
955 case Type::ArrayParameter:
956 llvm_unreachable("Array Parameter types should not get here.");
957
958 case Type::Builtin:
959 case Type::BitInt:
960
961 case Type::Vector:
962 case Type::ExtVector:
963 case Type::ConstantMatrix:
964 case Type::Complex:
965 case Type::Atomic:
966
967 case Type::BlockPointer:
968 return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
969 case Type::ConstantArray:
970 case Type::IncompleteArray:
971 case Type::VariableArray:
972 cgm.errorNYI("VTableClassNameForType: __array_type_info");
973 break;
974
975 case Type::FunctionNoProto:
976 case Type::FunctionProto:
977 cgm.errorNYI("VTableClassNameForType: __function_type_info");
978 break;
979
980 case Type::Enum:
981 return "_ZTVN10__cxxabiv116__enum_type_infoE";
982
983 case Type::Record: {
985 ->getDefinitionOrSelf();
986
988 return classTypeInfo;
989 }
990
991 if (canUseSingleInheritance(rd)) {
992 return siClassTypeInfo;
993 }
994
995 return vmiClassTypeInfo;
996 }
997
998 case Type::ObjCObject:
999 cgm.errorNYI("VTableClassNameForType: ObjCObject");
1000 break;
1001
1002 case Type::ObjCInterface:
1003 cgm.errorNYI("VTableClassNameForType: ObjCInterface");
1004 break;
1005
1006 case Type::ObjCObjectPointer:
1007 case Type::Pointer:
1008 cgm.errorNYI("VTableClassNameForType: __pointer_type_info");
1009 break;
1010
1011 case Type::MemberPointer:
1012 cgm.errorNYI("VTableClassNameForType: __pointer_to_member_type_info");
1013 break;
1014
1015 case Type::HLSLAttributedResource:
1016 case Type::HLSLInlineSpirv:
1017 llvm_unreachable("HLSL doesn't support virtual functions");
1018 }
1019
1020 return nullptr;
1021}
1022}
1023
1024
1025
1028
1029
1030
1031
1032
1033
1034
1035
1036 if (containsIncompleteClassType(ty))
1037 return cir::GlobalLinkageKind::InternalLinkage;
1038
1041 llvm_unreachable("Linkage hasn't been computed!");
1042
1046 return cir::GlobalLinkageKind::InternalLinkage;
1047
1051
1052
1054 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1055
1056 if (const RecordType *record = dyn_cast(ty)) {
1057 const auto *rd =
1059 if (rd->hasAttr())
1060 return cir::GlobalLinkageKind::WeakODRLinkage;
1061
1062 if (cgm.getTriple().isWindowsItaniumEnvironment())
1063 if (rd->hasAttr() &&
1064 shouldUseExternalRttiDescriptor(cgm, ty))
1065 return cir::GlobalLinkageKind::ExternalLinkage;
1066
1067
1071 .isWindowsGNUEnvironment())
1073 }
1074
1075 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1076 }
1077
1078 llvm_unreachable("Invalid linkage!");
1079}
1080
1081cir::GlobalOp
1082CIRGenItaniumRTTIBuilder::getAddrOfTypeName(mlir::Location loc, QualType ty,
1083 cir::GlobalLinkageKind linkage) {
1084 CIRGenBuilderTy &builder = cgm.getBuilder();
1085 SmallString<256> name;
1086 llvm::raw_svector_ostream out(name);
1088
1089
1090
1091
1092 mlir::Attribute init = builder.getString(
1094 std::nullopt);
1095
1096 CharUnits align =
1098
1099
1100
1101
1103
1105 loc, name, initStr.getType(), linkage, align);
1107 return gv;
1108}
1109
1110mlir::Attribute
1111CIRGenItaniumRTTIBuilder::getAddrOfExternalRTTIDescriptor(mlir::Location loc,
1112 QualType ty) {
1113
1114 SmallString<256> name;
1115 llvm::raw_svector_ostream out(name);
1117 CIRGenBuilderTy &builder = cgm.getBuilder();
1118
1119
1120 cir::GlobalOp gv = dyn_cast_or_nullcir::GlobalOp(
1121 mlir::SymbolTable::lookupSymbolIn(cgm.getModule(), name));
1122
1123 if (!gv) {
1124
1125
1126
1127
1129 true);
1132
1133
1134
1136 cgm.errorNYI("getAddrOfExternalRTTIDescriptor: hasPS4DLLImportExport");
1137 }
1138 }
1139
1141}
1142
1143void CIRGenItaniumRTTIBuilder::buildVTablePointer(mlir::Location loc,
1144 const Type *ty) {
1145 CIRGenBuilderTy &builder = cgm.getBuilder();
1146 const char *vTableName = vTableClassNameForType(cgm, ty);
1147
1148
1150 cgm.errorNYI("buildVTablePointer: isRelativeLayout");
1151 return;
1152 }
1153
1157 loc, vTableName, vtableGlobalTy, cir::GlobalLinkageKind::ExternalLinkage,
1159
1160
1161 mlir::Attribute field{};
1163 cgm.errorNYI("buildVTablePointer: isRelativeLayout");
1164 } else {
1165 SmallVector<mlir::Attribute, 4> offsets{
1166 cgm.getBuilder().getI32IntegerAttr(2)};
1167 auto indices = mlir::ArrayAttr::get(builder.getContext(), offsets);
1169 vTable, indices);
1170 }
1171
1172 assert(field && "expected attribute");
1173 fields.push_back(field);
1174}
1175
1176
1177
1178void CIRGenItaniumRTTIBuilder::buildSIClassTypeInfo(mlir::Location loc,
1179 const CXXRecordDecl *rd) {
1180
1181
1182
1183 mlir::Attribute baseTypeInfo =
1184 CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1186 fields.push_back(baseTypeInfo);
1187}
1188
1189
1190
1191
1192void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc,
1193 const CXXRecordDecl *rd) {
1194 mlir::Type unsignedIntLTy =
1196
1197
1198
1199
1200
1201 unsigned flags = computeVmiClassTypeInfoFlags(rd);
1202 fields.push_back(cir::IntAttr::get(unsignedIntLTy, flags));
1203
1204
1205
1206
1207 fields.push_back(cir::IntAttr::get(unsignedIntLTy, rd->getNumBases()));
1208
1210 return;
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1237 if (ti.getTriple().isOSCygMing() &&
1240 mlir::Type offsetFlagsLTy = cgm.convertType(offsetFlagsTy);
1241
1242 for (const CXXBaseSpecifier &base : rd->bases()) {
1243
1244 fields.push_back(CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1245 .buildTypeInfo(loc, base.getType()));
1246
1248 int64_t offsetFlags = 0;
1249
1250
1251
1252
1253
1254 CharUnits offset;
1257 rd, baseDecl);
1258 else {
1259 const ASTRecordLayout &layout =
1262 }
1264
1265
1266
1268 offsetFlags |= BCTI_Virtual;
1270 offsetFlags |= BCTI_Public;
1271
1272 fields.push_back(cir::IntAttr::get(offsetFlagsLTy, offsetFlags));
1273 }
1274}
1275
1276mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(mlir::Location loc,
1277 QualType ty) {
1278
1280
1281
1282 SmallString<256> name;
1283 llvm::raw_svector_ostream out(name);
1285
1286 auto oldGV = dyn_cast_or_nullcir::GlobalOp(
1287 mlir::SymbolTable::lookupSymbolIn(cgm.getModule(), name));
1288
1289 if (oldGV && !oldGV.isDeclaration()) {
1290 assert(!oldGV.hasAvailableExternallyLinkage() &&
1291 "available_externally typeinfos not yet implemented");
1293 oldGV);
1294 }
1295
1296
1297 if (isStandardLibraryRttiDescriptor(ty) ||
1298 shouldUseExternalRttiDescriptor(cgm, ty))
1299 return getAddrOfExternalRTTIDescriptor(loc, ty);
1300
1301
1303
1304
1305
1308
1309 mlir::SymbolTable::Visibility symVisibility;
1311
1312 symVisibility = mlir::SymbolTable::Visibility::Public;
1313 else if (cxxABI.classifyRTTIUniqueness(ty, linkage) ==
1314 CIRGenItaniumCXXABI::RUK_NonUniqueHidden) {
1316 "buildTypeInfo: classifyRTTIUniqueness == RUK_NonUniqueHidden");
1318 } else
1320
1321 return buildTypeInfo(loc, ty, linkage, symVisibility);
1322}
1323
1324mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
1325 mlir::Location loc, QualType ty, cir::GlobalLinkageKind linkage,
1326 mlir::SymbolTable::Visibility visibility) {
1327 CIRGenBuilderTy &builder = cgm.getBuilder();
1328
1330
1331
1332 buildVTablePointer(loc, cast(ty));
1333
1334
1335 cir::GlobalOp typeName = getAddrOfTypeName(loc, ty, linkage);
1336 mlir::Attribute typeNameField;
1337
1338
1339
1340 CIRGenItaniumCXXABI::RTTIUniquenessKind rttiUniqueness =
1341 cxxABI.classifyRTTIUniqueness(ty, linkage);
1342 if (rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique) {
1343
1344
1346 "buildTypeInfo: rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique");
1347 } else {
1348 typeNameField =
1350 }
1351
1352 fields.push_back(typeNameField);
1353
1355#define TYPE(Class, Base)
1356#define ABSTRACT_TYPE(Class, Base)
1357#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1358#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1359#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1360#include "clang/AST/TypeNodes.inc"
1361 llvm_unreachable("Non-canonical and dependent types shouldn't get here");
1362
1363
1364 case Type::Builtin:
1365 case Type::Vector:
1366 case Type::ExtVector:
1367 case Type::ConstantMatrix:
1368 case Type::Complex:
1369 case Type::BlockPointer:
1370
1371
1372 break;
1373
1374 case Type::LValueReference:
1375 case Type::RValueReference:
1376 llvm_unreachable("References shouldn't get here");
1377
1378 case Type::Auto:
1379 case Type::DeducedTemplateSpecialization:
1380 llvm_unreachable("Undeduced type shouldn't get here");
1381
1382 case Type::Pipe:
1383 break;
1384
1385 case Type::BitInt:
1386 break;
1387
1388 case Type::ConstantArray:
1389 case Type::IncompleteArray:
1390 case Type::VariableArray:
1391 case Type::ArrayParameter:
1392
1393
1394 break;
1395
1396 case Type::FunctionNoProto:
1397 case Type::FunctionProto:
1398
1399
1400 break;
1401
1402 case Type::Enum:
1403
1404
1405 break;
1406
1407 case Type::Record: {
1409 ->getDefinitionOrSelf();
1411
1412 break;
1413 }
1414
1415 if (canUseSingleInheritance(rd)) {
1416 buildSIClassTypeInfo(loc, rd);
1417 } else {
1418 buildVMIClassTypeInfo(loc, rd);
1419 }
1420
1421 break;
1422 }
1423
1424 case Type::ObjCObject:
1425 case Type::ObjCInterface:
1426 cgm.errorNYI("buildTypeInfo: ObjCObject & ObjCInterface");
1427 break;
1428
1429 case Type::ObjCObjectPointer:
1430 cgm.errorNYI("buildTypeInfo: ObjCObjectPointer");
1431 break;
1432
1433 case Type::Pointer:
1434 cgm.errorNYI("buildTypeInfo: Pointer");
1435 break;
1436
1437 case Type::MemberPointer:
1438 cgm.errorNYI("buildTypeInfo: MemberPointer");
1439 break;
1440
1441 case Type::Atomic:
1442
1443 break;
1444
1445 case Type::HLSLAttributedResource:
1446 case Type::HLSLInlineSpirv:
1447 llvm_unreachable("HLSL doesn't support RTTI");
1448 }
1449
1451 cir::TypeInfoAttr init = builder.getTypeInfo(builder.getArrayAttr(fields));
1452
1453 SmallString<256> name;
1454 llvm::raw_svector_ostream out(name);
1456
1457
1458 auto oldGV = dyn_cast_or_nullcir::GlobalOp(
1459 mlir::SymbolTable::lookupSymbolIn(cgm.getModule(), name));
1460
1461 cir::GlobalOp gv =
1463 true);
1464
1465
1466
1468 cgm.errorNYI("buildTypeInfo: target hasPS4DLLImportExport");
1469 return {};
1470 }
1471
1472
1473 if (oldGV) {
1474
1475 gv.setName(oldGV.getName());
1476 if (!oldGV->use_empty()) {
1477 cgm.errorNYI("buildTypeInfo: old GV !use_empty");
1478 return {};
1479 }
1480 oldGV->erase();
1481 }
1482
1485 cgm.errorNYI("buildTypeInfo: supportsCOMDAT & isWeakForLinker");
1486 return {};
1487 }
1488
1491 gv.setAlignmentAttr(cgm.getSize(align));
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508 mlir::SymbolTable::setSymbolVisibility(typeName, visibility);
1512
1513 mlir::SymbolTable::setSymbolVisibility(gv, visibility);
1517
1520}
1521
1522mlir::Attribute CIRGenItaniumCXXABI::getAddrOfRTTIDescriptor(mlir::Location loc,
1523 QualType ty) {
1524 return CIRGenItaniumRTTIBuilder(*this, cgm).buildTypeInfo(loc, ty);
1525}
1526
1527
1528
1529CIRGenItaniumCXXABI::RTTIUniquenessKind
1530CIRGenItaniumCXXABI::classifyRTTIUniqueness(
1531 QualType canTy, cir::GlobalLinkageKind linkage) const {
1532 if (shouldRTTIBeUnique())
1533 return RUK_Unique;
1534
1535
1536 if (linkage != cir::GlobalLinkageKind::LinkOnceODRLinkage &&
1537 linkage != cir::GlobalLinkageKind::WeakODRLinkage)
1538 return RUK_Unique;
1539
1540
1542 return RUK_Unique;
1543
1544
1545 if (linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage)
1546 return RUK_NonUniqueHidden;
1547
1548
1549
1550
1551 assert(linkage == cir::GlobalLinkageKind::WeakODRLinkage);
1552 return RUK_NonUniqueVisible;
1553}
1554
1555void CIRGenItaniumCXXABI::emitDestructorCall(
1556 CIRGenFunction &cgf, const CXXDestructorDecl *dd, CXXDtorType type,
1557 bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy) {
1558 GlobalDecl gd(dd, type);
1559 mlir::Value vtt =
1564 CIRGenCallee callee =
1566
1568 vttTy, nullptr);
1569}
1570
1571void CIRGenItaniumCXXABI::registerGlobalDtor(const VarDecl *vd,
1572 cir::FuncOp dtor,
1573 mlir::Value addr) {
1575 return;
1576
1579 return;
1580 }
1581
1582
1585 return;
1586 }
1587
1588
1589
1590}
1591
1592mlir::Value CIRGenItaniumCXXABI::getCXXDestructorImplicitParam(
1593 CIRGenFunction &cgf, const CXXDestructorDecl *dd, CXXDtorType type,
1594 bool forVirtualBase, bool delegating) {
1595 GlobalDecl gd(dd, type);
1596 return cgf.getVTTParameter(gd, forVirtualBase, delegating);
1597}
1598
1599
1600
1601
1603 mlir::Value exceptionPtr = {},
1604 mlir::FlatSymbolRefAttr typeInfo = {},
1605 mlir::FlatSymbolRefAttr dtor = {}) {
1606 mlir::Block *currentBlock = builder.getInsertionBlock();
1607 mlir::Region *region = currentBlock->getParent();
1608
1609 if (currentBlock->empty()) {
1610 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1611 cir::UnreachableOp::create(builder, loc);
1612 } else {
1613 mlir::Block *throwBlock = builder.createBlock(region);
1614
1615 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1616 cir::UnreachableOp::create(builder, loc);
1617
1618 builder.setInsertionPointToEnd(currentBlock);
1619 cir::BrOp::create(builder, loc, throwBlock);
1620 }
1621
1622 (void)builder.createBlock(region);
1623}
1624
1625void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf, bool isNoReturn) {
1626
1627 if (isNoReturn) {
1628 CIRGenBuilderTy &builder = cgf.getBuilder();
1629 assert(cgf.currSrcLoc && "expected source location");
1630 mlir::Location loc = *cgf.currSrcLoc;
1632 } else {
1633 cgm.errorNYI("emitRethrow with isNoReturn false");
1634 }
1635}
1636
1637void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf,
1638 const CXXThrowExpr *e) {
1639
1640
1641
1642
1643
1644 CIRGenBuilderTy &builder = cgf.getBuilder();
1646 cir::PointerType throwTy =
1651
1652
1653 mlir::TypedValuecir::PointerType exceptionPtr =
1654 cir::AllocExceptionOp::create(builder, subExprLoc, throwTy,
1655 builder.getI64IntegerAttr(typeSize))
1656 .getAddr();
1657
1658
1661
1662
1663 auto typeInfo = mlir::castcir::GlobalViewAttr(
1665 true));
1666 assert(!typeInfo.getIndices() && "expected no indirection");
1667
1668
1669
1670
1671
1672
1673
1674
1675 if (const RecordType *recordTy = clangThrowType->getAs()) {
1678 if (!rec->hasTrivialDestructor()) {
1679 cgm.errorNYI("emitThrow: non-trivial destructor");
1680 return;
1681 }
1682 }
1683
1684
1687}
1688
1691 case TargetCXXABI::GenericItanium:
1692 case TargetCXXABI::GenericAArch64:
1693 return new CIRGenItaniumCXXABI(cgm);
1694
1695 case TargetCXXABI::AppleARM64:
1696
1697
1699 return new CIRGenItaniumCXXABI(cgm);
1700
1701 default:
1702 llvm_unreachable("bad or NYI ABI kind");
1703 }
1704}
1705
1706cir::GlobalOp CIRGenItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *rd,
1708 assert(vptrOffset.isZero() && "Itanium ABI only supports zero vptr offsets");
1709 cir::GlobalOp &vtable = vtables[rd];
1710 if (vtable)
1711 return vtable;
1712
1713
1715
1717 llvm::raw_svector_ostream out(name);
1718 getMangleContext().mangleCXXVTable(rd, out);
1719
1723
1724
1725
1726
1728 ? 32
1730
1733 cir::GlobalLinkageKind::ExternalLinkage,
1735
1737
1738
1739
1740
1741
1742
1743
1744
1747 "getAddrOfVTable: PS4 DLL import/export");
1748
1750 return vtable;
1751}
1752
1753CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer(
1757 mlir::Location loc = cgf.getLoc(srcLoc);
1758 cir::PointerType tyPtr = builder.getPointerTo(ty);
1760 mlir::Value vtable = cgf.getVTablePtr(loc, thisAddr, methodDecl->getParent());
1761
1763 mlir::Value vfunc{};
1765 cgm.errorNYI(loc, "getVirtualFunctionPointer: emitVTableTypeCheckedLoad");
1766 } else {
1768
1769 mlir::Value vfuncLoad;
1772 cgm.errorNYI(loc, "getVirtualFunctionPointer: isRelativeLayout");
1773 } else {
1774 auto vtableSlotPtr = cir::VTableGetVirtualFnAddrOp::create(
1775 builder, loc, builder.getPointerTo(tyPtr), vtable, vtableIndex);
1776 vfuncLoad = builder.createAlignedLoad(loc, tyPtr, vtableSlotPtr,
1778 }
1779
1780
1781
1782
1783
1784
1785
1788 cgm.errorNYI(loc, "getVirtualFunctionPointer: strictVTablePointers");
1789 }
1790 vfunc = vfuncLoad;
1791 }
1792
1793 CIRGenCallee callee(gd, vfunc.getDefiningOp());
1794 return callee;
1795}
1796
1797mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1798 CIRGenFunction &cgf, const CXXRecordDecl *vtableClass, BaseSubobject base,
1799 const CXXRecordDecl *nearestVBase) {
1801 needsVTTParameter(cgf.curGD) && "This class doesn't have VTT");
1802
1803
1804 uint64_t virtualPointerIndex =
1806
1807
1808 mlir::Value vttPtr = cgf.loadCXXVTT();
1810
1812 virtualPointerIndex);
1813
1814 auto vptrType = cir::VPtrType::get(cgf.getBuilder().getContext());
1817}
1818
1819mlir::Value
1820CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject base,
1821 const CXXRecordDecl *vtableClass) {
1822 cir::GlobalOp vtable = getAddrOfVTable(vtableClass, CharUnits());
1823
1824
1825
1826 VTableLayout::AddressPointLocation addressPoint =
1830
1831 mlir::OpBuilder &builder = cgm.getBuilder();
1832 auto vtablePtrTy = cir::VPtrType::get(builder.getContext());
1833
1834 return cir::VTableAddrPointOp::create(
1836 mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()),
1837 cir::AddressPointAttr::get(cgm.getBuilder().getContext(),
1840}
1841
1842mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor(
1843 CIRGenFunction &cgf, const clang::CXXRecordDecl *vtableClass,
1844 clang::BaseSubobject base, const clang::CXXRecordDecl *nearestVBase) {
1845
1847 needsVTTParameter(cgf.curGD)) {
1848 return getVTableAddressPointInStructorWithVTT(cgf, vtableClass, base,
1849 nearestVBase);
1850 }
1851 return getVTableAddressPoint(base, vtableClass);
1852}
1853
1854bool CIRGenItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1855 CIRGenFunction &cgf, CIRGenFunction::VPtr vptr) {
1857 return false;
1858 return needsVTTParameter(cgf.curGD);
1859}
1860
1861mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(
1862 mlir::Location loc, CIRGenFunction &cgf, Address thisAddr,
1863 const CXXRecordDecl *classDecl, const CXXRecordDecl *baseClassDecl) {
1864 CIRGenBuilderTy &builder = cgf.getBuilder();
1865 mlir::Value vtablePtr = cgf.getVTablePtr(loc, thisAddr, classDecl);
1867 CharUnits vbaseOffsetOffset =
1869 baseClassDecl);
1870 mlir::Value offsetVal =
1872 auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.uInt8PtrTy,
1873 vtableBytePtr, offsetVal);
1874
1875 mlir::Value vbaseOffset;
1878 cgm.errorNYI(loc, "getVirtualBaseClassOffset: relative layout");
1879 } else {
1884 }
1885 return vbaseOffset;
1886}
1887
1889
1890
1891
1893
1894 cir::FuncType fnTy =
1897}
1898
1900
1902
1904 cir::UnreachableOp::create(cgf.getBuilder(), loc);
1905 cgf.getBuilder().clearInsertionPoint();
1906}
1907
1908void CIRGenItaniumCXXABI::emitBadCastCall(CIRGenFunction &cgf,
1909 mlir::Location loc) {
1911}
1912
1913
1917 CXXBasePaths paths(true, true,
1918 false);
1919
1920
1921
1922 if (!dst->isDerivedFrom(src, paths))
1924
1925 unsigned numPublicPaths = 0;
1927
1928
1930 if (path.Access != AS_public)
1931 continue;
1932
1933 ++numPublicPaths;
1934
1936
1937
1938 if (pathElement.Base->isVirtual())
1940
1941 if (numPublicPaths > 1)
1942 continue;
1943
1944
1948 pathElement.Base->getType()->getAsCXXRecordDecl());
1949 }
1950 }
1951
1952
1953 if (numPublicPaths == 0)
1955
1956
1957 if (numPublicPaths > 1)
1959
1960
1961
1962 return offset;
1963}
1964
1966
1967
1968
1969
1970
1971
1975
1976
1980
1981
1983
1985 {voidPtrTy, rttiPtrTy, rttiPtrTy, ptrDiffTy}, voidPtrTy);
1987}
1988
1991 bool vtableUsesRelativeLayout =
1994 loc, src.getPointer(), vtableUsesRelativeLayout);
1996}
1997
2002 cir::PointerType destCIRTy,
2003 bool isRefCast, Address src) {
2004
2007 CXXBasePaths paths(true, true,
2008 false);
2010
2011
2012
2013 std::optional offset;
2015
2017 continue;
2018
2021
2023 pathElement.Base->getType()->getAsCXXRecordDecl();
2024 if (pathElement.Base->isVirtual()) {
2025
2026
2030 } else {
2034 }
2035 }
2036
2037 if (!offset) {
2038 offset = pathOffset;
2039 } else if (offset != pathOffset) {
2040
2041
2042
2043
2045 srcDecl = destDecl;
2047 break;
2048 }
2049 }
2050
2052
2053 if (!offset) {
2054
2055 mlir::Value nullPtrValue = builder.getNullPtr(destCIRTy, loc);
2056 if (isRefCast) {
2057 mlir::Region *currentRegion = builder.getBlock()->getParent();
2059
2060
2061
2062 builder.createBlock(currentRegion, currentRegion->end());
2063 }
2064
2065 return nullPtrValue;
2066 }
2067
2068
2069
2070
2071
2072
2073 mlir::Value expectedVPtr =
2074 abi.getVTableAddressPoint(BaseSubobject(srcDecl, *offset), destDecl);
2075
2076
2078 mlir::Type vptrTy = expectedVPtr.getType();
2079 mlir::Type vptrPtrTy = builder.getPointerTo(vptrTy);
2082 mlir::Value srcVPtr = builder.createLoad(loc, srcVPtrPtr);
2083
2084
2086
2087 mlir::Value success =
2088 builder.createCompare(loc, cir::CmpOpKind::eq, srcVPtr, expectedVPtr);
2089
2090 auto emitCastResult = [&] {
2091 if (offset->isZero())
2093
2094
2097
2098 mlir::Value strideToApply =
2101 mlir::Value resultU8Ptr = cir::PtrStrideOp::create(builder, loc, u8PtrTy,
2102 srcU8Ptr, strideToApply);
2103 return builder.createBitcast(resultU8Ptr, destCIRTy);
2104 };
2105
2106 if (isRefCast) {
2107 mlir::Value failed = builder.createNot(success);
2108 cir::IfOp::create(builder, loc, failed, false,
2109 [&](mlir::OpBuilder &, mlir::Location) {
2111 });
2112 return emitCastResult();
2113 }
2114
2115 return cir::TernaryOp::create(
2116 builder, loc, success,
2117 [&](mlir::OpBuilder &, mlir::Location) {
2118 auto result = emitCastResult();
2120 },
2121 [&](mlir::OpBuilder &, mlir::Location) {
2122 mlir::Value nullPtrValue = builder.getNullPtr(destCIRTy, loc);
2124 })
2125 .getResult();
2126}
2127
2129 mlir::Location loc,
2132 auto srcRtti = mlir::castcir::GlobalViewAttr(
2134 auto destRtti = mlir::castcir::GlobalViewAttr(
2136
2138 cir::FuncOp badCastFuncOp = getBadCastFn(cgf);
2139 auto runtimeFuncRef = mlir::FlatSymbolRefAttr::get(runtimeFuncOp);
2140 auto badCastFuncRef = mlir::FlatSymbolRefAttr::get(badCastFuncOp);
2141
2145
2147 auto offsetHintAttr = cir::IntAttr::get(ptrdiffTy, offsetHint.getQuantity());
2148
2149 return cir::DynamicCastInfoAttr::get(srcRtti, destRtti, runtimeFuncRef,
2150 badCastFuncRef, offsetHintAttr);
2151}
2152
2153mlir::Value CIRGenItaniumCXXABI::emitDynamicCast(CIRGenFunction &cgf,
2154 mlir::Location loc,
2155 QualType srcRecordTy,
2156 QualType destRecordTy,
2157 cir::PointerType destCIRTy,
2158 bool isRefCast, Address src) {
2159 bool isCastToVoid = destRecordTy.isNull();
2160 assert((!isCastToVoid || !isRefCast) && "cannot cast to void reference");
2161
2162 if (isCastToVoid)
2164
2165
2166
2169 CIRGenBuilderTy &builder = cgf.getBuilder();
2170
2171 if (!isRefCast) {
2173 return cir::TernaryOp::create(
2174 builder, loc, srcPtrIsNull,
2175 [&](mlir::OpBuilder, mlir::Location) {
2177 loc, builder.getNullPtr(destCIRTy, loc).getResult());
2178 },
2179 [&](mlir::OpBuilder &, mlir::Location) {
2181 *this, cgf, loc, srcRecordTy, destRecordTy, destCIRTy,
2182 isRefCast, src);
2184 })
2185 .getResult();
2186 }
2187
2189 destCIRTy, isRefCast, src);
2190 }
2191
2192 cir::DynamicCastInfoAttr castInfo =
2195 isRefCast, castInfo);
2196}
2197
2198
2199
2200void CIRGenItaniumCXXABI::emitVirtualObjectDelete(
2201 CIRGenFunction &cgf, const CXXDeleteExpr *delExpr, Address ptr,
2202 QualType elementType, const CXXDestructorDecl *dtor) {
2204 if (useGlobalDelete) {
2206 "emitVirtualObjectDelete: global delete");
2207 }
2208
2210 emitVirtualDestructorCall(cgf, dtor, dtorType, ptr, delExpr);
2211}
2212
2213
2214
2215CharUnits CIRGenItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2216
2217
2218 return std::max(
2221}
2222
2223Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf,
2224 Address newPtr,
2225 mlir::Value numElements,
2226 const CXXNewExpr *e,
2227 QualType elementType) {
2228 assert(requiresArrayCookie(e));
2229
2230
2231
2234
2238
2239
2240 CharUnits cookieSize =
2242 assert(cookieSize == getArrayCookieSizeImpl(elementType));
2243
2245 mlir::Value baseBytePtr =
2247
2248
2249 CharUnits cookieOffset = cookieSize - sizeSize;
2250 mlir::Value cookiePtrValue = baseBytePtr;
2251 if (!cookieOffset.isZero()) {
2253 loc, cookieOffset.getQuantity(), 32);
2254 cookiePtrValue =
2256 }
2257
2258 CharUnits baseAlignment = newPtr.getAlignment();
2259 CharUnits cookiePtrAlignment = baseAlignment.alignmentAtOffset(cookieOffset);
2260 Address cookiePtr(cookiePtrValue, u8PtrTy, cookiePtrAlignment);
2261
2262
2263 Address numElementsPtr =
2266
2267
2268
2269 mlir::Value dataOffset =
2271 32);
2272 mlir::Value dataPtr =
2274 mlir::Value finalPtr =
2276 CharUnits finalAlignment = baseAlignment.alignmentAtOffset(cookieSize);
2277 return Address(finalPtr, newPtr.getElementType(), finalAlignment);
2278}
2279
2280namespace {
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294struct CallEndCatch final : EHScopeStack::Cleanup {
2295 CallEndCatch(bool mightThrow) : mightThrow(mightThrow) {}
2296 bool mightThrow;
2297
2298 void emit(CIRGenFunction &cgf, Flags flags) override {
2299 if (!mightThrow) {
2300
2301
2302
2303
2305 return;
2306 }
2307
2308
2309
2310
2311
2312 if (!cgf.getBuilder().getBlock()->mightHaveTerminator())
2314 }
2315};
2316}
2317
2319 bool endMightThrow) {
2320 auto catchParam = cir::CatchParamOp::create(
2322
2323 cgf.ehStack.pushCleanup(
2325 endMightThrow && !cgf.cgm.getLangOpts().AssumeNothrowExceptionDtor);
2326
2327 return catchParam.getParam();
2328}
2329
2330
2331
2336
2337
2339 cgf.cgm.errorNYI(loc, "initCatchParam: ReferenceType");
2340 return;
2341 }
2342
2343
2346
2347
2348
2349 if (catchType->hasPointerRepresentation()) {
2350 cgf.cgm.errorNYI(loc, "initCatchParam: hasPointerRepresentation");
2351 return;
2352 }
2353
2355 mlir::Value catchParam =
2358 LValue destLV = cgf.makeAddrLValue(paramAddr, catchType);
2359 switch (tek) {
2361 cgf.cgm.errorNYI(loc, "initCatchParam: cir::TEK_Complex");
2362 return;
2363 }
2367 return;
2368 }
2370 llvm_unreachable("evaluation kind filtered out!");
2371 }
2372
2373
2374 llvm_unreachable("bad evaluation kind");
2375 }
2376
2377 cgf.cgm.errorNYI(loc, "initCatchParam: cir::TEK_Aggregate");
2378}
2379
2380
2381
2382void CIRGenItaniumCXXABI::emitBeginCatch(CIRGenFunction &cgf,
2383 const CXXCatchStmt *catchStmt) {
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2408 if (!catchParam) {
2410 true);
2411 return;
2412 }
2413
2414 auto getCatchParamAllocaIP = [&]() {
2415 cir::CIRBaseBuilderTy::InsertPoint currIns =
2416 cgf.getBuilder().saveInsertionPoint();
2417 mlir::Operation *currParent = currIns.getBlock()->getParentOp();
2418
2419 mlir::Block *insertBlock = nullptr;
2420 if (auto scopeOp = currParent->getParentOfTypecir::ScopeOp()) {
2421 insertBlock = &scopeOp.getScopeRegion().getBlocks().back();
2422 } else if (auto fnOp = currParent->getParentOfTypecir::FuncOp()) {
2423 insertBlock = &fnOp.getRegion().getBlocks().back();
2424 } else {
2425 llvm_unreachable("unknown outermost scope-like parent");
2426 }
2428 };
2429
2430
2431
2432
2433
2434 CIRGenFunction::AutoVarEmission var =
2439}
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 void emitConstructorDestructorAlias(CIRGenModule &cgm, GlobalDecl aliasDecl, GlobalDecl targetDecl)
Definition CIRGenItaniumCXXABI.cpp:295
static CharUnits computeOffsetHint(ASTContext &astContext, const CXXRecordDecl *src, const CXXRecordDecl *dst)
Definition CIRGenItaniumCXXABI.cpp:1914
static void initCatchParam(CIRGenFunction &cgf, const VarDecl &catchParam, Address paramAddr, SourceLocation loc)
A "special initializer" callback for initializing a catch parameter during catch initialization.
Definition CIRGenItaniumCXXABI.cpp:2332
static void insertThrowAndSplit(mlir::OpBuilder &builder, mlir::Location loc, mlir::Value exceptionPtr={}, mlir::FlatSymbolRefAttr typeInfo={}, mlir::FlatSymbolRefAttr dtor={})
Definition CIRGenItaniumCXXABI.cpp:1602
static mlir::Value callBeginCatch(CIRGenFunction &cgf, mlir::Type paramTy, bool endMightThrow)
Definition CIRGenItaniumCXXABI.cpp:2318
static Address emitDynamicCastToVoid(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, Address src)
Definition CIRGenItaniumCXXABI.cpp:1989
static cir::DynamicCastInfoAttr emitDynamicCastInfo(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy)
Definition CIRGenItaniumCXXABI.cpp:2128
static cir::GlobalLinkageKind getTypeInfoLinkage(CIRGenModule &cgm, QualType ty)
Return the linkage that the type info and type info name constants should have for the given type.
Definition CIRGenItaniumCXXABI.cpp:1026
static mlir::Value emitExactDynamicCast(CIRGenItaniumCXXABI &abi, CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy, cir::PointerType destCIRTy, bool isRefCast, Address src)
Definition CIRGenItaniumCXXABI.cpp:1998
static void emitCallToBadCast(CIRGenFunction &cgf, mlir::Location loc)
Definition CIRGenItaniumCXXABI.cpp:1899
static cir::FuncOp getItaniumDynamicCastFn(CIRGenFunction &cgf)
Definition CIRGenItaniumCXXABI.cpp:1965
static StructorCIRGen getCIRGenToUse(CIRGenModule &cgm, const CXXMethodDecl *md)
Definition CIRGenItaniumCXXABI.cpp:257
static cir::FuncOp getBadCastFn(CIRGenFunction &cgf)
Definition CIRGenItaniumCXXABI.cpp:1888
Defines the clang::Expr interface and subclasses for C++ expressions.
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
mlir::Value createPtrIsNull(mlir::Value ptr)
cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base, mlir::Value stride)
static OpBuilder::InsertPoint getBestAllocaInsertPoint(mlir::Block *block)
cir::PointerType getPointerTo(mlir::Type ty)
mlir::Value createNot(mlir::Value value)
cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc)
mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy)
mlir::Value getSignedInt(mlir::Location loc, int64_t val, unsigned numBits)
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)
cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind, mlir::Value lhs, mlir::Value rhs)
cir::PointerType getVoidPtrTy(clang::LangAS langAS=clang::LangAS::Default)
cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value={})
Create a yield operation.
llvm::Align getABITypeAlign(mlir::Type ty) const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
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.
const LangOptions & getLangOpts() const
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CharUnits getExnObjectAlignment() const
Return the alignment (in bytes) of the thrown exception object.
CharUnits getPreferredTypeAlignInChars(QualType T) const
Return the PreferredAlignment of a (complete) type T, in characters.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
CanQualType getCanonicalTagType(const TagDecl *TD) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
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 * getBase() const
getBase - Returns the base class declaration.
mlir::Value getPointer() const
mlir::Type getElementType() const
clang::CharUnits getAlignment() const
mlir::Value emitRawPointer() const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
cir::IntType getUInt64Ty()
cir::TypeInfoAttr getTypeInfo(mlir::ArrayAttr fieldsAttr)
cir::ConstantOp getSInt64(uint64_t c, mlir::Location loc)
cir::PointerType getUInt8PtrTy()
mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy, std::optional< size_t > size)
Get a cir::ConstArrayAttr for a string literal.
cir::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty, mlir::Value ptr, llvm::MaybeAlign align)
cir::FuncType getFuncType(llvm::ArrayRef< mlir::Type > params, mlir::Type retTy, bool isVarArg=false)
mlir::Value createDynCastToVoid(mlir::Location loc, mlir::Value src, bool vtableUseRelativeLayout)
mlir::Value createDynCast(mlir::Location loc, mlir::Value src, cir::PointerType destType, bool isRefCast, cir::DynamicCastInfoAttr info)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
mlir::Value createVTTAddrPoint(mlir::Location loc, mlir::Type retTy, mlir::Value addr, uint64_t offset)
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false)
Implements C++ ABI-specific code generation functions.
clang::MangleContext & getMangleContext()
Gets the mangle context.
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
static CIRGenCallee forVirtual(const clang::CallExpr *ce, clang::GlobalDecl md, Address addr, cir::FuncType fTy)
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...
AutoVarEmission emitAutoVarAlloca(const clang::VarDecl &d, mlir::OpBuilder::InsertPoint ip={})
const clang::Decl * curFuncDecl
Address getAddrOfLocalVar(const clang::VarDecl *vd)
Return the address of a local variable.
void emitAnyExprToExn(const Expr *e, Address addr)
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.
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
mlir::Type convertTypeForMem(QualType t)
void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, clang::QualType ty, LValueBaseInfo baseInfo, bool isInit=false, bool isNontemporal=false)
mlir::Value loadCXXVTT()
Load the VTT parameter to base constructors/destructors have virtual bases.
mlir::Value getVTablePtr(mlir::Location loc, Address thisAddr, const clang::CXXRecordDecl *vtableClass)
Return the Value of the vtable pointer member pointed to by thisAddr.
bool shouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *rd)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
CIRGenBuilderTy & getBuilder()
mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
mlir::Value emitRuntimeCall(mlir::Location loc, cir::FuncOp callee, llvm::ArrayRef< mlir::Value > args={})
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)
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
clang::ASTContext & getContext() const
void emitAutoVarCleanups(const AutoVarEmission &emission)
This class organizes the cross-function state that is used while generating CIR code.
llvm::StringRef getMangledName(clang::GlobalDecl gd)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
clang::ASTContext & getASTContext() const
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::ArrayAttr={}, bool isLocal=false, bool assumeConvergent=false)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
mlir::Type convertType(clang::QualType type)
mlir::IntegerAttr getSize(CharUnits size)
CIRGenBuilderTy & getBuilder()
ItaniumVTableContext & getItaniumVTableContext()
void setGVProperties(mlir::Operation *op, const NamedDecl *d) const
Set visibility, dllimport/dllexport and dso_local.
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
const clang::TargetInfo & getTarget() const
const llvm::Triple & getTriple() const
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
cir::GlobalOp createOrReplaceCXXRuntimeVariable(mlir::Location loc, llvm::StringRef name, mlir::Type ty, cir::GlobalLinkageKind linkage, clang::CharUnits alignment)
Will return a global variable of the given type.
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
const cir::CIRDataLayout getDataLayout() const
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
const clang::CodeGenOptions & getCodeGenOpts() const
const clang::LangOptions & getLangOpts() const
cir::FuncOp codegenCXXStructor(clang::GlobalDecl gd)
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
mlir::Operation * getGlobalValue(llvm::StringRef ref)
mlir::ModuleOp getModule() const
bool supportsCOMDAT() const
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
static cir::GlobalOp createGlobalOp(CIRGenModule &cgm, mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::Operation *insertPoint=nullptr)
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
CIRGenCXXABI & getCXXABI() const
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
CIRGenVTables & getVTables()
cir::GlobalLinkageKind getVTableLinkage(const CXXRecordDecl *rd)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
cir::RecordType getVTableType(const clang::VTableLayout &layout)
Returns the type of a vtable with the given layout.
void createVTableInitializer(cir::GlobalOp &vtable, const clang::VTableLayout &layout, mlir::Attribute rtti, bool vtableHasLocalLinkage)
Add vtable components for the given vtable layout to the given global initializer.
void emitVTTDefinition(cir::GlobalOp vttOp, cir::GlobalLinkageKind linkage, const CXXRecordDecl *rd)
Emit the definition of the given vtable.
cir::GlobalOp getAddrOfVTT(const CXXRecordDecl *rd)
Get the address of the VTT for the given record decl.
bool isVTableExternal(const clang::CXXRecordDecl *rd)
At this point in the translation unit, does it appear that can we rely on the vtable being defined el...
uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *rd, BaseSubobject base)
Return the index in the VTT where the virtual pointer for the given subobject is located.
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
SourceLocation getBeginLoc() const LLVM_READONLY
VarDecl * getExceptionDecl() const
bool isGlobalDelete() 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.
SourceRange getSourceRange() const
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
const CXXBaseSpecifier * base_class_const_iterator
Iterator that traverses the base classes of a class.
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
bool hasDefinition() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
const Expr * getSubExpr() const
static CanQual< Type > CreateUnsafe(QualType Other)
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.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
GlobalDecl - represents a global declaration.
GlobalDecl getWithCtorType(CXXCtorType Type)
CXXCtorType getCtorType() const
GlobalDecl getWithDtorType(CXXDtorType Type)
CXXDtorType getDtorType() const
const Decl * getDecl() const
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
uint64_t getMethodVTableIndex(GlobalDecl GD)
Locate a virtual function in the vtable.
bool isRelativeLayout() const
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)
Return the offset in chars (relative to the vtable address point) where the offset of the virtual bas...
virtual void mangleCXXRTTI(QualType T, raw_ostream &)=0
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getCanonicalType() const
Encodes a location in the source.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool hasConstructorVariants() const
Does this ABI have different entrypoints for complete-object and base-subobject constructors?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
virtual bool hasPS4DLLImportExport() const
uint64_t getPointerAlign(LangAS AddrSpace) const
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
unsigned getLongWidth() const
getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' for this target,...
SourceLocation getBeginLoc() const LLVM_READONLY
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
CXXRecordDecl * castAsCXXRecordDecl() const
Visibility getVisibility() const
Determine the visibility of this type.
Linkage getLinkage() const
Determine the linkage of this type.
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs'.
AddressPointLocation getAddressPoint(BaseSubobject Base) const
Represents a variable declaration or definition.
TLSKind getTLSKind() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed?
static bool isLocalLinkage(GlobalLinkageKind linkage)
static bool isValidLinkage(GlobalLinkageKind gl)
static bool isWeakForLinker(GlobalLinkageKind linkage)
Whether the definition of this global may be replaced at link time.
static bool isDiscardableIfUnused(GlobalLinkageKind linkage)
Whether the definition of this global may be discarded if it is not used in its compilation unit.
CIRGenCXXABI * CreateCIRGenItaniumCXXABI(CIRGenModule &cgm)
Creates and Itanium-family ABI.
Definition CIRGenItaniumCXXABI.cpp:1689
llvm::Value * getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating)
const internal::VariadicDynCastAllOfMatcher< Stmt, CallExpr > callExpr
Matches call expressions.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
constexpr Variable var(Literal L)
Returns the variable of L.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
RangeSelector name(std::string ID)
Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...
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)
@ VisibleNone
No linkage according to the standard, but is visible from other translation units because of types de...
@ None
No linkage, which means that the entity is unique and can only be referred to from within its scope.
@ UniqueExternal
External linkage within a unique namespace.
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ External
External linkage, which indicates that the entity can be referred to from other translation units.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
CXXDtorType
C++ destructor types.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
@ Type
The name was classified as a type.
U cast(CodeGen::Address addr)
@ DefaultVisibility
Objects with "default" visibility are seen by the dynamic linker and act like normal objects.
static bool addressSpace()
static bool opGlobalUnnamedAddr()
static bool vtableEmitMetadata()
static bool emitTypeMetadataCodeForVCall()
static bool opFuncReadOnly()
static bool setDLLStorageClass()
static bool hiddenVisibility()
static bool opFuncNoUnwind()
static bool cxxabiAppleARM64CXXABI()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool isTrivialCtorOrDtor()
static bool opFuncCallingConv()
static bool opFuncWillReturn()
static bool protectedVisibility()
static bool deferredVtables()
static bool cxxabiUseARMGuardVarABI()
static bool cxxabiUseARMMethodPtrABI()
static bool setDSOLocal()
static bool vtableRelativeLayout()
const clang::CXXRecordDecl * nearestVBase
clang::CharUnits getPointerAlign() const
clang::CharUnits getSizeSize() const
cir::PointerType uInt8PtrTy
Represents an element in a path from a derived class to a base class.
unsigned AddressPointIndex