https://github.com/AmrDeveloper updated 
https://github.com/llvm/llvm-project/pull/159426

>From 120397488168606f961e05235c2c5fa8a85cd59a Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Wed, 17 Sep 2025 21:02:56 +0200
Subject: [PATCH 1/3] [CIR] Upstream TypeInfo attribute

---
 .../include/clang/CIR/Dialect/IR/CIRAttrs.td  | 48 +++++++++++++++++++
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp       | 23 ++++++++-
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 15 ++++++
 clang/test/CIR/IR/invalid-type-info.cir       | 17 +++++++
 4 files changed, 101 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/CIR/IR/invalid-type-info.cir

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 16b818f851e1c..10afd7133eed3 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -779,4 +779,52 @@ def CIR_AddressPointAttr : CIR_Attr<"AddressPoint", 
"address_point"> {
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// TypeInfoAttr
+//===----------------------------------------------------------------------===//
+
+def CIR_TypeInfoAttr : CIR_Attr<"TypeInfo", "typeinfo", [TypedAttrInterface]> {
+  let summary = "Represents a typeinfo used for RTTI";
+  let description = [{
+    The typeinfo data for a given class is stored into an ArrayAttr. The
+    layout is determined by the C++ ABI used (clang only implements
+    itanium on CIRGen).
+
+    The verifier enforces that the output type is always a `!cir.record`,
+    and that the ArrayAttr element types match the equivalent member type
+    for the resulting record, i.e, a GlobalViewAttr for symbol reference or
+    an IntAttr for flags.
+
+    Example:
+
+    ```
+    cir.global "private" external @_ZTVN10__cxxabiv120__si_class_type_infoE : 
!cir.ptr<i32>
+
+    !rec_anon_struct = !cir.record<struct  {!cir.ptr<!u8i>, !cir.ptr<!u8i>, 
!cir.ptr<!u8i>}>
+
+    cir.global constant external @type_info = #cir.typeinfo<{
+      #cir.global_view<@_ZTVN10__cxxabiv120__si_class_type_infoE, [2 : i32]>
+      : !cir.ptr<!u8i>, #cir.global_view<@_ZTS1B> : !cir.ptr<!u8i>, 
#cir.global_view<@_ZTI1A>
+      : !cir.ptr<!u8i>}> : !rec_anon_struct
+    ```
+  }];
+
+  let parameters = (ins AttributeSelfTypeParameter<"">:$type,
+                        "mlir::ArrayAttr":$data);
+
+  let builders = [
+    AttrBuilderWithInferredContext<(ins "mlir::Type":$type,
+                                        "mlir::ArrayAttr":$data), [{
+      return $_get(type.getContext(), type, data);
+    }]>
+  ];
+
+  // Checks record element types should match the array for every equivalent
+  // element type.
+  let genVerifyDecl = 1;
+  let assemblyFormat = [{
+    `<` custom<RecordMembers>($data) `>`
+  }];
+}
+
 #endif // CLANG_CIR_DIALECT_IR_CIRATTRS_TD
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 8918eb4cbb1ad..3fcc0aad9b11b 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -342,8 +342,8 @@ static LogicalResult checkConstantTypes(mlir::Operation 
*op, mlir::Type opType,
 
   if (mlir::isa<cir::ConstArrayAttr, cir::ConstVectorAttr,
                 cir::ConstComplexAttr, cir::ConstRecordAttr,
-                cir::GlobalViewAttr, cir::PoisonAttr, cir::VTableAttr>(
-          attrType))
+                cir::GlobalViewAttr, cir::PoisonAttr, cir::TypeInfoAttr,
+                cir::VTableAttr>(attrType))
     return success();
 
   assert(isa<TypedAttr>(attrType) && "What else could we be looking at here?");
@@ -2741,6 +2741,25 @@ LogicalResult cir::AtomicCmpXchg::verify() {
   return success();
 }
 
+//===----------------------------------------------------------------------===//
+// TypeInfoAttr
+//===----------------------------------------------------------------------===//
+
+LogicalResult cir::TypeInfoAttr::verify(
+    ::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError,
+    ::mlir::Type type, ::mlir::ArrayAttr typeinfoData) {
+
+  if (cir::ConstRecordAttr::verify(emitError, type, typeinfoData).failed())
+    return failure();
+
+  for (auto &member : typeinfoData) {
+    if (llvm::isa<GlobalViewAttr, IntAttr>(member))
+      continue;
+    return emitError() << "expected GlobalViewAttr or IntAttr attribute";
+  }
+  return success();
+}
+
 
//===----------------------------------------------------------------------===//
 // TableGen'd op method definitions
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 1d7e3df1430ac..0c0c28a5cc379 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -235,6 +235,7 @@ class CIRAttrToValue {
   mlir::Value visitCirAttr(cir::ConstRecordAttr attr);
   mlir::Value visitCirAttr(cir::ConstVectorAttr attr);
   mlir::Value visitCirAttr(cir::GlobalViewAttr attr);
+  mlir::Value visitCirAttr(cir::TypeInfoAttr attr);
   mlir::Value visitCirAttr(cir::VTableAttr attr);
   mlir::Value visitCirAttr(cir::ZeroAttr attr);
 
@@ -521,6 +522,20 @@ mlir::Value 
CIRAttrToValue::visitCirAttr(cir::GlobalViewAttr globalAttr) {
   llvm_unreachable("Expecting pointer or integer type for GlobalViewAttr");
 }
 
+// TypeInfoAttr visitor.
+mlir::Value CIRAttrToValue::visitCirAttr(cir::TypeInfoAttr typeinfoArr) {
+  mlir::Type llvmTy = converter->convertType(typeinfoArr.getType());
+  mlir::Location loc = parentOp->getLoc();
+  mlir::Value result = rewriter.create<mlir::LLVM::UndefOp>(loc, llvmTy);
+
+  for (auto [idx, elt] : llvm::enumerate(typeinfoArr.getData())) {
+    mlir::Value init = visit(elt);
+    result = rewriter.create<mlir::LLVM::InsertValueOp>(loc, result, init, 
idx);
+  }
+
+  return result;
+}
+
 // VTableAttr visitor.
 mlir::Value CIRAttrToValue::visitCirAttr(cir::VTableAttr vtableArr) {
   mlir::Type llvmTy = converter->convertType(vtableArr.getType());
diff --git a/clang/test/CIR/IR/invalid-type-info.cir 
b/clang/test/CIR/IR/invalid-type-info.cir
new file mode 100644
index 0000000000000..9a6c0d7234021
--- /dev/null
+++ b/clang/test/CIR/IR/invalid-type-info.cir
@@ -0,0 +1,17 @@
+// RUN: cir-opt %s -verify-diagnostics -split-input-file
+
+!u8i = !cir.int<u, 8>
+
+!rec_anon_struct = !cir.record<struct  {!cir.ptr<!u8i>, !cir.ptr<!u8i>, 
!cir.ptr<!u8i>}>
+
+// expected-error @below {{expected !cir.record type}}
+cir.global constant external @type_info = 
#cir.typeinfo<{#cir.global_view<@_ZTVN10__cxxabiv120__si_class_type_infoE, [2 : 
i32]> : !cir.ptr<!u8i>, #cir.global_view<@_ZTS1B> : !cir.ptr<!u8i>, 
#cir.global_view<@_ZTI1A> : !cir.ptr<!u8i>}> : !u8i
+
+// -----
+
+!u8i = !cir.int<u, 8>
+
+!rec_anon_struct = !cir.record<struct  {!u8i, !u8i, !u8i}>
+
+// expected-error @below {{expected GlobalViewAttr or IntAttr attribute}}
+cir.global constant external @type_info = #cir.typeinfo<{ #cir.undef : !u8i, 
#cir.int<1> : !u8i, #cir.int<1> : !u8i}> : !rec_anon_struct

>From 8467bdc8d4979ac6ba9502c6bf0e53b451a5c8df Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Thu, 18 Sep 2025 19:15:51 +0200
Subject: [PATCH 2/3] Address code review comments

---
 .../clang/CIR/Dialect/IR/CIRAttrConstraints.td   | 16 ++++++++++++++++
 clang/include/clang/CIR/Dialect/IR/CIRAttrs.td   | 12 +++++++-----
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp          |  7 -------
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp    | 11 ++++++-----
 clang/test/CIR/IR/invalid-type-info.cir          |  8 --------
 5 files changed, 29 insertions(+), 25 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td
index a8c81dbd71a09..8f72ff4d754ad 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td
@@ -38,6 +38,17 @@ def CIR_AnyIntOrFloatAttr : AnyAttrOf<[CIR_AnyIntAttr, 
CIR_AnyFPAttr],
   string cppType = "::mlir::TypedAttr";
 }
 
+//===----------------------------------------------------------------------===//
+// GlobalViewAttr constraints
+//===----------------------------------------------------------------------===//
+
+def CIR_AnyGlobalViewAttr : CIR_AttrConstraint<"::cir::GlobalViewAttr", 
"GlobalView attribute">;
+
+def CIR_AnyIntOrGlobalViewAttr : AnyAttrOf<[CIR_AnyIntAttr, 
CIR_AnyGlobalViewAttr],
+    "integer or global view attribute"> {
+  string cppType = "::mlir::TypedAttr";
+}
+
 
//===----------------------------------------------------------------------===//
 // ArrayAttr constraints
 
//===----------------------------------------------------------------------===//
@@ -45,4 +56,9 @@ def CIR_AnyIntOrFloatAttr : AnyAttrOf<[CIR_AnyIntAttr, 
CIR_AnyFPAttr],
 def CIR_IntArrayAttr : TypedArrayAttrBase<CIR_AnyIntAttr,
    "integer array attribute">;
 
+def CIR_IntOrGlobalViewArrayAttr : 
TypedArrayAttrBase<CIR_AnyIntOrGlobalViewAttr,
+   "integer or global view array attribute">{
+  string cppType = "::mlir::ArrayAttr";
+}
+
 #endif // CLANG_CIR_DIALECT_IR_CIRATTRCONSTRAINTS_TD
\ No newline at end of file
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 10afd7133eed3..e7a29e8b3dba1 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -798,19 +798,21 @@ def CIR_TypeInfoAttr : CIR_Attr<"TypeInfo", "typeinfo", 
[TypedAttrInterface]> {
     Example:
 
     ```
-    cir.global "private" external @_ZTVN10__cxxabiv120__si_class_type_infoE : 
!cir.ptr<i32>
+    cir.global "private" external @_ZTVN10__cxxabiv120__si_class_type_infoE
+      : !cir.ptr<i32>
 
-    !rec_anon_struct = !cir.record<struct  {!cir.ptr<!u8i>, !cir.ptr<!u8i>, 
!cir.ptr<!u8i>}>
+    !rec_anon_struct = !cir.record<struct  {!cir.ptr<!u8i>, !cir.ptr<!u8i>,
+      !cir.ptr<!u8i>}>
 
     cir.global constant external @type_info = #cir.typeinfo<{
       #cir.global_view<@_ZTVN10__cxxabiv120__si_class_type_infoE, [2 : i32]>
-      : !cir.ptr<!u8i>, #cir.global_view<@_ZTS1B> : !cir.ptr<!u8i>, 
#cir.global_view<@_ZTI1A>
-      : !cir.ptr<!u8i>}> : !rec_anon_struct
+      : !cir.ptr<!u8i>, #cir.global_view<@_ZTS1B> : !cir.ptr<!u8i>,
+      #cir.global_view<@_ZTI1A> : !cir.ptr<!u8i>}> : !rec_anon_struct
     ```
   }];
 
   let parameters = (ins AttributeSelfTypeParameter<"">:$type,
-                        "mlir::ArrayAttr":$data);
+                        CIR_IntOrGlobalViewArrayAttr:$data);
 
   let builders = [
     AttrBuilderWithInferredContext<(ins "mlir::Type":$type,
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 3fcc0aad9b11b..97c5c8440ff57 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -26,8 +26,6 @@
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/Support/LogicalResult.h"
 
-#include <numeric>
-
 using namespace mlir;
 using namespace cir;
 
@@ -2752,11 +2750,6 @@ LogicalResult cir::TypeInfoAttr::verify(
   if (cir::ConstRecordAttr::verify(emitError, type, typeinfoData).failed())
     return failure();
 
-  for (auto &member : typeinfoData) {
-    if (llvm::isa<GlobalViewAttr, IntAttr>(member))
-      continue;
-    return emitError() << "expected GlobalViewAttr or IntAttr attribute";
-  }
   return success();
 }
 
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 0c0c28a5cc379..90e3eb3f11f3e 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -523,14 +523,15 @@ mlir::Value 
CIRAttrToValue::visitCirAttr(cir::GlobalViewAttr globalAttr) {
 }
 
 // TypeInfoAttr visitor.
-mlir::Value CIRAttrToValue::visitCirAttr(cir::TypeInfoAttr typeinfoArr) {
-  mlir::Type llvmTy = converter->convertType(typeinfoArr.getType());
+mlir::Value CIRAttrToValue::visitCirAttr(cir::TypeInfoAttr typeinfoAttr) {
+  mlir::Type llvmTy = converter->convertType(typeinfoAttr.getType());
   mlir::Location loc = parentOp->getLoc();
-  mlir::Value result = rewriter.create<mlir::LLVM::UndefOp>(loc, llvmTy);
+  mlir::Value result = mlir::LLVM::UndefOp::create(rewriter, loc, llvmTy);
 
-  for (auto [idx, elt] : llvm::enumerate(typeinfoArr.getData())) {
+  for (auto [idx, elt] : llvm::enumerate(typeinfoAttr.getData())) {
     mlir::Value init = visit(elt);
-    result = rewriter.create<mlir::LLVM::InsertValueOp>(loc, result, init, 
idx);
+    result =
+        mlir::LLVM::InsertValueOp::create(rewriter, loc, result, init, idx);
   }
 
   return result;
diff --git a/clang/test/CIR/IR/invalid-type-info.cir 
b/clang/test/CIR/IR/invalid-type-info.cir
index 9a6c0d7234021..b07a27cd69e19 100644
--- a/clang/test/CIR/IR/invalid-type-info.cir
+++ b/clang/test/CIR/IR/invalid-type-info.cir
@@ -7,11 +7,3 @@
 // expected-error @below {{expected !cir.record type}}
 cir.global constant external @type_info = 
#cir.typeinfo<{#cir.global_view<@_ZTVN10__cxxabiv120__si_class_type_infoE, [2 : 
i32]> : !cir.ptr<!u8i>, #cir.global_view<@_ZTS1B> : !cir.ptr<!u8i>, 
#cir.global_view<@_ZTI1A> : !cir.ptr<!u8i>}> : !u8i
 
-// -----
-
-!u8i = !cir.int<u, 8>
-
-!rec_anon_struct = !cir.record<struct  {!u8i, !u8i, !u8i}>
-
-// expected-error @below {{expected GlobalViewAttr or IntAttr attribute}}
-cir.global constant external @type_info = #cir.typeinfo<{ #cir.undef : !u8i, 
#cir.int<1> : !u8i, #cir.int<1> : !u8i}> : !rec_anon_struct

>From 564f6ba201e0164c1f622ad7da3057eeb63a3da2 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Thu, 18 Sep 2025 19:36:39 +0200
Subject: [PATCH 3/3] Update error message for invalid type info test

---
 clang/test/CIR/IR/invalid-type-info.cir | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/clang/test/CIR/IR/invalid-type-info.cir 
b/clang/test/CIR/IR/invalid-type-info.cir
index b07a27cd69e19..4d4726bdac002 100644
--- a/clang/test/CIR/IR/invalid-type-info.cir
+++ b/clang/test/CIR/IR/invalid-type-info.cir
@@ -7,3 +7,11 @@
 // expected-error @below {{expected !cir.record type}}
 cir.global constant external @type_info = 
#cir.typeinfo<{#cir.global_view<@_ZTVN10__cxxabiv120__si_class_type_infoE, [2 : 
i32]> : !cir.ptr<!u8i>, #cir.global_view<@_ZTS1B> : !cir.ptr<!u8i>, 
#cir.global_view<@_ZTI1A> : !cir.ptr<!u8i>}> : !u8i
 
+// -----
+
+!u8i = !cir.int<u, 8>
+
+!rec_anon_struct = !cir.record<struct  {!u8i, !u8i, !u8i}>
+
+// expected-error @below {{integer or global view array attribute}}
+cir.global constant external @type_info = #cir.typeinfo<{ #cir.undef : !u8i, 
#cir.int<1> : !u8i, #cir.int<1> : !u8i}> : !rec_anon_struct

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to