llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clangir

Author: Amr Hesham (AmrDeveloper)

<details>
<summary>Changes</summary>

This change adds local initialization for ArrayType

Issue #<!-- -->130197

---

Patch is 59.03 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/132974.diff


25 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h (+35) 
- (modified) clang/include/clang/CIR/Dialect/IR/CIRDialect.h (+25) 
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+44) 
- (added) clang/include/clang/CIR/LoweringHelpers.h (+40) 
- (modified) clang/lib/CIR/CodeGen/Address.h (+10) 
- (modified) clang/lib/CIR/CodeGen/CIRGenBuilder.h (+4) 
- (modified) clang/lib/CIR/CodeGen/CIRGenDecl.cpp (+1-1) 
- (added) clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp (+277) 
- (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+23) 
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+46) 
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.h (+8-4) 
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+12) 
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.h (+5) 
- (modified) clang/lib/CIR/CodeGen/CIRGenTypeCache.h (+13) 
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+24) 
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.h (+4) 
- (modified) clang/lib/CIR/CodeGen/CIRGenValue.h (+42-2) 
- (modified) clang/lib/CIR/CodeGen/CMakeLists.txt (+1) 
- (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+35-7) 
- (modified) clang/lib/CIR/Lowering/CMakeLists.txt (+1) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+109) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h (+15) 
- (added) clang/lib/CIR/Lowering/LoweringHelpers.cpp (+150) 
- (modified) clang/test/CIR/CodeGen/array.cpp (+91-6) 
- (modified) clang/test/CIR/Lowering/array.cpp (+72-5) 


``````````diff
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index c6aea10d46b63..4c7e6ec061d46 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -32,6 +32,11 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
     return create<cir::ConstantOp>(loc, attr.getType(), attr);
   }
 
+  // Creates constant null value for integral type ty.
+  cir::ConstantOp getNullValue(mlir::Type ty, mlir::Location loc) {
+    return create<cir::ConstantOp>(loc, ty, getZeroInitAttr(ty));
+  }
+
   cir::ConstantOp getBool(bool state, mlir::Location loc) {
     return create<cir::ConstantOp>(loc, getBoolTy(), getCIRBoolAttr(state));
   }
@@ -68,6 +73,36 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
         getContext(), mlir::cast<cir::PointerType>(type), valueAttr);
   }
 
