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

>From cd8321c18eecd841907969753653548fbe23d76a Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Sat, 24 May 2025 14:18:06 +0200
Subject: [PATCH 01/11] [CIR] Upstream global initialization for ComplexType

---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h      |  2 +
 .../include/clang/CIR/Dialect/IR/CIRAttrs.td  | 34 ++++++++++
 .../include/clang/CIR/Dialect/IR/CIRTypes.td  | 43 ++++++++++++
 clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp  | 27 ++++++--
 clang/lib/CIR/CodeGen/CIRGenTypes.cpp         |  7 ++
 clang/lib/CIR/Dialect/IR/CIRAttrs.cpp         | 20 ++++++
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp       |  6 +-
 clang/lib/CIR/Dialect/IR/CIRTypes.cpp         | 24 ++++++-
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 65 +++++++++++++++----
 clang/test/CIR/CodeGen/complex.cpp            | 29 +++++++++
 clang/test/CIR/IR/complex.cir                 | 16 +++++
 11 files changed, 254 insertions(+), 19 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/complex.cpp
 create mode 100644 clang/test/CIR/IR/complex.cir

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index 5cd0caa823ca1..7a5f192618a5d 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -90,6 +90,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
       return cir::IntAttr::get(ty, 0);
     if (cir::isAnyFloatingPointType(ty))
       return cir::FPAttr::getZero(ty);
+    if (auto complexType = mlir::dyn_cast<cir::ComplexType>(ty))
+      return cir::ZeroAttr::get(complexType);
     if (auto arrTy = mlir::dyn_cast<cir::ArrayType>(ty))
       return cir::ZeroAttr::get(arrTy);
     if (auto vecTy = mlir::dyn_cast<cir::VectorType>(ty))
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index ecbced05a5fdd..27a0b4c57ebe4 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -276,6 +276,40 @@ def ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", 
[TypedAttrInterface]> {
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// ConstComplexAttr
+//===----------------------------------------------------------------------===//
+
+def ConstComplexAttr : CIR_Attr<"ConstComplex", "const_complex", 
[TypedAttrInterface]> {
+  let summary = "An attribute that contains a constant complex value";
+  let description = [{
+    The `#cir.const_complex` attribute contains a constant value of complex 
number
+    type. The `real` parameter gives the real part of the complex number and 
the
+    `imag` parameter gives the imaginary part of the complex number.
+
+    The `real` and `imag` parameter must be either an IntAttr or an FPAttr that
+    contains values of the same CIR type.
+  }];
+
+  let parameters = (ins
+    AttributeSelfTypeParameter<"", "cir::ComplexType">:$type,
+    "mlir::TypedAttr":$real, "mlir::TypedAttr":$imag);
+
+  let builders = [
+    AttrBuilderWithInferredContext<(ins "cir::ComplexType":$type,
+                                        "mlir::TypedAttr":$real,
+                                        "mlir::TypedAttr":$imag), [{
+      return $_get(type.getContext(), type, real, imag);
+    }]>,
+  ];
+
+  let genVerifyDecl = 1;
+
+  let assemblyFormat = [{
+    `<` qualified($real) `,` qualified($imag) `>`
+  }];
+}
+
 
//===----------------------------------------------------------------------===//
 // VisibilityAttr
 
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td 
b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
index 9c0af8d3eaa5f..e7954bee74e5d 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -161,6 +161,49 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", 
"long_double"> {
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// ComplexType
+//===----------------------------------------------------------------------===//
+
+def CIR_ComplexType : CIR_Type<"Complex", "complex",
+    [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
+
+  let summary = "CIR complex type";
+  let description = [{
+    CIR type that represents a C complex number. `cir.complex` models the C 
type
+    `T _Complex`.
+
+    The type models complex values, per C99 6.2.5p11. It supports the C99
+    complex float types as well as the GCC integer complex extensions.
+
+    The parameter `elementType` gives the type of the real and imaginary part 
of
+    the complex number. `elementType` must be either a CIR integer type or a 
CIR
+    floating-point type.
+  }];
+
+  let parameters = (ins CIR_AnyIntOrFloatType:$elementType);
+
+  let builders = [
+    TypeBuilderWithInferredContext<(ins "mlir::Type":$elementType), [{
+      return $_get(elementType.getContext(), elementType);
+    }]>,
+  ];
+
+  let assemblyFormat = [{
+    `<` $elementType `>`
+  }];
+
+  let extraClassDeclaration = [{
+    bool isFloatingPointComplex() const {
+      return isAnyFloatingPointType(getElementType());
+    }
+
+    bool isIntegerComplex() const {
+      return mlir::isa<cir::IntType>(getElementType());
+    }
+  }];
+}
+
 
//===----------------------------------------------------------------------===//
 // PointerType
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 9085ee2dfe506..973349b8c0443 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -577,12 +577,31 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const 
APValue &value,
   case APValue::Union:
     cgm.errorNYI("ConstExprEmitter::tryEmitPrivate struct or union");
     return {};
-  case APValue::FixedPoint:
   case APValue::ComplexInt:
-  case APValue::ComplexFloat:
+  case APValue::ComplexFloat: {
+    mlir::Type desiredType = cgm.convertType(destType);
+    cir::ComplexType complexType =
+        mlir::dyn_cast<cir::ComplexType>(desiredType);
+
+    mlir::Type compelxElemTy = complexType.getElementType();
+    if (isa<cir::IntType>(compelxElemTy)) {
+      llvm::APSInt real = value.getComplexIntReal();
+      llvm::APSInt imag = value.getComplexIntImag();
+      return builder.getAttr<cir::ConstComplexAttr>(
+          complexType, builder.getAttr<cir::IntAttr>(compelxElemTy, real),
+          builder.getAttr<cir::IntAttr>(compelxElemTy, imag));
+    }
+
+    llvm::APFloat real = value.getComplexFloatReal();
+    llvm::APFloat imag = value.getComplexFloatImag();
+    return builder.getAttr<cir::ConstComplexAttr>(
+        complexType, builder.getAttr<cir::FPAttr>(compelxElemTy, real),
+        builder.getAttr<cir::FPAttr>(compelxElemTy, imag));
+  }
+  case APValue::FixedPoint:
   case APValue::AddrLabelDiff:
-    cgm.errorNYI("ConstExprEmitter::tryEmitPrivate fixed point, complex int, "
-                 "complex float, addr label diff");
+    cgm.errorNYI(
+        "ConstExprEmitter::tryEmitPrivate fixed point, addr label diff");
     return {};
   }
   llvm_unreachable("Unknown APValue kind");
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp 
b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index d962372a4bcc0..5716cc8c79a17 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -387,6 +387,13 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
     break;
   }
 
+  case Type::Complex: {
+    const ComplexType *ct = cast<ComplexType>(ty);
+    mlir::Type elementTy = convertType(ct->getElementType());
+    resultType = cir::ComplexType::get(elementTy);
+    break;
+  }
+
   case Type::LValueReference:
   case Type::RValueReference: {
     const ReferenceType *refTy = cast<ReferenceType>(ty);
diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp 
b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
index 52f0b33afaba4..b52e9c3e49199 100644
--- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
@@ -183,6 +183,26 @@ LogicalResult 
FPAttr::verify(function_ref<InFlightDiagnostic()> emitError,
   return success();
 }
 
+//===----------------------------------------------------------------------===//
+// ConstComplexAttr definitions
+//===----------------------------------------------------------------------===//
+
+LogicalResult
+ConstComplexAttr::verify(function_ref<InFlightDiagnostic()> emitError,
+                         cir::ComplexType type, mlir::TypedAttr real,
+                         mlir::TypedAttr imag) {
+  mlir::Type elemType = type.getElementType();
+  if (real.getType() != elemType)
+    return emitError()
+           << "type of the real part does not match the complex type";
+
+  if (imag.getType() != elemType)
+    return emitError()
+           << "type of the imaginary part does not match the complex type";
+
+  return success();
+}
+
 
//===----------------------------------------------------------------------===//
 // CIR ConstArrayAttr
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 36f050de9f8bb..99d385eba72b6 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -230,7 +230,8 @@ static LogicalResult checkConstantTypes(mlir::Operation 
*op, mlir::Type opType,
   }
 
   if (isa<cir::ZeroAttr>(attrType)) {
-    if (isa<cir::RecordType, cir::ArrayType, cir::VectorType>(opType))
+    if (isa<cir::RecordType, cir::ArrayType, cir::VectorType, 
cir::ComplexType>(
+            opType))
       return success();
     return op->emitOpError("zero expects struct or array type");
   }
@@ -252,7 +253,8 @@ static LogicalResult checkConstantTypes(mlir::Operation 
*op, mlir::Type opType,
     return success();
   }
 
-  if (mlir::isa<cir::ConstArrayAttr, cir::ConstVectorAttr>(attrType))
+  if (mlir::isa<cir::ConstArrayAttr, cir::ConstVectorAttr,
+                cir::ConstComplexAttr>(attrType))
     return success();
 
   assert(isa<TypedAttr>(attrType) && "What else could we be looking at here?");
diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp 
b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
index 900871c3c2cba..630fedef248d6 100644
--- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -553,9 +553,31 @@ LongDoubleType::getABIAlignment(const mlir::DataLayout 
&dataLayout,
 }
 
 
//===----------------------------------------------------------------------===//
-// FuncType Definitions
+// ComplexType Definitions
 
//===----------------------------------------------------------------------===//
 
+llvm::TypeSize
+cir::ComplexType::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
+                                    mlir::DataLayoutEntryListRef params) const 
{
+  // C17 6.2.5p13:
+  //   Each complex type has the same representation and alignment requirements
+  //   as an array type containing exactly two elements of the corresponding
+  //   real type.
+
+  return dataLayout.getTypeSizeInBits(getElementType()) * 2;
+}
+
+uint64_t
+cir::ComplexType::getABIAlignment(const mlir::DataLayout &dataLayout,
+                                  mlir::DataLayoutEntryListRef params) const {
+  // C17 6.2.5p13:
+  //   Each complex type has the same representation and alignment requirements
+  //   as an array type containing exactly two elements of the corresponding
+  //   real type.
+
+  return dataLayout.getTypeABIAlignment(getElementType());
+}
+
 FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
   assert(results.size() == 1 && "expected exactly one result type");
   return get(llvm::to_vector(inputs), results[0], isVarArg());
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index f61e85ce3ccec..7a4f8eb079f93 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -188,14 +188,15 @@ class CIRAttrToValue {
 
   mlir::Value visit(mlir::Attribute attr) {
     return llvm::TypeSwitch<mlir::Attribute, mlir::Value>(attr)
-        .Case<cir::IntAttr, cir::FPAttr, cir::ConstArrayAttr,
-              cir::ConstVectorAttr, cir::ConstPtrAttr, cir::ZeroAttr>(
-            [&](auto attrT) { return visitCirAttr(attrT); })
+        .Case<cir::IntAttr, cir::FPAttr, cir::ConstComplexAttr,
+              cir::ConstArrayAttr, cir::ConstVectorAttr, cir::ConstPtrAttr,
+              cir::ZeroAttr>([&](auto attrT) { return visitCirAttr(attrT); })
         .Default([&](auto attrT) { return mlir::Value(); });
   }
 
   mlir::Value visitCirAttr(cir::IntAttr intAttr);
   mlir::Value visitCirAttr(cir::FPAttr fltAttr);
+  mlir::Value visitCirAttr(cir::ConstComplexAttr complexAttr);
   mlir::Value visitCirAttr(cir::ConstPtrAttr ptrAttr);
   mlir::Value visitCirAttr(cir::ConstArrayAttr attr);
   mlir::Value visitCirAttr(cir::ConstVectorAttr attr);
@@ -226,6 +227,42 @@ mlir::Value CIRAttrToValue::visitCirAttr(cir::IntAttr 
intAttr) {
       loc, converter->convertType(intAttr.getType()), intAttr.getValue());
 }
 
+/// FPAttr visitor.
+mlir::Value CIRAttrToValue::visitCirAttr(cir::FPAttr fltAttr) {
+  mlir::Location loc = parentOp->getLoc();
+  return rewriter.create<mlir::LLVM::ConstantOp>(
+      loc, converter->convertType(fltAttr.getType()), fltAttr.getValue());
+}
+
+/// ConstComplexAttr visitor.
+mlir::Value CIRAttrToValue::visitCirAttr(cir::ConstComplexAttr complexAttr) {
+  auto complexType = mlir::cast<cir::ComplexType>(complexAttr.getType());
+  auto complexElemTy = complexType.getElementType();
+  auto complexElemLLVMTy = converter->convertType(complexElemTy);
+
+  mlir::Attribute components[2];
+  if (const auto intType = mlir::dyn_cast<cir::IntType>(complexElemTy)) {
+    components[0] = rewriter.getIntegerAttr(
+        complexElemLLVMTy,
+        mlir::cast<cir::IntAttr>(complexAttr.getReal()).getValue());
+    components[1] = rewriter.getIntegerAttr(
+        complexElemLLVMTy,
+        mlir::cast<cir::IntAttr>(complexAttr.getImag()).getValue());
+  } else {
+    components[0] = rewriter.getFloatAttr(
+        complexElemLLVMTy,
+        mlir::cast<cir::FPAttr>(complexAttr.getReal()).getValue());
+    components[1] = rewriter.getFloatAttr(
+        complexElemLLVMTy,
+        mlir::cast<cir::FPAttr>(complexAttr.getImag()).getValue());
+  }
+
+  mlir::Location loc = parentOp->getLoc();
+  return rewriter.create<mlir::LLVM::ConstantOp>(
+      loc, converter->convertType(complexAttr.getType()),
+      rewriter.getArrayAttr(components));
+}
+
 /// ConstPtrAttr visitor.
 mlir::Value CIRAttrToValue::visitCirAttr(cir::ConstPtrAttr ptrAttr) {
   mlir::Location loc = parentOp->getLoc();
@@ -241,13 +278,6 @@ mlir::Value CIRAttrToValue::visitCirAttr(cir::ConstPtrAttr 
ptrAttr) {
       loc, converter->convertType(ptrAttr.getType()), ptrVal);
 }
 
-/// FPAttr visitor.
-mlir::Value CIRAttrToValue::visitCirAttr(cir::FPAttr fltAttr) {
-  mlir::Location loc = parentOp->getLoc();
-  return rewriter.create<mlir::LLVM::ConstantOp>(
-      loc, converter->convertType(fltAttr.getType()), fltAttr.getValue());
-}
-
 // ConstArrayAttr visitor
 mlir::Value CIRAttrToValue::visitCirAttr(cir::ConstArrayAttr attr) {
   mlir::Type llvmTy = converter->convertType(attr.getType());
@@ -341,9 +371,11 @@ class GlobalInitAttrRewriter {
   mlir::Attribute visitCirAttr(cir::IntAttr attr) {
     return rewriter.getIntegerAttr(llvmType, attr.getValue());
   }
+
   mlir::Attribute visitCirAttr(cir::FPAttr attr) {
     return rewriter.getFloatAttr(llvmType, attr.getValue());
   }
+
   mlir::Attribute visitCirAttr(cir::BoolAttr attr) {
     return rewriter.getBoolAttr(attr.getValue());
   }
@@ -986,7 +1018,7 @@ 
CIRToLLVMGlobalOpLowering::matchAndRewriteRegionInitializedGlobal(
     mlir::ConversionPatternRewriter &rewriter) const {
   // TODO: Generalize this handling when more types are needed here.
   assert((isa<cir::ConstArrayAttr, cir::ConstVectorAttr, cir::ConstPtrAttr,
-              cir::ZeroAttr>(init)));
+              cir::ConstComplexAttr, cir::ZeroAttr>(init)));
 
   // TODO(cir): once LLVM's dialect has proper equivalent attributes this
   // should be updated. For now, we use a custom op to initialize globals
@@ -1039,7 +1071,8 @@ mlir::LogicalResult 
CIRToLLVMGlobalOpLowering::matchAndRewrite(
         return mlir::failure();
       }
     } else if (mlir::isa<cir::ConstArrayAttr, cir::ConstVectorAttr,
-                         cir::ConstPtrAttr, cir::ZeroAttr>(init.value())) {
+                         cir::ConstPtrAttr, cir::ConstComplexAttr,
+                         cir::ZeroAttr>(init.value())) {
       // TODO(cir): once LLVM's dialect has proper equivalent attributes this
       // should be updated. For now, we use a custom op to initialize globals
       // to the appropriate value.
@@ -1571,6 +1604,14 @@ static void prepareTypeConverter(mlir::LLVMTypeConverter 
&converter,
   converter.addConversion([&](cir::BF16Type type) -> mlir::Type {
     return mlir::BFloat16Type::get(type.getContext());
   });
+  converter.addConversion([&](cir::ComplexType type) -> mlir::Type {
+    // A complex type is lowered to an LLVM struct that contains the real and
+    // imaginary part as data fields.
+    mlir::Type elementTy = converter.convertType(type.getElementType());
+    mlir::Type structFields[2] = {elementTy, elementTy};
+    return mlir::LLVM::LLVMStructType::getLiteral(type.getContext(),
+                                                  structFields);
+  });
   converter.addConversion([&](cir::FuncType type) -> std::optional<mlir::Type> 
{
     auto result = converter.convertType(type.getReturnType());
     llvm::SmallVector<mlir::Type> arguments;
diff --git a/clang/test/CIR/CodeGen/complex.cpp 
b/clang/test/CIR/CodeGen/complex.cpp
new file mode 100644
index 0000000000000..1e0c9fcf08ef0
--- /dev/null
+++ b/clang/test/CIR/CodeGen/complex.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+int _Complex ci;
+
+float _Complex cf;
+
+int _Complex ci2 = { 1, 2 };
+
+float _Complex cf2 = { 1.0f, 2.0f };
+
+// CIR: cir.global external @ci = #cir.zero : !cir.complex<!s32i>
+// CIR: cir.global external @cf = #cir.zero : !cir.complex<!cir.float>
+// CIR: cir.global external @ci2 = #cir.const_complex<#cir.int<1> : !s32i, 
#cir.int<2> : !s32i> : !cir.complex<!s32i>
+// CIR: cir.global external @cf2 = #cir.const_complex<#cir.fp<1.000000e+00> : 
!cir.float, #cir.fp<2.000000e+00> : !cir.float> : !cir.complex<!cir.float>
+
+// LLVM: {{.*}} = dso_local global { i32, i32 } zeroinitializer, align 4
+// LLVM: {{.*}} = dso_local global { float, float } zeroinitializer, align 4
+// LLVM: {{.*}} = dso_local global { i32, i32 } { i32 1, i32 2 }, align 4
+// LLVM: {{.*}} = dso_local global { float, float } { float 1.000000e+00, 
float 2.000000e+00 }, align 4
+
+// OGCG: {{.*}} = global { i32, i32 } zeroinitializer, align 4
+// OGCG: {{.*}} = global { float, float } zeroinitializer, align 4
+// OGCG: {{.*}} = global { i32, i32 } { i32 1, i32 2 }, align 4
+// OGCG: {{.*}} = global { float, float } { float 1.000000e+00, float 
2.000000e+00 }, align 4
diff --git a/clang/test/CIR/IR/complex.cir b/clang/test/CIR/IR/complex.cir
new file mode 100644
index 0000000000000..a73a8654ca274
--- /dev/null
+++ b/clang/test/CIR/IR/complex.cir
@@ -0,0 +1,16 @@
+// RUN: cir-opt %s | FileCheck %s
+
+!s32i = !cir.int<s, 32>
+
+module  {
+
+cir.global external @ci = #cir.zero : !cir.complex<!s32i>
+// CHECK: cir.global external {{.*}} = #cir.zero : !cir.complex<!s32i>
+
+cir.global external @cf = #cir.zero : !cir.complex<!cir.float>
+// CHECK: cir.global external {{.*}} = #cir.zero : !cir.complex<!cir.float>
+
+cir.global external @ci2 = #cir.const_complex<#cir.int<1> : !s32i, #cir.int<2> 
: !s32i> : !cir.complex<!s32i>
+// CHECK: cir.global external {{.*}} = #cir.const_complex<#cir.int<1> : !s32i, 
#cir.int<2> : !s32i> : !cir.complex<!s32i>
+
+}

>From 404e7d8b8f57ac343339ce243b3395b71b9cd53e Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Sun, 25 May 2025 16:09:14 +0200
Subject: [PATCH 02/11] Fix typo in var name

---
 clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 973349b8c0443..b2cd5c4572cad 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -583,20 +583,20 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const 
APValue &value,
     cir::ComplexType complexType =
         mlir::dyn_cast<cir::ComplexType>(desiredType);
 
-    mlir::Type compelxElemTy = complexType.getElementType();
-    if (isa<cir::IntType>(compelxElemTy)) {
+    mlir::Type complexElemTy = complexType.getElementType();
+    if (isa<cir::IntType>(complexElemTy)) {
       llvm::APSInt real = value.getComplexIntReal();
       llvm::APSInt imag = value.getComplexIntImag();
       return builder.getAttr<cir::ConstComplexAttr>(
-          complexType, builder.getAttr<cir::IntAttr>(compelxElemTy, real),
-          builder.getAttr<cir::IntAttr>(compelxElemTy, imag));
+          complexType, builder.getAttr<cir::IntAttr>(complexElemTy, real),
+          builder.getAttr<cir::IntAttr>(complexElemTy, imag));
     }
 
     llvm::APFloat real = value.getComplexFloatReal();
     llvm::APFloat imag = value.getComplexFloatImag();
     return builder.getAttr<cir::ConstComplexAttr>(
-        complexType, builder.getAttr<cir::FPAttr>(compelxElemTy, real),
-        builder.getAttr<cir::FPAttr>(compelxElemTy, imag));
+        complexType, builder.getAttr<cir::FPAttr>(complexElemTy, real),
+        builder.getAttr<cir::FPAttr>(complexElemTy, imag));
   }
   case APValue::FixedPoint:
   case APValue::AddrLabelDiff:

>From ec9fb3cba4f251c799a6ecff84068bc87d9b75a2 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Sun, 25 May 2025 20:29:23 +0200
Subject: [PATCH 03/11] Address codereview comments

---
 clang/include/clang/CIR/Dialect/IR/CIRAttrs.td      | 3 ++-
 clang/lib/CIR/CodeGen/CIRGenTypes.cpp               | 2 +-
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp             | 3 ++-
 clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 4 ++--
 4 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 27a0b4c57ebe4..18caa6376ba61 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -280,7 +280,8 @@ def ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", 
[TypedAttrInterface]> {
 // ConstComplexAttr
 
//===----------------------------------------------------------------------===//
 
-def ConstComplexAttr : CIR_Attr<"ConstComplex", "const_complex", 
[TypedAttrInterface]> {
+def ConstComplexAttr : CIR_Attr<"ConstComplex", "const_complex",
+                                [TypedAttrInterface]> {
   let summary = "An attribute that contains a constant complex value";
   let description = [{
     The `#cir.const_complex` attribute contains a constant value of complex 
number
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp 
b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 5716cc8c79a17..95900592c2793 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -388,7 +388,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
   }
 
   case Type::Complex: {
-    const ComplexType *ct = cast<ComplexType>(ty);
+    const auto *ct = mlir::cast<clang::ComplexType>(ty);
     mlir::Type elementTy = convertType(ct->getElementType());
     resultType = cir::ComplexType::get(elementTy);
     break;
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 99d385eba72b6..250496de22cd6 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -233,7 +233,8 @@ static LogicalResult checkConstantTypes(mlir::Operation 
*op, mlir::Type opType,
     if (isa<cir::RecordType, cir::ArrayType, cir::VectorType, 
cir::ComplexType>(
             opType))
       return success();
-    return op->emitOpError("zero expects struct or array type");
+    return op->emitOpError(
+        "zero expects struct, array, vector or complex type");
   }
 
   if (mlir::isa<cir::BoolAttr>(attrType)) {
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 7a4f8eb079f93..107a32b67cdcc 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -237,8 +237,8 @@ mlir::Value CIRAttrToValue::visitCirAttr(cir::FPAttr 
fltAttr) {
 /// ConstComplexAttr visitor.
 mlir::Value CIRAttrToValue::visitCirAttr(cir::ConstComplexAttr complexAttr) {
   auto complexType = mlir::cast<cir::ComplexType>(complexAttr.getType());
-  auto complexElemTy = complexType.getElementType();
-  auto complexElemLLVMTy = converter->convertType(complexElemTy);
+  mlir::Type complexElemTy = complexType.getElementType();
+  mlir::Type complexElemLLVMTy = converter->convertType(complexElemTy);
 
   mlir::Attribute components[2];
   if (const auto intType = mlir::dyn_cast<cir::IntType>(complexElemTy)) {

>From 476374cf30881da051efa45c3d84c8a8b9cf1f80 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Tue, 27 May 2025 19:20:23 +0200
Subject: [PATCH 04/11] Address code review comment

---
 clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp 
b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 95900592c2793..217b42390909f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -388,7 +388,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
   }
 
   case Type::Complex: {
-    const auto *ct = mlir::cast<clang::ComplexType>(ty);
+    const auto *ct = cast<clang::ComplexType>(ty);
     mlir::Type elementTy = convertType(ct->getElementType());
     resultType = cir::ComplexType::get(elementTy);
     break;

>From 9d6d5a82ecf5c80ba0517ff015ac4944167590fb Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Wed, 28 May 2025 21:27:12 +0200
Subject: [PATCH 05/11] Address code review comments

---
 clang/include/clang/CIR/Dialect/IR/CIRAttrs.td        | 11 +++++++++--
 clang/include/clang/CIR/Dialect/IR/CIRTypes.td        |  5 +++++
 clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp          |  2 ++
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp               |  2 +-
 .../IR/invalid-const-complex-wrong-imaginary-type.cir | 11 +++++++++++
 .../CIR/IR/invalid-const-complex-wrong-real-type.cir  | 11 +++++++++++
 6 files changed, 39 insertions(+), 3 deletions(-)
 create mode 100644 
clang/test/CIR/IR/invalid-const-complex-wrong-imaginary-type.cir
 create mode 100644 clang/test/CIR/IR/invalid-const-complex-wrong-real-type.cir

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 18caa6376ba61..12d3cd46788cb 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -288,8 +288,15 @@ def ConstComplexAttr : CIR_Attr<"ConstComplex", 
"const_complex",
     type. The `real` parameter gives the real part of the complex number and 
the
     `imag` parameter gives the imaginary part of the complex number.
 
-    The `real` and `imag` parameter must be either an IntAttr or an FPAttr that
-    contains values of the same CIR type.
+    The `real` and `imag` parameters must both reference the same type and must
+    be either IntAttr or FPAttr.
+
+    ```mlir
+    %ci = #cir.const_complex<#cir.int<1> : !s32i, #cir.int<2> : !s32i>
+        : !cir.complex<!s32i>
+    %cf = #cir.const_complex<#cir.fp<1.000000e+00> : !cir.float,
+        #cir.fp<2.000000e+00> : !cir.float> : !cir.complex<!cir.float>
+    ```
   }];
 
   let parameters = (ins
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td 
b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
index e7954bee74e5d..4c1495e60fdd8 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -179,6 +179,11 @@ def CIR_ComplexType : CIR_Type<"Complex", "complex",
     The parameter `elementType` gives the type of the real and imaginary part 
of
     the complex number. `elementType` must be either a CIR integer type or a 
CIR
     floating-point type.
+
+    ```mlir
+    !cir.complex<!s32i>
+    !cir.complex<!cir.float>
+    ```
   }];
 
   let parameters = (ins CIR_AnyIntOrFloatType:$elementType);
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index b2cd5c4572cad..c41ab54be09ca 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -592,6 +592,8 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const 
APValue &value,
           builder.getAttr<cir::IntAttr>(complexElemTy, imag));
     }
 
+    assert(isa<cir::CIRFPTypeInterface>(complexElemTy) &&
+           "expected floating-point type");
     llvm::APFloat real = value.getComplexFloatReal();
     llvm::APFloat imag = value.getComplexFloatImag();
     return builder.getAttr<cir::ConstComplexAttr>(
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 250496de22cd6..7e2b006e03b72 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -234,7 +234,7 @@ static LogicalResult checkConstantTypes(mlir::Operation 
*op, mlir::Type opType,
             opType))
       return success();
     return op->emitOpError(
-        "zero expects struct, array, vector or complex type");
+        "zero expects struct, array, vector, or complex type");
   }
 
   if (mlir::isa<cir::BoolAttr>(attrType)) {
diff --git a/clang/test/CIR/IR/invalid-const-complex-wrong-imaginary-type.cir 
b/clang/test/CIR/IR/invalid-const-complex-wrong-imaginary-type.cir
new file mode 100644
index 0000000000000..b714a7dfe7bd4
--- /dev/null
+++ b/clang/test/CIR/IR/invalid-const-complex-wrong-imaginary-type.cir
@@ -0,0 +1,11 @@
+// RUN: cir-opt %s -verify-diagnostics -split-input-file
+
+!s32i = !cir.int<s, 32>
+!s64i = !cir.int<s, 64>
+
+module {
+
+// expected-error @below {{type of the imaginary part does not match the 
complex type}}
+cir.global external @ci2 = #cir.const_complex<#cir.int<1> : !s32i, #cir.int<2> 
: !s64i> : !cir.complex<!s32i>
+
+}
diff --git a/clang/test/CIR/IR/invalid-const-complex-wrong-real-type.cir 
b/clang/test/CIR/IR/invalid-const-complex-wrong-real-type.cir
new file mode 100644
index 0000000000000..53baabfe43b42
--- /dev/null
+++ b/clang/test/CIR/IR/invalid-const-complex-wrong-real-type.cir
@@ -0,0 +1,11 @@
+// RUN: cir-opt %s -verify-diagnostics -split-input-file
+
+!s32i = !cir.int<s, 32>
+!s64i = !cir.int<s, 64>
+
+module {
+
+// expected-error @below {{type of the real part does not match the complex 
type}}
+cir.global external @ci2 = #cir.const_complex<#cir.int<1> : !s64i, #cir.int<2> 
: !s32i> : !cir.complex<!s32i>
+
+}

>From aa60e6f3fe17ca8e4d9d1bdb7e40326cbbb85886 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Wed, 28 May 2025 23:45:52 +0200
Subject: [PATCH 06/11] Merge invalid complex test into one file

---
 ...mplex-wrong-real-type.cir => invalid-complex.cir} | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 rename clang/test/CIR/IR/{invalid-const-complex-wrong-real-type.cir => 
invalid-complex.cir} (53%)

diff --git a/clang/test/CIR/IR/invalid-const-complex-wrong-real-type.cir 
b/clang/test/CIR/IR/invalid-complex.cir
similarity index 53%
rename from clang/test/CIR/IR/invalid-const-complex-wrong-real-type.cir
rename to clang/test/CIR/IR/invalid-complex.cir
index 53baabfe43b42..8c6d890579321 100644
--- a/clang/test/CIR/IR/invalid-const-complex-wrong-real-type.cir
+++ b/clang/test/CIR/IR/invalid-complex.cir
@@ -9,3 +9,15 @@ module {
 cir.global external @ci2 = #cir.const_complex<#cir.int<1> : !s64i, #cir.int<2> 
: !s32i> : !cir.complex<!s32i>
 
 }
+
+// -----
+
+!s32i = !cir.int<s, 32>
+!s64i = !cir.int<s, 64>
+
+module {
+
+// expected-error @below {{type of the imaginary part does not match the 
complex type}}
+cir.global external @ci2 = #cir.const_complex<#cir.int<1> : !s32i, #cir.int<2> 
: !s64i> : !cir.complex<!s32i>
+
+}

>From 1ef6589aa648f7e0add07056bbf13ee9e24ca5d4 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Thu, 29 May 2025 00:00:22 +0200
Subject: [PATCH 07/11] Format description and remove extra test file

