Author: Henrich Lauko Date: 2025-06-27T16:50:01+02:00 New Revision: 07f1502b867e85b0b67a54664e57b71dcb37f1cb
URL: https://github.com/llvm/llvm-project/commit/07f1502b867e85b0b67a54664e57b71dcb37f1cb DIFF: https://github.com/llvm/llvm-project/commit/07f1502b867e85b0b67a54664e57b71dcb37f1cb.diff LOG: [CIR] Implement SizedTypeInterface to make isSized hookable (#146045) Resolves issues pointed out in https://github.com/llvm/llvm-project/pull/143960/files#r2164047625 of needing to update sized list of types on each new type. This mirrors incubator changes from https://github.com/llvm/clangir/pull/1714 Added: Modified: clang/include/clang/CIR/Dialect/IR/CIRTypes.h clang/include/clang/CIR/Dialect/IR/CIRTypes.td clang/include/clang/CIR/Interfaces/CIRTypeInterfaces.td clang/lib/CIR/CodeGen/CIRGenBuilder.h clang/lib/CIR/CodeGen/CIRGenTypes.cpp clang/lib/CIR/Dialect/IR/CIRTypes.cpp Removed: ################################################################################ diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index 620c72ef9023e..7f9fb9ef388b3 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -26,6 +26,15 @@ struct RecordTypeStorage; bool isValidFundamentalIntWidth(unsigned width); +/// Returns true if the type is a CIR sized type. +/// +/// Types are sized if they implement SizedTypeInterface and +/// return true from its method isSized. +/// +/// Unsized types are those that do not have a size, such as +/// void, or abstract types. +bool isSized(mlir::Type ty); + } // namespace cir //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index 75c42a08c185f..bfe42562abad7 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -33,8 +33,10 @@ class CIR_Type<string name, string typeMnemonic, list<Trait> traits = [], // IntType //===----------------------------------------------------------------------===// -def CIR_IntType : CIR_Type<"Int", "int", - [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> { +def CIR_IntType : CIR_Type<"Int", "int", [ + DeclareTypeInterfaceMethods<DataLayoutTypeInterface>, + DeclareTypeInterfaceMethods<CIR_SizedTypeInterface> +]> { let summary = "Integer type with arbitrary precision up to a fixed limit"; let description = [{ CIR type that represents integer types with arbitrary precision, including @@ -82,7 +84,8 @@ def CIR_IntType : CIR_Type<"Int", "int", class CIR_FloatType<string name, string mnemonic> : CIR_Type<name, mnemonic, [ DeclareTypeInterfaceMethods<DataLayoutTypeInterface>, - DeclareTypeInterfaceMethods<CIR_FPTypeInterface> + DeclareTypeInterfaceMethods<CIR_FPTypeInterface>, + DeclareTypeInterfaceMethods<CIR_SizedTypeInterface> ]>; def CIR_Single : CIR_FloatType<"Single", "float"> { @@ -165,9 +168,10 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> { // ComplexType //===----------------------------------------------------------------------===// -def CIR_ComplexType : CIR_Type<"Complex", "complex", - [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> { - +def CIR_ComplexType : CIR_Type<"Complex", "complex", [ + DeclareTypeInterfaceMethods<DataLayoutTypeInterface>, + DeclareTypeInterfaceMethods<CIR_SizedTypeInterface> +]> { let summary = "CIR complex type"; let description = [{ CIR type that represents a C complex number. `cir.complex` models the C type @@ -215,12 +219,13 @@ def CIR_ComplexType : CIR_Type<"Complex", "complex", // PointerType //===----------------------------------------------------------------------===// -def CIR_PointerType : CIR_Type<"Pointer", "ptr", - [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> { - +def CIR_PointerType : CIR_Type<"Pointer", "ptr", [ + DeclareTypeInterfaceMethods<DataLayoutTypeInterface>, + DeclareTypeInterfaceMethods<CIR_SizedTypeInterface> +]> { let summary = "CIR pointer type"; let description = [{ - The `cir.ptr` type represents C and C++ pointer types and C++ reference + The `!cir.ptr` type represents C and C++ pointer types and C++ reference types, other than pointers-to-members. The `pointee` type is the type pointed to. @@ -279,13 +284,13 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr", // BoolType //===----------------------------------------------------------------------===// -def CIR_BoolType : - CIR_Type<"Bool", "bool", - [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> { - +def CIR_BoolType : CIR_Type<"Bool", "bool", [ + DeclareTypeInterfaceMethods<DataLayoutTypeInterface>, + DeclareTypeInterfaceMethods<CIR_SizedTypeInterface> +]> { let summary = "CIR bool type"; let description = [{ - `cir.bool` represents C++ bool type. + `!cir.bool` represents C++ bool type. }]; } @@ -293,12 +298,13 @@ def CIR_BoolType : // ArrayType //===----------------------------------------------------------------------===// -def CIR_ArrayType : CIR_Type<"Array", "array", - [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> { - +def CIR_ArrayType : CIR_Type<"Array", "array", [ + DeclareTypeInterfaceMethods<DataLayoutTypeInterface>, + DeclareTypeInterfaceMethods<CIR_SizedTypeInterface, ["isSized"]>, +]> { let summary = "CIR array type"; let description = [{ - `CIR.array` represents C/C++ constant arrays. + `!cir.array` represents C/C++ constant arrays. }]; let parameters = (ins "mlir::Type":$elementType, "uint64_t":$size); @@ -314,15 +320,22 @@ def CIR_ArrayType : CIR_Type<"Array", "array", let assemblyFormat = [{ `<` $elementType `x` $size `>` }]; + + let extraClassDefinition = [{ + bool $cppClass::isSized() const { + return ::cir::isSized(getElementType()); + } + }]; } //===----------------------------------------------------------------------===// // VectorType (fixed size) //===----------------------------------------------------------------------===// -def CIR_VectorType : CIR_Type<"Vector", "vector", - [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> { - +def CIR_VectorType : CIR_Type<"Vector", "vector", [ + DeclareTypeInterfaceMethods<DataLayoutTypeInterface>, + DeclareTypeInterfaceMethods<CIR_SizedTypeInterface, ["isSized"]>, +]> { let summary = "CIR vector type"; let description = [{ The `!cir.vector` type represents a fixed-size, one-dimensional vector. @@ -363,6 +376,12 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", }]>, ]; + let extraClassDefinition = [{ + bool $cppClass::isSized() const { + return ::cir::isSized(getElementType()); + } + }]; + let genVerifyDecl = 1; } @@ -459,11 +478,11 @@ def CIR_VoidType : CIR_Type<"Void", "void"> { // The base type for all RecordDecls. //===----------------------------------------------------------------------===// -def CIR_RecordType : CIR_Type<"Record", "record", - [ - DeclareTypeInterfaceMethods<DataLayoutTypeInterface>, - MutableType, - ]> { +def CIR_RecordType : CIR_Type<"Record", "record", [ + DeclareTypeInterfaceMethods<DataLayoutTypeInterface>, + DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>, + MutableType, +]> { let summary = "CIR record type"; let description = [{ Each unique clang::RecordDecl is mapped to a `cir.record` and any object in diff --git a/clang/include/clang/CIR/Interfaces/CIRTypeInterfaces.td b/clang/include/clang/CIR/Interfaces/CIRTypeInterfaces.td index 84147478f8030..1b1acf749e773 100644 --- a/clang/include/clang/CIR/Interfaces/CIRTypeInterfaces.td +++ b/clang/include/clang/CIR/Interfaces/CIRTypeInterfaces.td @@ -53,4 +53,29 @@ def CIR_FPTypeInterface : TypeInterface<"FPTypeInterface"> { ]; } +def CIR_SizedTypeInterface : TypeInterface<"SizedTypeInterface"> { + let description = [{ + Annotates types that have known size. Types that don't have a size are + abstract types and void. + }]; + let cppNamespace = "::cir"; + let methods = [ + InterfaceMethod<[{ + Returns true if this is a sized type. This mirrors sizedness from the + clang AST, where a type is sized if it has a known size. + By default type defining this interface returns true, + but this can be overridden if sizedness depends on properties of the type. + For example, whether a struct is not sized if it is incomplete. + }], + /*retTy=*/"bool", + /*methodName=*/"isSized", + /*args=*/(ins), + /*methodBody=*/"", + /*defaultImplementation=*/[{ + return true; + }] + >, + ]; +} + #endif // CLANG_CIR_INTERFACES_CIRTYPEINTERFACES_TD diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index e316c39b98919..17b931a0693aa 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -139,18 +139,6 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy { return getType<cir::RecordType>(nameAttr, kind); } - bool isSized(mlir::Type ty) { - if (mlir::isa<cir::PointerType, cir::ArrayType, cir::BoolType, cir::IntType, - cir::FPTypeInterface, cir::ComplexType, cir::RecordType>(ty)) - return true; - - if (const auto vt = mlir::dyn_cast<cir::VectorType>(ty)) - return isSized(vt.getElementType()); - - assert(!cir::MissingFeatures::unsizedTypes()); - return false; - } - // Return true if the value is a null constant such as null pointer, (+0.0) // for floating-point or zero initializer bool isNullValue(mlir::Attribute attr) const { diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index 621eb66962bfb..3e07f6d3e54cc 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -424,7 +424,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) { mlir::Type elemTy = convertTypeForMem(arrTy->getElementType()); // int X[] -> [0 x int], unless the element type is not sized. If it is // unsized (e.g. an incomplete record) just use [0 x i8]. - if (!builder.isSized(elemTy)) { + if (!cir::isSized(elemTy)) { elemTy = cgm.SInt8Ty; } @@ -438,7 +438,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) { // TODO(CIR): In LLVM, "lower arrays of undefined struct type to arrays of // i8 just to have a concrete type" - if (!builder.isSized(elemTy)) { + if (!cir::isSized(elemTy)) { cgm.errorNYI(SourceLocation(), "arrays of undefined struct type", type); resultType = cgm.UInt32Ty; break; diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp index 1db5a9728fdb9..c6760cf1618cb 100644 --- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp @@ -18,6 +18,16 @@ #include "clang/CIR/MissingFeatures.h" #include "llvm/ADT/TypeSwitch.h" +//===----------------------------------------------------------------------===// +// CIR Helpers +//===----------------------------------------------------------------------===// +bool cir::isSized(mlir::Type ty) { + if (auto sizedTy = mlir::dyn_cast<cir::SizedTypeInterface>(ty)) + return sizedTy.isSized(); + assert(!cir::MissingFeatures::unsizedTypes()); + return false; +} + //===----------------------------------------------------------------------===// // CIR Custom Parser/Printer Signatures //===----------------------------------------------------------------------===// _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits