================
@@ -3249,166 +3249,204 @@ void SemaHLSL::processExplicitBindingsOnDecl(VarDecl 
*VD) {
     }
   }
 }
-
-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.
+namespace {
+class InitListTransformer {
+  Sema &S;
+  ASTContext &Ctx;
+  QualType InitTy;
+  QualType *DstIt = nullptr;
+  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;
+      }
+      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;
   }
-  InitializedEntity Entity = InitializedEntity::InitializeParameter(
-      Ctx, DestTypes[List.size()], false);
-  ExprResult Res = S.PerformCopyInitialization(Entity, E->getBeginLoc(), E);
-  if (Res.isInvalid())
-    return false;
-  Expr *Init = Res.get();
-  List.push_back(Init);
-  return true;
-}
 
-static bool BuildInitializerList(Sema &S, ASTContext &Ctx, Expr *E,
-                                 llvm::SmallVectorImpl<Expr *> &List,
-                                 llvm::SmallVectorImpl<QualType> &DestTypes) {
-  // 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))
-        return false;
-    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;
+      return true;
+    }
 
-  // If this is a scalar type, just enqueue the expression.
-  QualType Ty = E->getType();
+    // If this is a scalar type, just enqueue the expression.
+    QualType Ty = E->getType();
 
-  if (Ty->isScalarType() || (Ty->isRecordType() && !Ty->isAggregateType()))
-    return CastInitializer(S, Ctx, E, List, DestTypes);
+    if (Ty->isScalarType() || (Ty->isRecordType() && !Ty->isAggregateType()))
+      return castInitializer(E);
 
-  if (auto *VecTy = Ty->getAs<VectorType>()) {
-    uint64_t Size = VecTy->getNumElements();
+    if (auto *VecTy = Ty->getAs<VectorType>()) {
+      uint64_t Size = VecTy->getNumElements();
 
-    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());
+      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 (!CastInitializer(S, Ctx, ElExpr.get(), List, DestTypes))
-        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 *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 (!BuildInitializerList(S, Ctx, ElExpr.get(), List, DestTypes))
-        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())
+    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 (!BuildInitializerList(S, Ctx, Res.get(), List, DestTypes))
+        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;
-}
 
-static Expr *GenerateInitLists(ASTContext &Ctx, QualType Ty,
-                               llvm::SmallVectorImpl<Expr *>::iterator &It) {
-  if (Ty->isScalarType() || (Ty->isRecordType() && !Ty->isAggregateType())) {
-    return *(It++);
-  }
-  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(GenerateInitLists(Ctx, ElTy, It));
-  }
-  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(GenerateInitLists(Ctx, FD->getType(), 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);
+    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;
-}
 
-bool SemaHLSL::TransformInitList(const InitializedEntity &Entity,
-                                 const InitializationKind &Kind,
+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);
----------------
llvm-beanz wrote:

You can't have a double incomplete array, so you'd need to do something like 
`int2[][2]` which would be an incomplete array of `int2[2]` elements, so InitTy 
would be `int2[2]`... gross right?

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

Reply via email to