---
 clang/include/clang/CIR/Dialect/IR/CIRAttrs.td        |  6 +++---
 .../IR/invalid-const-complex-wrong-imaginary-type.cir | 11 -----------
 2 files changed, 3 insertions(+), 14 deletions(-)
 delete mode 100644 
clang/test/CIR/IR/invalid-const-complex-wrong-imaginary-type.cir

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 12d3cd46788cb..4a16b14d4f3b1 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -284,9 +284,9 @@ def ConstComplexAttr : CIR_Attr<"ConstComplex", 
"const_complex",
                                 [TypedAttrInterface]> {
   let summary = "An attribute that contains a constant complex value";
   let description = [{
-    The `#cir.const_complex` attribute contains a constant value of complex 
number
-    type. The `real` parameter gives the real part of the complex number and 
the
-    `imag` parameter gives the imaginary part of the complex number.
+    The `#cir.const_complex` attribute contains a constant value of complex
+    number type. The `real` parameter gives the real part of the complex number
+    and the `imag` parameter gives the imaginary part of the complex number.
 
     The `real` and `imag` parameters must both reference the same type and must
     be either IntAttr or FPAttr.
diff --git a/clang/test/CIR/IR/invalid-const-complex-wrong-imaginary-type.cir 
b/clang/test/CIR/IR/invalid-const-complex-wrong-imaginary-type.cir
deleted file mode 100644
index b714a7dfe7bd4..0000000000000
--- a/clang/test/CIR/IR/invalid-const-complex-wrong-imaginary-type.cir
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: cir-opt %s -verify-diagnostics -split-input-file
-
-!s32i = !cir.int<s, 32>
-!s64i = !cir.int<s, 64>
-
-module {
-
-// expected-error @below {{type of the imaginary part does not match the 
complex type}}
-cir.global external @ci2 = #cir.const_complex<#cir.int<1> : !s32i, #cir.int<2> 
: !s64i> : !cir.complex<!s32i>
-
-}

>From 850ee56503a515db25265af260b7818aa1988ac4 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Sat, 31 May 2025 12:05:42 +0200
Subject: [PATCH 08/11] Update ComplexType testing to not check for dso_local

---
 clang/test/CIR/CodeGen/complex.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/test/CIR/CodeGen/complex.cpp 
b/clang/test/CIR/CodeGen/complex.cpp
index 1e0c9fcf08ef0..6fa7bca3749cf 100644
--- a/clang/test/CIR/CodeGen/complex.cpp
+++ b/clang/test/CIR/CodeGen/complex.cpp
@@ -18,10 +18,10 @@ float _Complex cf2 = { 1.0f, 2.0f };
 // CIR: cir.global external @ci2 = #cir.const_complex<#cir.int<1> : !s32i, 
#cir.int<2> : !s32i> : !cir.complex<!s32i>
 // CIR: cir.global external @cf2 = #cir.const_complex<#cir.fp<1.000000e+00> : 
!cir.float, #cir.fp<2.000000e+00> : !cir.float> : !cir.complex<!cir.float>
 
-// LLVM: {{.*}} = dso_local global { i32, i32 } zeroinitializer, align 4
-// LLVM: {{.*}} = dso_local global { float, float } zeroinitializer, align 4
-// LLVM: {{.*}} = dso_local global { i32, i32 } { i32 1, i32 2 }, align 4
-// LLVM: {{.*}} = dso_local global { float, float } { float 1.000000e+00, 
float 2.000000e+00 }, align 4
+// LLVM: {{.*}} = global { i32, i32 } zeroinitializer, align 4
+// LLVM: {{.*}} = global { float, float } zeroinitializer, align 4
+// LLVM: {{.*}} = global { i32, i32 } { i32 1, i32 2 }, align 4
+// LLVM: {{.*}} = global { float, float } { float 1.000000e+00, float 
2.000000e+00 }, align 4
 
 // OGCG: {{.*}} = global { i32, i32 } zeroinitializer, align 4
 // OGCG: {{.*}} = global { float, float } zeroinitializer, align 4

>From cb1d4018286e6cba1a41f5f6672907fcefdd555d Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Tue, 3 Jun 2025 23:33:11 +0200
Subject: [PATCH 09/11] Add constraints for Attr parameters

---
 .../CIR/Dialect/IR/CIRAttrConstraints.td      | 41 +++++++++++++++++++
 .../include/clang/CIR/Dialect/IR/CIRAttrs.td  |  5 ++-
 .../include/clang/CIR/Dialect/IR/CIRTypes.td  |  2 +
 .../clang/CIR/Dialect/IR/CMakeLists.txt       |  6 +++
 4 files changed, 53 insertions(+), 1 deletion(-)
 create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td
new file mode 100644
index 0000000000000..4c873c4028d3e
--- /dev/null
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td
@@ -0,0 +1,41 @@
+
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the CIR dialect attributes constraints.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CIR_DIALECT_IR_CIRATTRCONSTRAINTS_TD
+#define CLANG_CIR_DIALECT_IR_CIRATTRCONSTRAINTS_TD
+
+include "mlir/IR/CommonAttrConstraints.td"
+
+class CIR_IsAttrPred<code attr> : CPred<"::mlir::isa<" # attr # ">($_self)">;
+
+class CIR_AttrConstraint<code attr, string summary = "">
+    : Attr<CIR_IsAttrPred<attr>, summary>;
+
+//===----------------------------------------------------------------------===//
+// IntAttr constraints
+//===----------------------------------------------------------------------===//
+
+def CIR_AnyIntAttr : CIR_AttrConstraint<"::cir::IntAttr", "integer attribute">;
+
+//===----------------------------------------------------------------------===//
+// FPAttr constraints
+//===----------------------------------------------------------------------===//
+
+def CIR_AnyFPAttr : CIR_AttrConstraint<"::cir::FPAttr", "floating-point 
attribute">;
+
+def CIR_AnyIntOrFloatAttr : AnyAttrOf<[CIR_AnyIntAttr, CIR_AnyFPAttr],
+    "integer or floating point type"> {
+  string cppType = "::mlir::TypedAttr";
+}
+
+#endif // CLANG_CIR_DIALECT_IR_CIRATTRCONSTRAINTS_TD
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 4a16b14d4f3b1..d22d265e82425 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -17,6 +17,7 @@ include "mlir/IR/BuiltinAttributeInterfaces.td"
 include "mlir/IR/EnumAttr.td"
 
 include "clang/CIR/Dialect/IR/CIRDialect.td"
+include "clang/CIR/Dialect/IR/CIRAttrConstraints.td"
 
 
//===----------------------------------------------------------------------===//
 // CIR Attrs
@@ -301,7 +302,9 @@ def ConstComplexAttr : CIR_Attr<"ConstComplex", 
"const_complex",
 
   let parameters = (ins
     AttributeSelfTypeParameter<"", "cir::ComplexType">:$type,
-    "mlir::TypedAttr":$real, "mlir::TypedAttr":$imag);
+    CIR_AnyIntOrFloatAttr:$real,
+    CIR_AnyIntOrFloatAttr:$imag
+  );
 
   let builders = [
     AttrBuilderWithInferredContext<(ins "cir::ComplexType":$type,
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td 
b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
index 4c1495e60fdd8..cd74a9035b85d 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -173,6 +173,8 @@ def CIR_ComplexType : CIR_Type<"Complex", "complex",
     CIR type that represents a C complex number. `cir.complex` models the C 
type
     `T _Complex`.
 
+    `cir.complex` type is not directly mapped to `std::complex`.
+
     The type models complex values, per C99 6.2.5p11. It supports the C99
     complex float types as well as the GCC integer complex extensions.
 
diff --git a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt 
b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
index 6e7f3da4add3e..436c9aa85635c 100644
--- a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
+++ b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
@@ -25,3 +25,9 @@ mlir_tablegen(CIRTypeConstraints.h.inc 
-gen-type-constraint-decls)
 mlir_tablegen(CIRTypeConstraints.cpp.inc -gen-type-constraint-defs)
 add_public_tablegen_target(MLIRCIRTypeConstraintsIncGen)
 add_dependencies(mlir-headers MLIRCIRTypeConstraintsIncGen)
+
+set(LLVM_TARGET_DEFINITIONS CIRAttrConstraints.td)
+mlir_tablegen(CIRAttrConstraints.h.inc -gen-type-constraint-decls)
+mlir_tablegen(CIRAttrConstraints.cpp.inc -gen-type-constraint-defs)
+add_public_tablegen_target(MLIRCIRAttrConstraintsIncGen)
+add_dependencies(mlir-headers MLIRCIRAttrConstraintsIncGen)

>From 50ac7399fad695c2b387d72d4ea78232c4a0068a Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Thu, 5 Jun 2025 12:41:15 +0200
Subject: [PATCH 10/11] Remoe un needed cmake config

---
 clang/include/clang/CIR/Dialect/IR/CMakeLists.txt | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt 
b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
index 436c9aa85635c..6e7f3da4add3e 100644
--- a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
+++ b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
@@ -25,9 +25,3 @@ mlir_tablegen(CIRTypeConstraints.h.inc 
-gen-type-constraint-decls)
 mlir_tablegen(CIRTypeConstraints.cpp.inc -gen-type-constraint-defs)
 add_public_tablegen_target(MLIRCIRTypeConstraintsIncGen)
 add_dependencies(mlir-headers MLIRCIRTypeConstraintsIncGen)
-
-set(LLVM_TARGET_DEFINITIONS CIRAttrConstraints.td)
-mlir_tablegen(CIRAttrConstraints.h.inc -gen-type-constraint-decls)
-mlir_tablegen(CIRAttrConstraints.cpp.inc -gen-type-constraint-defs)
-add_public_tablegen_target(MLIRCIRAttrConstraintsIncGen)
-add_dependencies(mlir-headers MLIRCIRAttrConstraintsIncGen)

>From 187780a53f2a169a1747a0517cbbaf158741ce16 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Thu, 5 Jun 2025 17:57:08 +0200
Subject: [PATCH 11/11] Address code review comment

---
 clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td
index 4c873c4028d3e..382117938b2fe 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td
@@ -31,7 +31,8 @@ def CIR_AnyIntAttr : CIR_AttrConstraint<"::cir::IntAttr", 
"integer attribute">;
 // FPAttr constraints
 
//===----------------------------------------------------------------------===//
 
-def CIR_AnyFPAttr : CIR_AttrConstraint<"::cir::FPAttr", "floating-point 
attribute">;
+def CIR_AnyFPAttr : CIR_AttrConstraint<"::cir::FPAttr",
+  "floating-point attribute">;
 
 def CIR_AnyIntOrFloatAttr : AnyAttrOf<[CIR_AnyIntAttr, CIR_AnyFPAttr],
     "integer or floating point type"> {

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

Reply via email to