+  mlir::TypedAttr getConstNullPtrAttr(mlir::Type t) {
+    assert(mlir::isa<cir::PointerType>(t) && "expected cir.ptr");
+    return getConstPtrAttr(t, 0);
+  }
+
+  mlir::TypedAttr getZeroAttr(mlir::Type t) {
+    return cir::ZeroAttr::get(getContext(), t);
+  }
+
+  mlir::TypedAttr getZeroInitAttr(mlir::Type ty) {
+    if (mlir::isa<cir::IntType>(ty))
+      return cir::IntAttr::get(ty, 0);
+    if (auto fltType = mlir::dyn_cast<cir::SingleType>(ty))
+      return cir::FPAttr::getZero(fltType);
+    if (auto fltType = mlir::dyn_cast<cir::DoubleType>(ty))
+      return cir::FPAttr::getZero(fltType);
+    if (auto fltType = mlir::dyn_cast<cir::FP16Type>(ty))
+      return cir::FPAttr::getZero(fltType);
+    if (auto fltType = mlir::dyn_cast<cir::BF16Type>(ty))
+      return cir::FPAttr::getZero(fltType);
+    if (auto arrTy = mlir::dyn_cast<cir::ArrayType>(ty))
+      return getZeroAttr(arrTy);
+    if (auto ptrTy = mlir::dyn_cast<cir::PointerType>(ty))
+      return getConstNullPtrAttr(ptrTy);
+    if (mlir::isa<cir::BoolType>(ty)) {
+      return getCIRBoolAttr(false);
+    }
+    llvm_unreachable("Zero initializer for given type is NYI");
+  }
+
   mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
                            mlir::Type type, llvm::StringRef name,
                            mlir::IntegerAttr alignment) {
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h 
b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h
index da3b41371b9ab..ba7bbedf4714e 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h
@@ -32,6 +32,31 @@
 #include "clang/CIR/Interfaces/CIRLoopOpInterface.h"
 #include "clang/CIR/Interfaces/CIROpInterfaces.h"
 
+namespace mlir {
+namespace OpTrait {
+
+namespace impl {
+// These functions are out-of-line implementations of the methods in the
+// corresponding trait classes.  This avoids them being template
+// instantiated/duplicated.
+LogicalResult verifySameFirstOperandAndResultType(Operation *op);
+} // namespace impl
+
+/// This class provides verification for ops that are known to have the same
+/// first operand and result type.
+///
+template <typename ConcreteType>
+class SameFirstOperandAndResultType
+    : public TraitBase<ConcreteType, SameFirstOperandAndResultType> {
+public:
+  static llvm::LogicalResult verifyTrait(Operation *op) {
+    return impl::verifySameFirstOperandAndResultType(op);
+  }
+};
+
+} // namespace OpTrait
+} // namespace mlir
+
 // TableGen'erated files for MLIR dialects require that a macro be defined when
 // they are included.  GET_OP_CLASSES tells the file to define the classes for
 // the operations of that dialect.
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index d7d63e040a2ba..7784c8a51fdf3 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -79,6 +79,13 @@ class LLVMLoweringInfo {
 class CIR_Op<string mnemonic, list<Trait> traits = []> :
     Op<CIR_Dialect, mnemonic, traits>, LLVMLoweringInfo;
 
+//===----------------------------------------------------------------------===//
+// CIR Op Traits
+//===----------------------------------------------------------------------===//
+
+def SameFirstOperandAndResultType :
+  NativeOpTrait<"SameFirstOperandAndResultType">;
+
 
//===----------------------------------------------------------------------===//
 // CastOp
 
//===----------------------------------------------------------------------===//
@@ -229,6 +236,43 @@ def CastOp : CIR_Op<"cast",
   let hasFolder = 1;
 }
 
+
+//===----------------------------------------------------------------------===//
+// PtrStrideOp
+//===----------------------------------------------------------------------===//
+
+def PtrStrideOp : CIR_Op<"ptr_stride",
+                         [Pure, SameFirstOperandAndResultType]> {
+  let summary = "Pointer access with stride";
+  let description = [{
+    Given a base pointer as first operand, provides a new pointer after 
applying
+    a stride (second operand).
+
+    ```mlir
+    %3 = cir.const 0 : i32
+    %4 = cir.ptr_stride(%2 : !cir.ptr<i32>, %3 : i32), !cir.ptr<i32>
+    ```
+  }];
+
+  let arguments = (ins CIR_PointerType:$base, PrimitiveInt:$stride);
+  let results = (outs CIR_PointerType:$result);
+
+  let assemblyFormat = [{
+    `(` $base `:` qualified(type($base)) `,` $stride `:` 
qualified(type($stride)) `)`
+    `,` qualified(type($result)) attr-dict
+  }];
+
+  let extraClassDeclaration = [{
+    // Get type pointed by the base pointer.
+    mlir::Type getElementTy() {
+      return mlir::cast<cir::PointerType>(getBase().getType()).getPointee();
+    }
+  }];
+
+  // SameFirstOperandAndResultType already checks all we need.
+  let hasVerifier = 0;
+}
+
 
//===----------------------------------------------------------------------===//
 // ConstantOp
 
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/LoweringHelpers.h 
b/clang/include/clang/CIR/LoweringHelpers.h
new file mode 100644
index 0000000000000..3077010ee5ffe
--- /dev/null
+++ b/clang/include/clang/CIR/LoweringHelpers.h
@@ -0,0 +1,40 @@
+//====- LoweringHelpers.h - Lowering helper functions 
---------------------===//
+//
+// 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 declares helper functions for lowering from CIR to LLVM or MLIR.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_CIR_LOWERINGHELPERS_H
+#define LLVM_CLANG_CIR_LOWERINGHELPERS_H
+
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/Transforms/DialectConversion.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+
+mlir::DenseElementsAttr
+convertStringAttrToDenseElementsAttr(cir::ConstArrayAttr attr, mlir::Type 
type);
+
+template <typename StorageTy> StorageTy getZeroInitFromType(mlir::Type ty);
+template <> mlir::APInt getZeroInitFromType(mlir::Type ty);
+template <> mlir::APFloat getZeroInitFromType(mlir::Type ty);
+
+template <typename AttrTy, typename StorageTy>
+void convertToDenseElementsAttrImpl(cir::ConstArrayAttr attr,
+                                    llvm::SmallVectorImpl<StorageTy> &values);
+
+template <typename AttrTy, typename StorageTy>
+mlir::DenseElementsAttr
+convertToDenseElementsAttr(cir::ConstArrayAttr attr,
+                           const llvm::SmallVectorImpl<int64_t> &dims,
+                           mlir::Type type);
+
+std::optional<mlir::Attribute>
+lowerConstArrayAttr(cir::ConstArrayAttr constArr,
+                    const mlir::TypeConverter *converter);
+
+#endif
diff --git a/clang/lib/CIR/CodeGen/Address.h b/clang/lib/CIR/CodeGen/Address.h
index fba1ffd90877b..2cc8ada783197 100644
--- a/clang/lib/CIR/CodeGen/Address.h
+++ b/clang/lib/CIR/CodeGen/Address.h
@@ -70,6 +70,14 @@ class Address {
     return pointerAndKnownNonNull.getPointer();
   }
 
+  mlir::Type getType() const {
+    assert(mlir::cast<cir::PointerType>(
+               pointerAndKnownNonNull.getPointer().getType())
+               .getPointee() == elementType);
+
+    return mlir::cast<cir::PointerType>(getPointer().getType());
+  }
+
   mlir::Type getElementType() const {
     assert(isValid());
     assert(mlir::cast<cir::PointerType>(
@@ -77,6 +85,8 @@ class Address {
                .getPointee() == elementType);
     return elementType;
   }
+
+  clang::CharUnits getAlignment() const { return alignment; }
 };
 
 } // namespace clang::CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index fef290612149a..d1a81f85b66fc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -83,6 +83,10 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
 
   bool isInt(mlir::Type i) { return mlir::isa<cir::IntType>(i); }
 
+  bool isInt8Ty(mlir::Type i) {
+    return i == typeCache.UInt8Ty || i == typeCache.SInt8Ty;
+  }
+
   // Creates constant nullptr for pointer type ty.
   cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc) {
     assert(!cir::MissingFeatures::targetCodeGenInfoGetNullPointer());
diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp 
b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
index a93e8dbcb42de..a0c6b832faa24 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
@@ -250,7 +250,7 @@ void CIRGenFunction::emitExprAsInit(const Expr *init, const 
ValueDecl *d,
     return;
   }
   case cir::TEK_Aggregate:
-    cgm.errorNYI(init->getSourceRange(), "emitExprAsInit: aggregate type");
+    emitAggExpr(init, AggValueSlot::forLValue(lvalue));
     return;
   }
   llvm_unreachable("bad evaluation kind");
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
new file mode 100644
index 0000000000000..3bd898422f4d6
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -0,0 +1,277 @@
+//===--- CIRGenExprAgg.cpp - Emit CIR Code from Aggregate Expressions 
-----===//
+//
+// 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 contains code to emit Aggregate Expr nodes as CIR code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIRGenBuilder.h"
+#include "CIRGenFunction.h"
+#include "CIRGenValue.h"
+#include "clang/CIR/Dialect/IR/CIRAttrs.h"
+
+#include "clang/AST/Expr.h"
+#include "clang/AST/StmtVisitor.h"
+#include <cstdint>
+
+using namespace clang;
+using namespace clang::CIRGen;
+
+namespace {
+class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
+
+  CIRGenFunction &cgf;
+  AggValueSlot dest;
+
+  AggValueSlot ensureSlot(mlir::Location loc, QualType t) {
+    if (!dest.isIgnored())
+      return dest;
+    llvm_unreachable("Slot for ignored address NTI");
+  }
+
+public:
+  AggExprEmitter(CIRGenFunction &cgf, AggValueSlot dest)
+      : cgf(cgf), dest(dest) {}
+
+  void emitArrayInit(Address destPtr, cir::ArrayType arrayTy, QualType 
arrayQTy,
+                     Expr *exprToVisit, ArrayRef<Expr *> args,
+                     Expr *arrayFiller);
+
+  void emitInitializationToLValue(Expr *e, LValue lv);
+
+  void emitNullInitializationToLValue(mlir::Location loc, LValue lv);
+
+  void Visit(Expr *e) { StmtVisitor<AggExprEmitter>::Visit(e); }
+
+  void VisitInitListExpr(InitListExpr *e);
+
+  void visitCXXParenListOrInitListExpr(Expr *e, ArrayRef<Expr *> args,
+                                       FieldDecl *initializedFieldInUnion,
+                                       Expr *arrayFiller);
+};
+
+} // namespace
+
+static bool isTrivialFiller(Expr *e) {
+  if (!e)
+    return true;
+
+  if (isa<ImplicitValueInitExpr>(e))
+    return true;
+
+  if (auto *ile = dyn_cast<InitListExpr>(e)) {
+    if (ile->getNumInits())
+      return false;
+    return isTrivialFiller(ile->getArrayFiller());
+  }
+
+  if (const auto *cons = dyn_cast_or_null<CXXConstructExpr>(e))
+    return cons->getConstructor()->isDefaultConstructor() &&
+           cons->getConstructor()->isTrivial();
+
+  return false;
+}
+
+void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy,
+                                   QualType arrayQTy, Expr *e,
+                                   ArrayRef<Expr *> args, Expr *arrayFiller) {
+  CIRGenBuilderTy &builder = cgf.getBuilder();
+  const mlir::Location loc = cgf.getLoc(e->getSourceRange());
+
+  const uint64_t numInitElements = args.size();
+
+  const QualType elementType =
+      cgf.getContext().getAsArrayType(arrayQTy)->getElementType();
+
+  if (elementType.isDestructedType()) {
+    llvm_unreachable("dtorKind NYI");
+  }
+
+  const QualType elementPtrType = cgf.getContext().getPointerType(elementType);
+
+  const mlir::Type cirElementType = cgf.convertType(elementType);
+  const cir::PointerType cirElementPtrType =
+      builder.getPointerTo(cirElementType);
+
+  auto begin = builder.create<cir::CastOp>(loc, cirElementPtrType,
+                                           cir::CastKind::array_to_ptrdecay,
+                                           destPtr.getPointer());
+
+  const CharUnits elementSize =
+      cgf.getContext().getTypeSizeInChars(elementType);
+  const CharUnits elementAlign =
+      destPtr.getAlignment().alignmentOfArrayElement(elementSize);
+
+  // The 'current element to initialize'.  The invariants on this
+  // variable are complicated.  Essentially, after each iteration of
+  // the loop, it points to the last initialized element, except
+  // that it points to the beginning of the array before any
+  // elements have been initialized.
+  mlir::Value element = begin;
+
+  // Don't build the 'one' before the cycle to avoid
+  // emmiting the redundant `cir.const 1` instrs.
+  mlir::Value one;
+
+  // Emit the explicit initializers.
+  for (uint64_t i = 0; i != numInitElements; ++i) {
+    // Advance to the next element.
+    if (i > 0) {
+      one = builder.create<cir::ConstantOp>(
+          loc, cgf.PtrDiffTy, cir::IntAttr::get(cgf.PtrDiffTy, i));
+      element =
+          builder.create<cir::PtrStrideOp>(loc, cirElementPtrType, begin, one);
+    }
+
+    const Address address = Address(element, cirElementType, elementAlign);
+    const LValue elementLV = LValue::makeAddr(address, elementType);
+    emitInitializationToLValue(args[i], elementLV);
+  }
+
+  const uint64_t numArrayElements = arrayTy.getSize();
+
+  // Check whether there's a non-trivial array-fill expression.
+  const bool hasTrivialFiller = isTrivialFiller(arrayFiller);
+
+  // Any remaining elements need to be zero-initialized, possibly
+  // using the filler expression.  We can skip this if the we're
+  // emitting to zeroed memory.
+  if (numInitElements != numArrayElements &&
+      !(dest.isZeroed() && hasTrivialFiller &&
+        cgf.getTypes().isZeroInitializable(elementType))) {
+    // Advance to the start of the rest of the array.
+    if (numInitElements) {
+      one = builder.create<cir::ConstantOp>(
+          loc, cgf.PtrDiffTy, cir::IntAttr::get(cgf.PtrDiffTy, 1));
+      element = builder.create<cir::PtrStrideOp>(loc, cirElementPtrType,
+                                                 element, one);
+    }
+
+    // Allocate the temporary variable
+    // to store the pointer to first unitialized element
+    auto tmpAddr = cgf.createTempAlloca(
+        cirElementPtrType, cgf.getPointerAlign(), loc, "arrayinit.temp");
+    LValue tmpLV = LValue::makeAddr(tmpAddr, elementPtrType);
+    cgf.emitStoreThroughLValue(RValue::get(element), tmpLV);
+
+    // TODO:Replace this part later with cir::DoWhileOp
+    for (unsigned i = numInitElements; i != numArrayElements; ++i) {
+      auto currentElement = builder.createLoad(loc, tmpAddr.getPointer());
+
+      // Emit the actual filler expression.
+      const LValue elementLV = LValue::makeAddr(
+          Address(currentElement, cirElementType, elementAlign), elementType);
+
+      if (arrayFiller)
+        emitInitializationToLValue(arrayFiller, elementLV);
+      else
+        emitNullInitializationToLValue(loc, elementLV);
+
+      // Advance pointer and store them to temporary variable
+      one = builder.create<cir::ConstantOp>(
+          loc, cgf.PtrDiffTy, cir::IntAttr::get(cgf.PtrDiffTy, 1));
+
+      auto nextElement = builder.create<cir::PtrStrideOp>(
+          loc, cirElementPtrType, currentElement, one);
+      cgf.emitStoreThroughLValue(RValue::get(nextElement), tmpLV);
+    }
+  }
+}
+
+void AggExprEmitter::emitInitializationToLValue(Expr *e, LValue lv) {
+  const QualType type = lv.getType();
+
+  if (isa<ImplicitValueInitExpr, CXXScalarValueInitExpr>(e)) {
+    const auto loc = e->getSourceRange().isValid()
+                         ? cgf.getLoc(e->getSourceRange())
+                         : *cgf.currSrcLoc;
+    return emitNullInitializationToLValue(loc, lv);
+  }
+
+  if (isa<NoInitExpr>(e))
+    return;
+
+  if (type->isReferenceType()) {
+    llvm_unreachable("NTI");
+  }
+
+  switch (cgf.getEvaluationKind(type)) {
+  case cir::TEK_Complex:
+    llvm_unreachable("TEK_Complex NYI");
+    break;
+  case cir::TEK_Aggregate:
+    cgf.emitAggExpr(e, AggValueSlot::forLValue(lv));
+    return;
+  case cir::TEK_Scalar:
+    if (lv.isSimple())
+      cgf.emitScalarInit(e, cgf.getLoc(e->getSourceRange()), lv);
+    else
+      cgf.emitStoreThroughLValue(RValue::get(cgf.emitScalarExpr(e)), lv);
+    return;
+  }
+}
+
+void AggExprEmitter::emitNullInitializationToLValue(mlir::Location loc,
+                                                    LValue lv) {
+  const QualType type = lv.getType();
+
+  // If the destination slot is already zeroed out before the aggregate is
+  // copied into it, we don't have to emit any zeros here.
+  if (dest.isZeroed() && cgf.getTypes().isZeroInitializable(type))
+    return;
+
+  if (cgf.hasScalarEvaluationKind(type)) {
+    // For non-aggregates, we can store the appropriate null constant.
+    auto null = cgf.cgm.emitNullConstant(type, loc);
+    if (lv.isSimple()) {
+      cgf.emitStoreOfScalar(null, lv, /* isInitialization */ true);
+      return;
+    }
+
+    llvm_unreachable("emitStoreThroughBitfieldLValue NYI");
+    return;
+  }
+
+  // There's a potential optimization opportunity in combining
+  // memsets; that would be easy for arrays, but relatively
+  // difficult for structures with the current code.
+  cgf.emitNullInitialization(loc, lv.getAddress(), lv.getType());
+}
+
+void AggExprEmitter::VisitInitListExpr(InitListExpr *e) {
+  if (e->hadArrayRangeDesignator())
+    llvm_unreachable("GNU array range designator extension");
+
+  if (e->isTransparent())
+    return Visit(e->getInit(0));
+
+  visitCXXParenListOrInitListExpr(
+      e, e->inits(), e->getInitializedFieldInUnion(), e->getArrayFiller());
+}
+
+void AggExprEmitter::visitCXXParenListOrInitListExpr(
+    Expr *e, ArrayRef<Expr *> args, FieldDecl *initializedFieldInUnion,
+    Expr *arrayFiller) {
+
+  const AggValueSlot dest =
+      ensureSlot(cgf.getLoc(e->getSourceRange()), e->getType());
+
+  if (e->getType()->isConstantArrayType()) {
+    cir::ArrayType arrayTy =
+        cast<cir::ArrayType>(dest.getAddress().getElementType());
+    emitArrayInit(dest.getAddress(), arrayTy, e->getType(), e, args,
+                  arrayFiller);
+    return;
+  }
+
+  llvm_unreachable("NYI");
+}
+
+void CIRGenFunction::emitAggExpr(const Expr *e, AggValueSlot slot) {
+  AggExprEmitter(*this, slot).Visit(const_cast<Expr *>(e));
+}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index fc49d6da97206..06fcc0e2c040a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -412,3 +412,26 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const 
APValue &value,
   }
   llvm_unreachable("Unknown APValue kind");
 }
+
+mlir::Value CIRGenModule::emitNullConstant(QualType t, mlir::Location loc) {
+  if (t->getAs<PointerType>()) {
+    return builder.getNullPtr(getTypes().convertTypeForM...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/132974
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to