From b5ba28c269fbe2cc83a2c02ad6e4d7d2fdb2e143 Mon Sep 17 00:00:00 2001 From: Chen Steenvoorden Date: Wed, 3 Jun 2026 15:32:03 +0200 Subject: [PATCH 1/4] Rename GetClassTypeInfoType to GetTypeInfoType --- clang/lib/CodeGen/CGVTables.cpp | 8 ++++---- clang/lib/CodeGen/CodeGenTypes.h | 2 +- clang/lib/CodeGen/ItaniumCXXABI.cpp | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 3ba4bbc7b0d4..cbced2f97629 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -849,7 +849,7 @@ void CodeGenVTables::addVTableComponent(ConstantAggregateBuilderBase &builder, vtableHasLocalLinkage, /*isCompleteDtor=*/false); else - return builder.add(llvm::ConstantExpr::getBitCast(rtti, CGM.getTarget().isByteAddressable() ? CGM.Int8PtrTy : CGM.getTypes().GetClassTypeInfoType()->getPointerTo())); + return builder.add(llvm::ConstantExpr::getBitCast(rtti, CGM.getTarget().isByteAddressable() ? CGM.Int8PtrTy : CGM.getTypes().GetTypeInfoType()->getPointerTo())); case VTableComponent::CK_FunctionPointer: case VTableComponent::CK_CompleteDtorPointer: @@ -1530,7 +1530,7 @@ llvm::Type* CodeGenTypes::GetVTableSubObjectType(CodeGenModule& CGM, VTableTypes.push_back(OffsetTy); break; case VTableComponent::CK_RTTI: - VTableTypes.push_back(CGM.getTypes().GetClassTypeInfoType()->getPointerTo()); + VTableTypes.push_back(CGM.getTypes().GetTypeInfoType()->getPointerTo()); break; case VTableComponent::CK_FunctionPointer: case VTableComponent::CK_CompleteDtorPointer: @@ -1581,7 +1581,7 @@ llvm::Type* CodeGenTypes::GetBasicVTableType(uint32_t virtualMethodsCount, bool } // RTTI - VTableTypes.push_back(GetClassTypeInfoType()->getPointerTo()); + VTableTypes.push_back(GetTypeInfoType()->getPointerTo()); // Virtual functions for(uint32_t j=0;j(GetVTableBaseType(asmjs)), /*isByteLayout*/false, asmjs); } -llvm::Type* CodeGenTypes::GetClassTypeInfoType() +llvm::Type* CodeGenTypes::GetTypeInfoType() { llvm::Type* ResultType = llvm::StructType::getTypeByName(CGM.getLLVMContext(), "class._ZSt9type_info"); if(!ResultType) diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index 2760cf718a38..b5d53e25b726 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -168,7 +168,7 @@ class CodeGenTypes { uint32_t extraOffsets, bool asmjs); - llvm::Type* GetClassTypeInfoType(); + llvm::Type* GetTypeInfoType(); const CGRecordLayout &getCGRecordLayout(const RecordDecl*); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 5431facceafd..6a4df3304461 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1494,7 +1494,7 @@ static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF, bool a llvm::FunctionType *FTy = NULL; llvm::StringRef FName; if(!CGF.getTarget().isByteAddressable()) { - llvm::Type* classTypeInfoPtr = CGF.getTypes().GetClassTypeInfoType()->getPointerTo(); + llvm::Type* classTypeInfoPtr = CGF.getTypes().GetTypeInfoType()->getPointerTo(); llvm::Type *Args[5] = { PtrDiffTy, CGF.getTypes().GetVTableBaseType(asmjs)->getPointerTo(), classTypeInfoPtr, classTypeInfoPtr, PtrDiffTy }; FTy = llvm::FunctionType::get(PtrDiffTy, Args, false); FName = asmjs? "__dynamic_cast_asmjs" : "__dynamic_cast_genericjs"; @@ -3589,7 +3589,7 @@ ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) { } } - return llvm::ConstantExpr::getBitCast(GV, CGM.getTarget().isByteAddressable() ? CGM.Int8PtrTy : CGM.getTypes().GetClassTypeInfoType()->getPointerTo()); + return llvm::ConstantExpr::getBitCast(GV, CGM.getTarget().isByteAddressable() ? CGM.Int8PtrTy : CGM.getTypes().GetTypeInfoType()->getPointerTo()); } /// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type @@ -4072,7 +4072,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty) { assert(!OldGV->hasAvailableExternallyLinkage() && "available_externally typeinfos not yet implemented"); - return llvm::ConstantExpr::getBitCast(OldGV, CGM.getTarget().isByteAddressable() ? CGM.Int8PtrTy : CGM.getTypes().GetClassTypeInfoType()->getPointerTo()); + return llvm::ConstantExpr::getBitCast(OldGV, CGM.getTarget().isByteAddressable() ? CGM.Int8PtrTy : CGM.getTypes().GetTypeInfoType()->getPointerTo()); } // Check if there is already an external RTTI descriptor for this type. @@ -4233,7 +4233,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( break; } - llvm::Type* directBase = CGM.getTarget().isByteAddressable() ? NULL : CGM.getTypes().GetClassTypeInfoType(); + llvm::Type* directBase = CGM.getTarget().isByteAddressable() ? NULL : CGM.getTypes().GetTypeInfoType(); llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields, false, directBase ? cast(directBase) : NULL, asmjs); SmallString<256> Name; @@ -4307,7 +4307,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( TypeName->setPartition(CGM.getCodeGenOpts().SymbolPartition); GV->setPartition(CGM.getCodeGenOpts().SymbolPartition); - return llvm::ConstantExpr::getBitCast(GV, CGM.getTarget().isByteAddressable() ? CGM.Int8PtrTy : CGM.getTypes().GetClassTypeInfoType()->getPointerTo()); + return llvm::ConstantExpr::getBitCast(GV, CGM.getTarget().isByteAddressable() ? CGM.Int8PtrTy : CGM.getTypes().GetTypeInfoType()->getPointerTo()); } /// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info From 9a9d8fbc1be04fc2933e7ced0dc5c3b05f9a0e1f Mon Sep 17 00:00:00 2001 From: Chen Steenvoorden Date: Wed, 3 Jun 2026 15:37:25 +0200 Subject: [PATCH 2/4] Change return type of GetTypeInfoType to StructType --- clang/lib/CodeGen/CGVTables.cpp | 4 ++-- clang/lib/CodeGen/CodeGenTypes.h | 2 +- clang/lib/CodeGen/ItaniumCXXABI.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index cbced2f97629..4595be500014 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -1590,9 +1590,9 @@ llvm::Type* CodeGenTypes::GetBasicVTableType(uint32_t virtualMethodsCount, bool return llvm::StructType::get(getLLVMContext(), VTableTypes, false, cast(GetVTableBaseType(asmjs)), /*isByteLayout*/false, asmjs); } -llvm::Type* CodeGenTypes::GetTypeInfoType() +llvm::StructType* CodeGenTypes::GetTypeInfoType() { - llvm::Type* ResultType = llvm::StructType::getTypeByName(CGM.getLLVMContext(), "class._ZSt9type_info"); + llvm::StructType* ResultType = llvm::StructType::getTypeByName(CGM.getLLVMContext(), "class._ZSt9type_info"); if(!ResultType) ResultType = llvm::StructType::create(CGM.getLLVMContext(),"class._ZSt9type_info"); return ResultType; diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index b5d53e25b726..39aecd5721cf 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -168,7 +168,7 @@ class CodeGenTypes { uint32_t extraOffsets, bool asmjs); - llvm::Type* GetTypeInfoType(); + llvm::StructType* GetTypeInfoType(); const CGRecordLayout &getCGRecordLayout(const RecordDecl*); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 6a4df3304461..655ac06d3c54 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -4233,8 +4233,8 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( break; } - llvm::Type* directBase = CGM.getTarget().isByteAddressable() ? NULL : CGM.getTypes().GetTypeInfoType(); - llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields, false, directBase ? cast(directBase) : NULL, asmjs); + llvm::StructType* directBase = CGM.getTarget().isByteAddressable() ? NULL : CGM.getTypes().GetTypeInfoType(); + llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields, false, directBase ? directBase : NULL, asmjs); SmallString<256> Name; llvm::raw_svector_ostream Out(Name); From 1812f5ea23fd3a20bf3be5f3f148cd2fda0fb250 Mon Sep 17 00:00:00 2001 From: Chen Steenvoorden Date: Wed, 3 Jun 2026 15:52:40 +0200 Subject: [PATCH 3/4] CodeGen: Fixed type info types --- clang/lib/CodeGen/CGVTables.cpp | 42 ++++++++++++++++++++++++++--- clang/lib/CodeGen/CodeGenTypes.h | 6 +++++ clang/lib/CodeGen/ItaniumCXXABI.cpp | 21 ++++++++++----- 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 4595be500014..b4ad8879f4fd 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -1590,10 +1590,44 @@ llvm::Type* CodeGenTypes::GetBasicVTableType(uint32_t virtualMethodsCount, bool return llvm::StructType::get(getLLVMContext(), VTableTypes, false, cast(GetVTableBaseType(asmjs)), /*isByteLayout*/false, asmjs); } +static llvm::StructType* GetOrCreateStructType(llvm::LLVMContext& Context, StringRef Name) +{ + if (llvm::StructType* Result = llvm::StructType::getTypeByName(Context, Name)) + return Result; + return llvm::StructType::create(Context, Name); +} + llvm::StructType* CodeGenTypes::GetTypeInfoType() { - llvm::StructType* ResultType = llvm::StructType::getTypeByName(CGM.getLLVMContext(), "class._ZSt9type_info"); - if(!ResultType) - ResultType = llvm::StructType::create(CGM.getLLVMContext(),"class._ZSt9type_info"); - return ResultType; + return GetOrCreateStructType(CGM.getLLVMContext(), "class._ZSt9type_info"); +} + +llvm::StructType* CodeGenTypes::GetClassTypeInfoType() +{ + return GetOrCreateStructType(CGM.getLLVMContext(), "class._ZN10__cxxabiv117__class_type_infoE"); +} + +llvm::StructType* CodeGenTypes::GetBaseClassTypeInfoType() +{ + return GetOrCreateStructType(CGM.getLLVMContext(), "struct._ZN10__cxxabiv122__base_class_type_infoE"); +} + +llvm::StructType* CodeGenTypes::GetSIClassTypeInfoType() +{ + return GetOrCreateStructType(CGM.getLLVMContext(), "class._ZN10__cxxabiv120__si_class_type_infoE"); +} + +llvm::StructType* CodeGenTypes::GetVMIClassTypeInfoType() +{ + return GetOrCreateStructType(CGM.getLLVMContext(), "class._ZN10__cxxabiv121__vmi_class_type_infoE"); +} + +llvm::StructType* CodeGenTypes::GetPointerTypeInfoType() +{ + return GetOrCreateStructType(CGM.getLLVMContext(), "class._ZN10__cxxabiv119__pointer_type_infoE"); +} + +llvm::StructType* CodeGenTypes::GetPointerToMemberTypeInfoType() +{ + return GetOrCreateStructType(CGM.getLLVMContext(), "class._ZN10__cxxabiv129__pointer_to_member_type_infoE"); } diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index 39aecd5721cf..347bb1330c82 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -169,6 +169,12 @@ class CodeGenTypes { bool asmjs); llvm::StructType* GetTypeInfoType(); + llvm::StructType* GetClassTypeInfoType(); + llvm::StructType* GetBaseClassTypeInfoType(); + llvm::StructType* GetSIClassTypeInfoType(); + llvm::StructType* GetVMIClassTypeInfoType(); + llvm::StructType* GetPointerTypeInfoType(); + llvm::StructType* GetPointerToMemberTypeInfoType(); const CGRecordLayout &getCGRecordLayout(const RecordDecl*); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 655ac06d3c54..313ee2628609 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -4142,6 +4142,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( // CHEERP: for the cheerp-wasm target, we put the RTTI in the asmjs section bool asmjs = CGM.getContext().getTargetInfo().getTriple().isCheerpWasm(); + llvm::StructType *TypeInfoType = CGM.getTypes().GetTypeInfoType(); switch (Ty->getTypeClass()) { #define TYPE(Class, Base) @@ -4203,10 +4204,13 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( break; } - if (CanUseSingleInheritance(RD)) + if (CanUseSingleInheritance(RD)) { BuildSIClassTypeInfo(RD); - else + TypeInfoType = CGM.getTypes().GetSIClassTypeInfoType(); + } else { BuildVMIClassTypeInfo(RD); + TypeInfoType = CGM.getTypes().GetVMIClassTypeInfoType(); + } break; } @@ -4218,14 +4222,17 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( case Type::ObjCObjectPointer: BuildPointerTypeInfo(cast(Ty)->getPointeeType()); + TypeInfoType = CGM.getTypes().GetPointerTypeInfoType(); break; case Type::Pointer: BuildPointerTypeInfo(cast(Ty)->getPointeeType()); + TypeInfoType = CGM.getTypes().GetPointerTypeInfoType(); break; case Type::MemberPointer: BuildPointerToMemberTypeInfo(cast(Ty)); + TypeInfoType = CGM.getTypes().GetPointerToMemberTypeInfoType(); break; case Type::Atomic: @@ -4233,7 +4240,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( break; } - llvm::StructType* directBase = CGM.getTarget().isByteAddressable() ? NULL : CGM.getTypes().GetTypeInfoType(); + llvm::StructType* directBase = CGM.getTarget().isByteAddressable() ? NULL : TypeInfoType; llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields, false, directBase ? directBase : NULL, asmjs); SmallString<256> Name; @@ -4475,7 +4482,7 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { for (const auto &Base : RD->bases()) { llvm::SmallVector baseFields; // The __base_type member points to the RTTI for the base type. - baseFields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType())); + baseFields.push_back(llvm::ConstantExpr::getBitCast(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType()), CGM.getTypes().GetClassTypeInfoType()->getPointerTo())); auto *BaseDecl = cast(Base.getType()->castAs()->getDecl()); @@ -4508,7 +4515,7 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { OffsetFlags |= BCTI_Public; baseFields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags)); - basesFields.push_back(llvm::ConstantStruct::getAnon(baseFields, false, NULL, asmjs)); + basesFields.push_back(llvm::ConstantStruct::get(CGM.getTypes().GetBaseClassTypeInfoType(), baseFields)); } if(!CGM.getTarget().isByteAddressable()) { typedef std::pair RdUnsignedPair; @@ -4528,7 +4535,7 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { llvm::SmallVector baseFields; // The __base_type member points to the RTTI for the base type. QualType VBaseTy = CGM.getContext().getCanonicalType(CGM.getContext().getTagDeclType(pair.first)); - baseFields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(VBaseTy)); + baseFields.push_back(llvm::ConstantExpr::getBitCast(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(VBaseTy), CGM.getTypes().GetClassTypeInfoType()->getPointerTo())); unsigned Offset = 0; if (asmjs) Offset = Layout.getVBaseClassOffset(pair.first).getQuantity(); @@ -4536,7 +4543,7 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { Offset = CGLayout.getTotalOffsetToBase(pair.second); baseFields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, Offset)); - basesFields.push_back(llvm::ConstantStruct::getAnon(baseFields, false, NULL, asmjs)); + basesFields.push_back(llvm::ConstantStruct::get(CGM.getTypes().GetBaseClassTypeInfoType(), baseFields)); } } llvm::ArrayType* basesArrayType = llvm::ArrayType::get(basesFields[0]->getType(), basesFields.size()); From 90b0fecc617225b3a1c7aa67519f96ccbe79616b Mon Sep 17 00:00:00 2001 From: Chen Steenvoorden Date: Tue, 9 Jun 2026 16:55:44 +0200 Subject: [PATCH 4/4] fixup! CodeGen: Fixed type info types --- clang/lib/CodeGen/ItaniumCXXABI.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 313ee2628609..06638f6873d8 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -4515,7 +4515,7 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { OffsetFlags |= BCTI_Public; baseFields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags)); - basesFields.push_back(llvm::ConstantStruct::get(CGM.getTypes().GetBaseClassTypeInfoType(), baseFields)); + basesFields.push_back(llvm::ConstantStruct::getAnon(baseFields, false, CGM.getTypes().GetBaseClassTypeInfoType(), asmjs)); } if(!CGM.getTarget().isByteAddressable()) { typedef std::pair RdUnsignedPair; @@ -4543,7 +4543,7 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { Offset = CGLayout.getTotalOffsetToBase(pair.second); baseFields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, Offset)); - basesFields.push_back(llvm::ConstantStruct::get(CGM.getTypes().GetBaseClassTypeInfoType(), baseFields)); + basesFields.push_back(llvm::ConstantStruct::getAnon(baseFields, false, CGM.getTypes().GetBaseClassTypeInfoType(), asmjs)); } } llvm::ArrayType* basesArrayType = llvm::ArrayType::get(basesFields[0]->getType(), basesFields.size());