Skip to content

[CIR] Implement SizedTypeInterface to make isSized hookable #146045

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 27, 2025

Conversation

xlauko
Copy link
Contributor

@xlauko xlauko commented Jun 27, 2025

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 llvm/clangir#1714

@xlauko
Copy link
Contributor Author

xlauko commented Jun 27, 2025

@xlauko xlauko requested review from andykaylor and erichkeane June 27, 2025 09:27
@xlauko xlauko marked this pull request as ready for review June 27, 2025 09:27
@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Jun 27, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 27, 2025

@llvm/pr-subscribers-clangir

@llvm/pr-subscribers-clang

Author: Henrich Lauko (xlauko)

Changes

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 llvm/clangir#1714


Full diff: https://github.com/llvm/llvm-project/pull/146045.diff

6 Files Affected:

  • (modified) clang/include/clang/CIR/Dialect/IR/CIRTypes.h (+9)
  • (modified) clang/include/clang/CIR/Dialect/IR/CIRTypes.td (+46-27)
  • (modified) clang/include/clang/CIR/Interfaces/CIRTypeInterfaces.td (+25)
  • (modified) clang/lib/CIR/CodeGen/CIRGenBuilder.h (-12)
  • (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+2-2)
  • (modified) clang/lib/CIR/Dialect/IR/CIRTypes.cpp (+10)
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
 //===----------------------------------------------------------------------===//

@xlauko
Copy link
Contributor Author

xlauko commented Jun 27, 2025

Merge activity

  • Jun 27, 2:37 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 27, 2:48 PM UTC: Graphite rebased this pull request as part of a merge.
  • Jun 27, 2:50 PM UTC: @xlauko merged this pull request with Graphite.

@xlauko xlauko force-pushed the users/xlauko/cir-cleanup-type-interfaces branch 3 times, most recently from 7d2e8b3 to a56f531 Compare June 27, 2025 14:45
Base automatically changed from users/xlauko/cir-cleanup-type-interfaces to main June 27, 2025 14:48
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 llvm/clangir#1714
@xlauko xlauko force-pushed the users/xlauko/cir-sized-type-interface branch from 586f2cc to 1f65dd5 Compare June 27, 2025 14:48
@xlauko xlauko merged commit 07f1502 into main Jun 27, 2025
5 of 7 checks passed
@xlauko xlauko deleted the users/xlauko/cir-sized-type-interface branch June 27, 2025 14:50
rlavaee pushed a commit to rlavaee/llvm-project that referenced this pull request Jul 1, 2025
)

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 llvm/clangir#1714
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants