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

Reply via email to