diff options
author | Andy Kaylor <akaylor@nvidia.com> | 2025-06-10 16:50:29 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-10 16:50:29 -0700 |
commit | b9329fe88e47741d9c20ab92f892ac52457e6195 (patch) | |
tree | 8b8b4159cda241363fd60898a1fab1d1440a5144 /clang/lib/CIR/CodeGen/CIRGenModule.cpp | |
parent | ad479ddb343c2756e6eed0f2999bbdb88a65c7c5 (diff) | |
download | llvm-b9329fe88e47741d9c20ab92f892ac52457e6195.zip llvm-b9329fe88e47741d9c20ab92f892ac52457e6195.tar.gz llvm-b9329fe88e47741d9c20ab92f892ac52457e6195.tar.bz2 |
[CIR] Upstream support for calling constructors (#143579)
This change adds support for calling C++ constructors. The support for
actually defining a constructor is still missing and will be added in a
later change.
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenModule.cpp')
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenModule.cpp | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 3d46c44..8407f8f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -103,6 +103,25 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext, CIRGenModule::~CIRGenModule() = default; +/// FIXME: this could likely be a common helper and not necessarily related +/// with codegen. +/// Return the best known alignment for an unknown pointer to a +/// particular class. +CharUnits CIRGenModule::getClassPointerAlignment(const CXXRecordDecl *rd) { + if (!rd->hasDefinition()) + return CharUnits::One(); // Hopefully won't be used anywhere. + + auto &layout = astContext.getASTRecordLayout(rd); + + // If the class is final, then we know that the pointer points to an + // object of that type and can use the full alignment. + if (rd->isEffectivelyFinal()) + return layout.getAlignment(); + + // Otherwise, we have to assume it could be a subclass. + return layout.getNonVirtualAlignment(); +} + CharUnits CIRGenModule::getNaturalTypeAlignment(QualType t, LValueBaseInfo *baseInfo) { assert(!cir::MissingFeatures::opTBAA()); @@ -1174,6 +1193,34 @@ void CIRGenModule::setInitializer(cir::GlobalOp &op, mlir::Attribute value) { assert(!cir::MissingFeatures::opGlobalVisibility()); } +std::pair<cir::FuncType, cir::FuncOp> CIRGenModule::getAddrAndTypeOfCXXStructor( + GlobalDecl gd, const CIRGenFunctionInfo *fnInfo, cir::FuncType fnType, + bool dontDefer, ForDefinition_t isForDefinition) { + auto *md = cast<CXXMethodDecl>(gd.getDecl()); + + if (isa<CXXDestructorDecl>(md)) { + // Always alias equivalent complete destructors to base destructors in the + // MS ABI. + if (getTarget().getCXXABI().isMicrosoft() && + gd.getDtorType() == Dtor_Complete && + md->getParent()->getNumVBases() == 0) + errorNYI(md->getSourceRange(), + "getAddrAndTypeOfCXXStructor: MS ABI complete destructor"); + } + + if (!fnType) { + if (!fnInfo) + fnInfo = &getTypes().arrangeCXXStructorDeclaration(gd); + fnType = getTypes().getFunctionType(*fnInfo); + } + + auto fn = getOrCreateCIRFunction(getMangledName(gd), fnType, gd, + /*ForVtable=*/false, dontDefer, + /*IsThunk=*/false, isForDefinition); + + return {fnType, fn}; +} + cir::FuncOp CIRGenModule::getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType, bool forVTable, bool dontDefer, @@ -1248,8 +1295,11 @@ StringRef CIRGenModule::getMangledName(GlobalDecl gd) { // Some ABIs don't have constructor variants. Make sure that base and complete // constructors get mangled the same. if (const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.getDecl())) { - errorNYI(cd->getSourceRange(), "getMangledName: C++ constructor"); - return cast<NamedDecl>(gd.getDecl())->getIdentifier()->getName(); + if (!getTarget().getCXXABI().hasConstructorVariants()) { + errorNYI(cd->getSourceRange(), + "getMangledName: C++ constructor without variants"); + return cast<NamedDecl>(gd.getDecl())->getIdentifier()->getName(); + } } // Keep the first result in the case of a mangling collision. |