https://github.com/llvm-beanz updated 
https://github.com/llvm/llvm-project/pull/133508

>From 6234f442adfebaaf73328d2c09ee443facc848b0 Mon Sep 17 00:00:00 2001
From: Chris Bieneman <chris.biene...@me.com>
Date: Thu, 27 Mar 2025 09:26:31 -0500
Subject: [PATCH 1/4] [HLSL] Handle incomplete array types

This refactors the initialization list transformation code to handle
incomplete array types.

Fixes #132958

../clang/test/SemaHLSL/Language/InitIncompleteArrays.hlsl
---
 clang/lib/Sema/SemaHLSL.cpp                   | 131 ++++++++++++------
 .../Language/InitIncompleteArrays.hlsl        |  53 +++++++
 clang/test/SemaHLSL/Language/InitListAST.hlsl |  78 +++++++++++
 3 files changed, 222 insertions(+), 40 deletions(-)
 create mode 100644 clang/test/SemaHLSL/Language/InitIncompleteArrays.hlsl

diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 07d03e2c58b9a..cad8aa4ed0dec 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3249,33 +3249,42 @@ void SemaHLSL::processExplicitBindingsOnDecl(VarDecl 
*VD) {
     }
   }
 }
+namespace {
+class InitListTransformer {
+  Sema &S;
+  ASTContext &Ctx;
+  QualType InitTy;
+  QualType *DstIt = nullptr;
+  Expr **ArgIt = nullptr;
+  bool Wrap;
 
-static bool CastInitializer(Sema &S, ASTContext &Ctx, Expr *E,
-                            llvm::SmallVectorImpl<Expr *> &List,
-                            llvm::SmallVectorImpl<QualType> &DestTypes) {
-  if (List.size() >= DestTypes.size()) {
-    List.push_back(E);
-    // This is odd, but it isn't technically a failure due to conversion, we
-    // handle mismatched counts of arguments differently.
-    return true;
+ bool castInitializer(Expr *E) {
+  assert(DstIt && "This should always be something!");
+  if (DstIt == DestTypes.end()) {
+    if (!Wrap) {
+      ArgExprs.push_back(E);
+      // This is odd, but it isn't technically a failure due to conversion, we
+      // handle mismatched counts of arguments differently.
+      return true;
+    }
+    DstIt = DestTypes.begin();
   }
-  InitializedEntity Entity = InitializedEntity::InitializeParameter(
-      Ctx, DestTypes[List.size()], false);
+  InitializedEntity Entity =
+      InitializedEntity::InitializeParameter(Ctx, *DstIt, true);
   ExprResult Res = S.PerformCopyInitialization(Entity, E->getBeginLoc(), E);
   if (Res.isInvalid())
     return false;
   Expr *Init = Res.get();
-  List.push_back(Init);
+  ArgExprs.push_back(Init);
+  DstIt++;
   return true;
 }
 
-static bool BuildInitializerList(Sema &S, ASTContext &Ctx, Expr *E,
-                                 llvm::SmallVectorImpl<Expr *> &List,
-                                 llvm::SmallVectorImpl<QualType> &DestTypes) {
+bool buildInitializerListImpl(Expr *E) {
   // If this is an initialization list, traverse the sub initializers.
   if (auto *Init = dyn_cast<InitListExpr>(E)) {
     for (auto *SubInit : Init->inits())
-      if (!BuildInitializerList(S, Ctx, SubInit, List, DestTypes))
+      if (!buildInitializerListImpl(SubInit))
         return false;
     return true;
   }
@@ -3284,7 +3293,7 @@ static bool BuildInitializerList(Sema &S, ASTContext 
&Ctx, Expr *E,
   QualType Ty = E->getType();
 
   if (Ty->isScalarType() || (Ty->isRecordType() && !Ty->isAggregateType()))
-    return CastInitializer(S, Ctx, E, List, DestTypes);
+    return castInitializer(E);
 
   if (auto *VecTy = Ty->getAs<VectorType>()) {
     uint64_t Size = VecTy->getNumElements();
@@ -3299,7 +3308,7 @@ static bool BuildInitializerList(Sema &S, ASTContext 
&Ctx, Expr *E,
           E, E->getBeginLoc(), Idx, E->getEndLoc());
       if (ElExpr.isInvalid())
         return false;
-      if (!CastInitializer(S, Ctx, ElExpr.get(), List, DestTypes))
+      if (!castInitializer(ElExpr.get()))
         return false;
     }
     return true;
@@ -3316,7 +3325,7 @@ static bool BuildInitializerList(Sema &S, ASTContext 
&Ctx, Expr *E,
           E, E->getBeginLoc(), Idx, E->getEndLoc());
       if (ElExpr.isInvalid())
         return false;
-      if (!BuildInitializerList(S, Ctx, ElExpr.get(), List, DestTypes))
+      if (!buildInitializerListImpl(ElExpr.get()))
         return false;
     }
     return true;
@@ -3341,7 +3350,7 @@ static bool BuildInitializerList(Sema &S, ASTContext 
&Ctx, Expr *E,
             E, false, E->getBeginLoc(), CXXScopeSpec(), FD, Found, NameInfo);
         if (Res.isInvalid())
           return false;
-        if (!BuildInitializerList(S, Ctx, Res.get(), List, DestTypes))
+        if (!buildInitializerListImpl(Res.get()))
           return false;
       }
     }
@@ -3349,11 +3358,11 @@ static bool BuildInitializerList(Sema &S, ASTContext 
&Ctx, Expr *E,
   return true;
 }
 
-static Expr *GenerateInitLists(ASTContext &Ctx, QualType Ty,
-                               llvm::SmallVectorImpl<Expr *>::iterator &It) {
-  if (Ty->isScalarType() || (Ty->isRecordType() && !Ty->isAggregateType())) {
-    return *(It++);
-  }
+Expr *generateInitListsImpl(QualType Ty) {
+  assert(ArgIt != ArgExprs.end() && "Something is off in iteration!");
+  if (Ty->isScalarType() || (Ty->isRecordType() && !Ty->isAggregateType()))
+    return *(ArgIt++);
+
   llvm::SmallVector<Expr *> Inits;
   assert(!isa<MatrixType>(Ty) && "Matrix types not yet supported in HLSL");
   Ty = Ty.getDesugaredType(Ctx);
@@ -3369,7 +3378,7 @@ static Expr *GenerateInitLists(ASTContext &Ctx, QualType 
Ty,
       Size = VTy->getZExtSize();
     }
     for (uint64_t I = 0; I < Size; ++I)
-      Inits.push_back(GenerateInitLists(Ctx, ElTy, It));
+      Inits.push_back(generateInitListsImpl(ElTy));
   }
   if (auto *RTy = Ty->getAs<RecordType>()) {
     llvm::SmallVector<const RecordType *> RecordTypes;
@@ -3384,7 +3393,7 @@ static Expr *GenerateInitLists(ASTContext &Ctx, QualType 
Ty,
       const RecordType *RT = RecordTypes.back();
       RecordTypes.pop_back();
       for (auto *FD : RT->getDecl()->fields()) {
-        Inits.push_back(GenerateInitLists(Ctx, FD->getType(), It));
+        Inits.push_back(generateInitListsImpl(FD->getType()));
       }
     }
   }
@@ -3393,6 +3402,43 @@ static Expr *GenerateInitLists(ASTContext &Ctx, QualType 
Ty,
   NewInit->setType(Ty);
   return NewInit;
 }
+public:
+llvm::SmallVector<QualType, 16> DestTypes;
+  llvm::SmallVector<Expr *, 16> ArgExprs;
+  InitListTransformer(Sema &SemaRef, const InitializedEntity &Entity)
+      : S(SemaRef), Ctx(SemaRef.getASTContext()),
+        Wrap(Entity.getType()->isIncompleteArrayType()) {
+    InitTy = Entity.getType().getNonReferenceType();
+    // When we're generating initializer lists for incomplete array types we
+    // need to wrap around both when building the initializers and when
+    // generating the final initializer lists.
+    if (Wrap)
+      InitTy = QualType(InitTy->getBaseElementTypeUnsafe(),0);
+    BuildFlattenedTypeList(InitTy, DestTypes);
+    DstIt = DestTypes.begin();
+  }
+
+  bool buildInitializerList(Expr *E) {
+    return buildInitializerListImpl(E);
+  }
+
+  Expr *generateInitLists() {
+    ArgIt = ArgExprs.begin();
+    if (!Wrap)
+      return generateInitListsImpl(InitTy);
+    llvm::SmallVector<Expr *> Inits;
+    while (ArgIt != ArgExprs.end())
+      Inits.push_back(generateInitListsImpl(InitTy));
+
+    auto *NewInit = new (Ctx) InitListExpr(Ctx, Inits.front()->getBeginLoc(),
+                                           Inits, Inits.back()->getEndLoc());
+    llvm::APInt ArySize(64, Inits.size());
+    NewInit->setType(Ctx.getConstantArrayType(InitTy, ArySize, nullptr,
+                                              ArraySizeModifier::Normal, 0));
+    return NewInit;
+  }
+};
+}
 
 bool SemaHLSL::TransformInitList(const InitializedEntity &Entity,
                                  const InitializationKind &Kind,
@@ -3401,14 +3447,8 @@ bool SemaHLSL::TransformInitList(const InitializedEntity 
&Entity,
   if (Init->getType()->isScalarType())
     return true;
   ASTContext &Ctx = SemaRef.getASTContext();
-  llvm::SmallVector<QualType, 16> DestTypes;
-  // An initializer list might be attempting to initialize a reference or
-  // rvalue-reference. When checking the initializer we should look through the
-  // reference.
-  QualType InitTy = Entity.getType().getNonReferenceType();
-  BuildFlattenedTypeList(InitTy, DestTypes);
+  InitListTransformer ILT(SemaRef, Entity);
 
-  llvm::SmallVector<Expr *, 16> ArgExprs;
   for (unsigned I = 0; I < Init->getNumInits(); ++I) {
     Expr *E = Init->getInit(I);
     if (E->HasSideEffects(Ctx)) {
@@ -3419,21 +3459,32 @@ bool SemaHLSL::TransformInitList(const 
InitializedEntity &Entity,
                                     E->getObjectKind(), E);
       Init->setInit(I, E);
     }
-    if (!BuildInitializerList(SemaRef, Ctx, E, ArgExprs, DestTypes))
+    if (!ILT.buildInitializerList(E))
       return false;
   }
+  size_t ExpectedSize = ILT.DestTypes.size();
+  size_t ActualSize = ILT.ArgExprs.size();
+  // For incomplete arrays it is completely arbitrary to choose whether we 
think
+  // the user intended fewer or more elements. This implementation assumes that
+  // the user intended more, and errors that there are too few initializers to
+  // complete the final element.
+  if (Entity.getType()->isIncompleteArrayType())
+    ExpectedSize = ((ActualSize + ExpectedSize - 1) / ExpectedSize) * 
ExpectedSize;
 
-  if (DestTypes.size() != ArgExprs.size()) {
-    int TooManyOrFew = ArgExprs.size() > DestTypes.size() ? 1 : 0;
+  // An initializer list might be attempting to initialize a reference or
+  // rvalue-reference. When checking the initializer we should look through
+  // the reference.
+  QualType InitTy = Entity.getType().getNonReferenceType();
+  if (ExpectedSize != ActualSize) {
+    int TooManyOrFew = ActualSize > ExpectedSize ? 1 : 0;
     SemaRef.Diag(Init->getBeginLoc(), 
diag::err_hlsl_incorrect_num_initializers)
-        << TooManyOrFew << InitTy << DestTypes.size() << ArgExprs.size();
+        << TooManyOrFew << InitTy << ExpectedSize << ActualSize;
     return false;
   }
 
-  auto It = ArgExprs.begin();
-  // GenerateInitLists will always return an InitListExpr here, because the
+  // generateInitListsImpl will always return an InitListExpr here, because the
   // scalar case is handled above.
-  auto *NewInit = cast<InitListExpr>(GenerateInitLists(Ctx, InitTy, It));
+  auto *NewInit = cast<InitListExpr>(ILT.generateInitLists());
   Init->resizeInits(Ctx, NewInit->getNumInits());
   for (unsigned I = 0; I < NewInit->getNumInits(); ++I)
     Init->updateInit(Ctx, I, NewInit->getInit(I));
diff --git a/clang/test/SemaHLSL/Language/InitIncompleteArrays.hlsl 
b/clang/test/SemaHLSL/Language/InitIncompleteArrays.hlsl
new file mode 100644
index 0000000000000..15a991a45a6c4
--- /dev/null
+++ b/clang/test/SemaHLSL/Language/InitIncompleteArrays.hlsl
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute 
-finclude-default-header -verify -Wdouble-promotion -Wconversion %s
+
+// Some helpers!
+template <typename T, typename U>
+struct is_same {
+  static const bool value = false;
+};
+
+template <typename T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
+
+struct SomeVals {
+    int2 X;
+    float2 Y;
+    double2 D;
+};
+
+static SomeVals V = {1,2,3,4,5,6};
+
+static int2 SomeArr[] = {V}; // #SomeArr
+// expected-warning@#SomeArr 2 {{implicit conversion turns floating-point 
number into integer: 'double' to 'int'}}
+// expected-warning@#SomeArr 2 {{implicit conversion turns floating-point 
number into integer: 'float' to 'int'}}
+
+_Static_assert(is_same<__decltype(SomeArr), int2[3]>::value, "What is this 
even?");
+
+static int2 VecArr[] = {
+    int2(0,1),
+    int2(2,3),
+    int4(4,5,6,7),
+    };
+
+_Static_assert(is_same<__decltype(VecArr), int2[4]>::value, "One vec, two vec, 
three vecs, FOUR!");
+
+static int4 V4Arr[] = {
+  int2(0,1),
+  int2(2,3),
+};
+
+_Static_assert(is_same<__decltype(V4Arr), int4[1]>::value, "One!");
+
+// expected-error@+1{{too few initializers in list for type 'int4[]' (aka 
'vector<int, 4>[]') (expected 4 but found 2)}}
+static int4 V4ArrTooSmall[] = {
+  int2(0,1),
+};
+
+// expected-error@+1{{too few initializers in list for type 'int4[]' (aka 
'vector<int, 4>[]') (expected 8 but found 7)}}
+static int4 V4ArrAlsoTooSmall[] = {
+  int2(0,1),
+  int2(2,3),
+  int3(4,5,6),
+};
diff --git a/clang/test/SemaHLSL/Language/InitListAST.hlsl 
b/clang/test/SemaHLSL/Language/InitListAST.hlsl
index d58582f9029fe..78bf269769ae6 100644
--- a/clang/test/SemaHLSL/Language/InitListAST.hlsl
+++ b/clang/test/SemaHLSL/Language/InitListAST.hlsl
@@ -8,6 +8,11 @@ struct TwoInts {
   int Z, W;
 };
 
+struct IntAndFloat {
+  int A;
+  float B;
+};
+
 struct Doggo {
   int4 LegState;
   int TailState;
@@ -981,3 +986,76 @@ FourFloats case16() {
     FourFloats FF = {0, makeTwo(X), 3};
     return FF;
 }
+
+// CHECK-LABEL: Dumping case17
+// CHECK: VarDecl {{.*}} col:15 used Structs 'IntAndFloat[2]' cinit
+// CHECK-NEXT: InitListExpr {{.*}} 'IntAndFloat[2]'
+// CHECK-NEXT: InitListExpr {{.*}} 'IntAndFloat'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <IntegralToFloating>
+// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2
+// CHECK-NEXT: InitListExpr {{.*}} 'IntAndFloat'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <IntegralToFloating>
+// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 4
+
+
+// CHECK: VarDecl {{.*}} col:9 used Floats 'float[8]' cinit
+// CHECK-NEXT: InitListExpr {{.*}} 'float[8]'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <IntegralToFloating>
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
+// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue .A {{.*}}
+// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'IntAndFloat' lvalue
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'IntAndFloat *' <ArrayToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'IntAndFloat[2]' lvalue Var {{.*}} 'Structs' 
'IntAndFloat[2]'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <LValueToRValue>
+// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .B {{.*}}
+// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'IntAndFloat' lvalue
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'IntAndFloat *' <ArrayToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'IntAndFloat[2]' lvalue Var {{.*}} 'Structs' 
'IntAndFloat[2]'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <IntegralToFloating>
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
+// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue .A {{.*}}
+// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'IntAndFloat' lvalue
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'IntAndFloat *' <ArrayToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'IntAndFloat[2]' lvalue Var {{.*}} 'Structs' 
'IntAndFloat[2]'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <LValueToRValue>
+// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .B {{.*}}
+// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'IntAndFloat' lvalue
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'IntAndFloat *' <ArrayToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'IntAndFloat[2]' lvalue Var {{.*}} 'Structs' 
'IntAndFloat[2]'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <IntegralToFloating>
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
+// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue .A {{.*}}
+// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'IntAndFloat' lvalue
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'IntAndFloat *' <ArrayToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'IntAndFloat[2]' lvalue Var {{.*}} 'Structs' 
'IntAndFloat[2]'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <LValueToRValue>
+// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .B {{.*}}
+// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'IntAndFloat' lvalue
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'IntAndFloat *' <ArrayToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'IntAndFloat[2]' lvalue Var {{.*}} 'Structs' 
'IntAndFloat[2]'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <IntegralToFloating>
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
+// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue .A {{.*}}
+// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'IntAndFloat' lvalue
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'IntAndFloat *' <ArrayToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'IntAndFloat[2]' lvalue Var {{.*}} 'Structs' 
'IntAndFloat[2]'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <LValueToRValue>
+// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .B {{.*}}
+// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'IntAndFloat' lvalue
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'IntAndFloat *' <ArrayToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'IntAndFloat[2]' lvalue Var {{.*}} 'Structs' 
'IntAndFloat[2]'
+// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1
+float case17() {
+  IntAndFloat Structs[] = {1,2,3,4};
+  float Floats[] = {Structs, Structs};
+  return Floats[7];
+}

>From 279cb38890fa933250d0ea2cdfa04aeed6f374dc Mon Sep 17 00:00:00 2001
From: Chris Bieneman <chris.biene...@me.com>
Date: Fri, 28 Mar 2025 15:23:24 -0500
Subject: [PATCH 2/4] Fix formatting

---
 clang/lib/Sema/SemaHLSL.cpp | 262 ++++++++++++++++++------------------
 1 file changed, 131 insertions(+), 131 deletions(-)

diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index cad8aa4ed0dec..36f1ec6dd3d50 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3258,152 +3258,153 @@ class InitListTransformer {
   Expr **ArgIt = nullptr;
   bool Wrap;
 
- bool castInitializer(Expr *E) {
-  assert(DstIt && "This should always be something!");
-  if (DstIt == DestTypes.end()) {
-    if (!Wrap) {
-      ArgExprs.push_back(E);
-      // This is odd, but it isn't technically a failure due to conversion, we
-      // handle mismatched counts of arguments differently.
-      return true;
+  bool castInitializer(Expr *E) {
+    assert(DstIt && "This should always be something!");
+    if (DstIt == DestTypes.end()) {
+      if (!Wrap) {
+        ArgExprs.push_back(E);
+        // This is odd, but it isn't technically a failure due to conversion, 
we
+        // handle mismatched counts of arguments differently.
+        return true;
+      }
+      DstIt = DestTypes.begin();
     }
-    DstIt = DestTypes.begin();
-  }
-  InitializedEntity Entity =
-      InitializedEntity::InitializeParameter(Ctx, *DstIt, true);
-  ExprResult Res = S.PerformCopyInitialization(Entity, E->getBeginLoc(), E);
-  if (Res.isInvalid())
-    return false;
-  Expr *Init = Res.get();
-  ArgExprs.push_back(Init);
-  DstIt++;
-  return true;
-}
-
-bool buildInitializerListImpl(Expr *E) {
-  // If this is an initialization list, traverse the sub initializers.
-  if (auto *Init = dyn_cast<InitListExpr>(E)) {
-    for (auto *SubInit : Init->inits())
-      if (!buildInitializerListImpl(SubInit))
-        return false;
+    InitializedEntity Entity =
+        InitializedEntity::InitializeParameter(Ctx, *DstIt, true);
+    ExprResult Res = S.PerformCopyInitialization(Entity, E->getBeginLoc(), E);
+    if (Res.isInvalid())
+      return false;
+    Expr *Init = Res.get();
+    ArgExprs.push_back(Init);
+    DstIt++;
     return true;
   }
 
-  // If this is a scalar type, just enqueue the expression.
-  QualType Ty = E->getType();
+  bool buildInitializerListImpl(Expr *E) {
+    // If this is an initialization list, traverse the sub initializers.
+    if (auto *Init = dyn_cast<InitListExpr>(E)) {
+      for (auto *SubInit : Init->inits())
+        if (!buildInitializerListImpl(SubInit))
+          return false;
+      return true;
+    }
 
-  if (Ty->isScalarType() || (Ty->isRecordType() && !Ty->isAggregateType()))
-    return castInitializer(E);
+    // If this is a scalar type, just enqueue the expression.
+    QualType Ty = E->getType();
 
-  if (auto *VecTy = Ty->getAs<VectorType>()) {
-    uint64_t Size = VecTy->getNumElements();
+    if (Ty->isScalarType() || (Ty->isRecordType() && !Ty->isAggregateType()))
+      return castInitializer(E);
 
-    QualType SizeTy = Ctx.getSizeType();
-    uint64_t SizeTySize = Ctx.getTypeSize(SizeTy);
-    for (uint64_t I = 0; I < Size; ++I) {
-      auto *Idx = IntegerLiteral::Create(Ctx, llvm::APInt(SizeTySize, I),
-                                         SizeTy, SourceLocation());
+    if (auto *VecTy = Ty->getAs<VectorType>()) {
+      uint64_t Size = VecTy->getNumElements();
 
-      ExprResult ElExpr = S.CreateBuiltinArraySubscriptExpr(
-          E, E->getBeginLoc(), Idx, E->getEndLoc());
-      if (ElExpr.isInvalid())
-        return false;
-      if (!castInitializer(ElExpr.get()))
-        return false;
-    }
-    return true;
-  }
+      QualType SizeTy = Ctx.getSizeType();
+      uint64_t SizeTySize = Ctx.getTypeSize(SizeTy);
+      for (uint64_t I = 0; I < Size; ++I) {
+        auto *Idx = IntegerLiteral::Create(Ctx, llvm::APInt(SizeTySize, I),
+                                           SizeTy, SourceLocation());
 
-  if (auto *ArrTy = dyn_cast<ConstantArrayType>(Ty.getTypePtr())) {
-    uint64_t Size = ArrTy->getZExtSize();
-    QualType SizeTy = Ctx.getSizeType();
-    uint64_t SizeTySize = Ctx.getTypeSize(SizeTy);
-    for (uint64_t I = 0; I < Size; ++I) {
-      auto *Idx = IntegerLiteral::Create(Ctx, llvm::APInt(SizeTySize, I),
-                                         SizeTy, SourceLocation());
-      ExprResult ElExpr = S.CreateBuiltinArraySubscriptExpr(
-          E, E->getBeginLoc(), Idx, E->getEndLoc());
-      if (ElExpr.isInvalid())
-        return false;
-      if (!buildInitializerListImpl(ElExpr.get()))
-        return false;
+        ExprResult ElExpr = S.CreateBuiltinArraySubscriptExpr(
+            E, E->getBeginLoc(), Idx, E->getEndLoc());
+        if (ElExpr.isInvalid())
+          return false;
+        if (!castInitializer(ElExpr.get()))
+          return false;
+      }
+      return true;
     }
-    return true;
-  }
 
-  if (auto *RTy = Ty->getAs<RecordType>()) {
-    llvm::SmallVector<const RecordType *> RecordTypes;
-    RecordTypes.push_back(RTy);
-    while (RecordTypes.back()->getAsCXXRecordDecl()->getNumBases()) {
-      CXXRecordDecl *D = RecordTypes.back()->getAsCXXRecordDecl();
-      assert(D->getNumBases() == 1 &&
-             "HLSL doesn't support multiple inheritance");
-      RecordTypes.push_back(D->bases_begin()->getType()->getAs<RecordType>());
-    }
-    while (!RecordTypes.empty()) {
-      const RecordType *RT = RecordTypes.back();
-      RecordTypes.pop_back();
-      for (auto *FD : RT->getDecl()->fields()) {
-        DeclAccessPair Found = DeclAccessPair::make(FD, FD->getAccess());
-        DeclarationNameInfo NameInfo(FD->getDeclName(), E->getBeginLoc());
-        ExprResult Res = S.BuildFieldReferenceExpr(
-            E, false, E->getBeginLoc(), CXXScopeSpec(), FD, Found, NameInfo);
-        if (Res.isInvalid())
+    if (auto *ArrTy = dyn_cast<ConstantArrayType>(Ty.getTypePtr())) {
+      uint64_t Size = ArrTy->getZExtSize();
+      QualType SizeTy = Ctx.getSizeType();
+      uint64_t SizeTySize = Ctx.getTypeSize(SizeTy);
+      for (uint64_t I = 0; I < Size; ++I) {
+        auto *Idx = IntegerLiteral::Create(Ctx, llvm::APInt(SizeTySize, I),
+                                           SizeTy, SourceLocation());
+        ExprResult ElExpr = S.CreateBuiltinArraySubscriptExpr(
+            E, E->getBeginLoc(), Idx, E->getEndLoc());
+        if (ElExpr.isInvalid())
           return false;
-        if (!buildInitializerListImpl(Res.get()))
+        if (!buildInitializerListImpl(ElExpr.get()))
           return false;
       }
+      return true;
     }
+
+    if (auto *RTy = Ty->getAs<RecordType>()) {
+      llvm::SmallVector<const RecordType *> RecordTypes;
+      RecordTypes.push_back(RTy);
+      while (RecordTypes.back()->getAsCXXRecordDecl()->getNumBases()) {
+        CXXRecordDecl *D = RecordTypes.back()->getAsCXXRecordDecl();
+        assert(D->getNumBases() == 1 &&
+               "HLSL doesn't support multiple inheritance");
+        
RecordTypes.push_back(D->bases_begin()->getType()->getAs<RecordType>());
+      }
+      while (!RecordTypes.empty()) {
+        const RecordType *RT = RecordTypes.back();
+        RecordTypes.pop_back();
+        for (auto *FD : RT->getDecl()->fields()) {
+          DeclAccessPair Found = DeclAccessPair::make(FD, FD->getAccess());
+          DeclarationNameInfo NameInfo(FD->getDeclName(), E->getBeginLoc());
+          ExprResult Res = S.BuildFieldReferenceExpr(
+              E, false, E->getBeginLoc(), CXXScopeSpec(), FD, Found, NameInfo);
+          if (Res.isInvalid())
+            return false;
+          if (!buildInitializerListImpl(Res.get()))
+            return false;
+        }
+      }
+    }
+    return true;
   }
-  return true;
-}
 
-Expr *generateInitListsImpl(QualType Ty) {
-  assert(ArgIt != ArgExprs.end() && "Something is off in iteration!");
-  if (Ty->isScalarType() || (Ty->isRecordType() && !Ty->isAggregateType()))
-    return *(ArgIt++);
-
-  llvm::SmallVector<Expr *> Inits;
-  assert(!isa<MatrixType>(Ty) && "Matrix types not yet supported in HLSL");
-  Ty = Ty.getDesugaredType(Ctx);
-  if (Ty->isVectorType() || Ty->isConstantArrayType()) {
-    QualType ElTy;
-    uint64_t Size = 0;
-    if (auto *ATy = Ty->getAs<VectorType>()) {
-      ElTy = ATy->getElementType();
-      Size = ATy->getNumElements();
-    } else {
-      auto *VTy = cast<ConstantArrayType>(Ty.getTypePtr());
-      ElTy = VTy->getElementType();
-      Size = VTy->getZExtSize();
-    }
-    for (uint64_t I = 0; I < Size; ++I)
-      Inits.push_back(generateInitListsImpl(ElTy));
-  }
-  if (auto *RTy = Ty->getAs<RecordType>()) {
-    llvm::SmallVector<const RecordType *> RecordTypes;
-    RecordTypes.push_back(RTy);
-    while (RecordTypes.back()->getAsCXXRecordDecl()->getNumBases()) {
-      CXXRecordDecl *D = RecordTypes.back()->getAsCXXRecordDecl();
-      assert(D->getNumBases() == 1 &&
-             "HLSL doesn't support multiple inheritance");
-      RecordTypes.push_back(D->bases_begin()->getType()->getAs<RecordType>());
-    }
-    while (!RecordTypes.empty()) {
-      const RecordType *RT = RecordTypes.back();
-      RecordTypes.pop_back();
-      for (auto *FD : RT->getDecl()->fields()) {
-        Inits.push_back(generateInitListsImpl(FD->getType()));
+  Expr *generateInitListsImpl(QualType Ty) {
+    assert(ArgIt != ArgExprs.end() && "Something is off in iteration!");
+    if (Ty->isScalarType() || (Ty->isRecordType() && !Ty->isAggregateType()))
+      return *(ArgIt++);
+
+    llvm::SmallVector<Expr *> Inits;
+    assert(!isa<MatrixType>(Ty) && "Matrix types not yet supported in HLSL");
+    Ty = Ty.getDesugaredType(Ctx);
+    if (Ty->isVectorType() || Ty->isConstantArrayType()) {
+      QualType ElTy;
+      uint64_t Size = 0;
+      if (auto *ATy = Ty->getAs<VectorType>()) {
+        ElTy = ATy->getElementType();
+        Size = ATy->getNumElements();
+      } else {
+        auto *VTy = cast<ConstantArrayType>(Ty.getTypePtr());
+        ElTy = VTy->getElementType();
+        Size = VTy->getZExtSize();
+      }
+      for (uint64_t I = 0; I < Size; ++I)
+        Inits.push_back(generateInitListsImpl(ElTy));
+    }
+    if (auto *RTy = Ty->getAs<RecordType>()) {
+      llvm::SmallVector<const RecordType *> RecordTypes;
+      RecordTypes.push_back(RTy);
+      while (RecordTypes.back()->getAsCXXRecordDecl()->getNumBases()) {
+        CXXRecordDecl *D = RecordTypes.back()->getAsCXXRecordDecl();
+        assert(D->getNumBases() == 1 &&
+               "HLSL doesn't support multiple inheritance");
+        
RecordTypes.push_back(D->bases_begin()->getType()->getAs<RecordType>());
+      }
+      while (!RecordTypes.empty()) {
+        const RecordType *RT = RecordTypes.back();
+        RecordTypes.pop_back();
+        for (auto *FD : RT->getDecl()->fields()) {
+          Inits.push_back(generateInitListsImpl(FD->getType()));
+        }
       }
     }
+    auto *NewInit = new (Ctx) InitListExpr(Ctx, Inits.front()->getBeginLoc(),
+                                           Inits, Inits.back()->getEndLoc());
+    NewInit->setType(Ty);
+    return NewInit;
   }
-  auto *NewInit = new (Ctx) InitListExpr(Ctx, Inits.front()->getBeginLoc(),
-                                         Inits, Inits.back()->getEndLoc());
-  NewInit->setType(Ty);
-  return NewInit;
-}
+
 public:
-llvm::SmallVector<QualType, 16> DestTypes;
+  llvm::SmallVector<QualType, 16> DestTypes;
   llvm::SmallVector<Expr *, 16> ArgExprs;
   InitListTransformer(Sema &SemaRef, const InitializedEntity &Entity)
       : S(SemaRef), Ctx(SemaRef.getASTContext()),
@@ -3413,14 +3414,12 @@ llvm::SmallVector<QualType, 16> DestTypes;
     // need to wrap around both when building the initializers and when
     // generating the final initializer lists.
     if (Wrap)
-      InitTy = QualType(InitTy->getBaseElementTypeUnsafe(),0);
+      InitTy = QualType(InitTy->getBaseElementTypeUnsafe(), 0);
     BuildFlattenedTypeList(InitTy, DestTypes);
     DstIt = DestTypes.begin();
   }
 
-  bool buildInitializerList(Expr *E) {
-    return buildInitializerListImpl(E);
-  }
+  bool buildInitializerList(Expr *E) { return buildInitializerListImpl(E); }
 
   Expr *generateInitLists() {
     ArgIt = ArgExprs.begin();
@@ -3438,7 +3437,7 @@ llvm::SmallVector<QualType, 16> DestTypes;
     return NewInit;
   }
 };
-}
+} // namespace
 
 bool SemaHLSL::TransformInitList(const InitializedEntity &Entity,
                                  const InitializationKind &Kind,
@@ -3469,7 +3468,8 @@ bool SemaHLSL::TransformInitList(const InitializedEntity 
&Entity,
   // the user intended more, and errors that there are too few initializers to
   // complete the final element.
   if (Entity.getType()->isIncompleteArrayType())
-    ExpectedSize = ((ActualSize + ExpectedSize - 1) / ExpectedSize) * 
ExpectedSize;
+    ExpectedSize =
+        ((ActualSize + ExpectedSize - 1) / ExpectedSize) * ExpectedSize;
 
   // An initializer list might be attempting to initialize a reference or
   // rvalue-reference. When checking the initializer we should look through

>From 46afbd63761e2837dacab11f5375ab1074912b53 Mon Sep 17 00:00:00 2001
From: Chris Bieneman <chris.biene...@me.com>
Date: Fri, 28 Mar 2025 16:34:07 -0500
Subject: [PATCH 3/4] Remove unused parameter to SemaHLSL::transformInitList

---
 clang/include/clang/Sema/SemaHLSL.h | 3 +--
 clang/lib/Sema/SemaHLSL.cpp         | 3 +--
 clang/lib/Sema/SemaInit.cpp         | 2 +-
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/Sema/SemaHLSL.h 
b/clang/include/clang/Sema/SemaHLSL.h
index f333fe30e8da0..5442b5264f18f 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -151,8 +151,7 @@ class SemaHLSL : public SemaBase {
 
   QualType getInoutParameterType(QualType Ty);
 
-  bool TransformInitList(const InitializedEntity &Entity,
-                         const InitializationKind &Kind, InitListExpr *Init);
+  bool transformInitList(const InitializedEntity &Entity, InitListExpr *Init);
 
 private:
   // HLSL resource type attributes need to be processed all at once.
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 36f1ec6dd3d50..103c97e1a4855 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3439,8 +3439,7 @@ class InitListTransformer {
 };
 } // namespace
 
-bool SemaHLSL::TransformInitList(const InitializedEntity &Entity,
-                                 const InitializationKind &Kind,
+bool SemaHLSL::transformInitList(const InitializedEntity &Entity,
                                  InitListExpr *Init) {
   // If the initializer is a scalar, just return it.
   if (Init->getType()->isScalarType())
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 9814c3f456f0d..eece4f7292dde 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -4845,7 +4845,7 @@ static void TryListInitialization(Sema &S,
   QualType DestType = Entity.getType();
 
   if (S.getLangOpts().HLSL &&
-      !S.HLSL().TransformInitList(Entity, Kind, InitList))
+      !S.HLSL().transformInitList(Entity, InitList))
     return;
 
   // C++ doesn't allow scalar initialization with more than one argument.

>From 79b270cde76958a390899bd993dae7419101a410 Mon Sep 17 00:00:00 2001
From: Chris Bieneman <chris.biene...@me.com>
Date: Fri, 28 Mar 2025 18:32:35 -0500
Subject: [PATCH 4/4] clang-format

---
 clang/lib/Sema/SemaInit.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index eece4f7292dde..6615c4bf51aaf 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -4844,8 +4844,7 @@ static void TryListInitialization(Sema &S,
                                   bool TreatUnavailableAsInvalid) {
   QualType DestType = Entity.getType();
 
-  if (S.getLangOpts().HLSL &&
-      !S.HLSL().transformInitList(Entity, InitList))
+  if (S.getLangOpts().HLSL && !S.HLSL().transformInitList(Entity, InitList))
     return;
 
   // C++ doesn't allow scalar initialization with more than one argument.

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

Reply via email to