-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[HLSL] Add matrix constructors using initalizer lists #162743
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[HLSL] Add matrix constructors using initalizer lists #162743
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-hlsl Author: Farzon Lotfi (farzonl) Changesfixes #159434 In HLSL matrices are matrix_type in all respects except that they support a constructor style syntax for initializing matrices. This change adds a translation of vector constructor arguments into initializer lists. This supports the following HLSL syntax: using the same initalizer list behavior defined in transformInitList allows us to support struct element initalization via HLSLElementwiseCast Patch is 58.84 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/162743.diff 7 Files Affected:
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b157cbb0b8069..c1607f8b20275 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2418,9 +2418,9 @@ def err_init_conversion_failed : Error<
"cannot initialize %select{a variable|a parameter|template parameter|"
"return object|statement expression result|an "
"exception object|a member subobject|an array element|a new value|a value|a "
- "base class|a constructor delegation|a vector element|a block element|a "
- "block element|a complex element|a lambda capture|a compound literal "
- "initializer|a related result|a parameter of CF audited function|a "
+ "base class|a constructor delegation|a vector element|a matrix element|a "
+ "block element|a block element|a complex element|a lambda capture|a compound"
+ " literal initializer|a related result|a parameter of CF audited function|a "
"structured binding|a member subobject}0 "
"%diff{of type $ with an %select{rvalue|lvalue}2 of type $|"
"with an %select{rvalue|lvalue}2 of incompatible type}1,3"
@@ -6543,9 +6543,9 @@ def warn_extern_init : Warning<"'extern' variable has an initializer">,
def err_variable_object_no_init : Error<
"variable-sized object may not be initialized">;
def err_excess_initializers : Error<
- "excess elements in %select{array|vector|scalar|union|struct}0 initializer">;
+ "excess elements in %select{array|vector|matrix|scalar|union|struct}0 initializer">;
def ext_excess_initializers : ExtWarn<
- "excess elements in %select{array|vector|scalar|union|struct}0 initializer">,
+ "excess elements in %select{array|vector|matrix|scalar|union|struct}0 initializer">,
InGroup<ExcessInitializers>;
def err_excess_initializers_for_sizeless_type : Error<
"excess elements in initializer for indivisible sizeless type %0">;
@@ -11086,8 +11086,8 @@ def err_first_argument_to_cwsc_pdtor_call : Error<
def err_second_argument_to_cwsc_not_pointer : Error<
"second argument to __builtin_call_with_static_chain must be of pointer type">;
-def err_vector_incorrect_num_elements : Error<
- "%select{too many|too few}0 elements in vector %select{initialization|operand}3 (expected %1 elements, have %2)">;
+def err_tensor_incorrect_num_elements : Error<
+ "%select{too many|too few}0 elements in %select{vector|matrix}1 %select{initialization|operand}4 (expected %2 elements, have %3)">;
def err_altivec_empty_initializer : Error<"expected initializer">;
def err_vector_incorrect_bit_count : Error<
diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h
index 5e96317ffb7fe..8d13b4947717a 100644
--- a/clang/include/clang/Sema/Initialization.h
+++ b/clang/include/clang/Sema/Initialization.h
@@ -91,6 +91,10 @@ class alignas(8) InitializedEntity {
/// or vector.
EK_VectorElement,
+ /// The entity being initialized is an element of a matrix.
+ /// or matrix.
+ EK_MatrixElement,
+
/// The entity being initialized is a field of block descriptor for
/// the copied-in c++ object.
EK_BlockElement,
@@ -205,8 +209,8 @@ class alignas(8) InitializedEntity {
/// virtual base.
llvm::PointerIntPair<const CXXBaseSpecifier *, 1> Base;
- /// When Kind == EK_ArrayElement, EK_VectorElement, or
- /// EK_ComplexElement, the index of the array or vector element being
+ /// When Kind == EK_ArrayElement, EK_VectorElement, or EK_MatrixElement,
+ /// or EK_ComplexElement, the index of the array or vector element being
/// initialized.
unsigned Index;
@@ -536,7 +540,7 @@ class alignas(8) InitializedEntity {
/// element's index.
unsigned getElementIndex() const {
assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement ||
- getKind() == EK_ComplexElement);
+ getKind() == EK_MatrixElement || getKind() == EK_ComplexElement);
return Index;
}
@@ -544,7 +548,7 @@ class alignas(8) InitializedEntity {
/// element, sets the element index.
void setElementIndex(unsigned Index) {
assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement ||
- getKind() == EK_ComplexElement);
+ getKind() == EK_MatrixElement || getKind() == EK_ComplexElement);
this->Index = Index;
}
diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp
index e8a7ad3bd355a..2a956cb79c0bf 100644
--- a/clang/lib/Sema/CheckExprLifetime.cpp
+++ b/clang/lib/Sema/CheckExprLifetime.cpp
@@ -155,6 +155,7 @@ getEntityLifetime(const InitializedEntity *Entity,
case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
case InitializedEntity::EK_LambdaCapture:
case InitializedEntity::EK_VectorElement:
+ case InitializedEntity::EK_MatrixElement:
case InitializedEntity::EK_ComplexElement:
return {nullptr, LK_FullExpression};
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index a662b72c2a362..1b11a964a3d53 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -21,6 +21,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/HLSLResource.h"
#include "clang/AST/Type.h"
+#include "clang/AST/TypeBase.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/DiagnosticSema.h"
@@ -3323,6 +3324,11 @@ static void BuildFlattenedTypeList(QualType BaseTy,
List.insert(List.end(), VT->getNumElements(), VT->getElementType());
continue;
}
+ if (const auto *MT = dyn_cast<ConstantMatrixType>(T)) {
+ List.insert(List.end(), MT->getNumElementsFlattened(),
+ MT->getElementType());
+ continue;
+ }
if (const auto *RD = T->getAsCXXRecordDecl()) {
if (RD->isStandardLayout())
RD = RD->getStandardLayoutBaseWithFields();
@@ -4124,6 +4130,32 @@ class InitListTransformer {
}
return true;
}
+ if (auto *MTy = Ty->getAs<ConstantMatrixType>()) {
+ unsigned Rows = MTy->getNumRows();
+ unsigned Cols = MTy->getNumColumns();
+ QualType ElemTy = MTy->getElementType();
+
+ for (unsigned C = 0; C < Cols; ++C) {
+ for (unsigned R = 0; R < Rows; ++R) {
+ // row index literal
+ Expr *RowIdx = IntegerLiteral::Create(
+ Ctx, llvm::APInt(Ctx.getIntWidth(Ctx.IntTy), R), Ctx.IntTy,
+ E->getBeginLoc());
+ // column index literal
+ Expr *ColIdx = IntegerLiteral::Create(
+ Ctx, llvm::APInt(Ctx.getIntWidth(Ctx.IntTy), C), Ctx.IntTy,
+ E->getBeginLoc());
+ ExprResult ElExpr = S.CreateBuiltinMatrixSubscriptExpr(
+ E, RowIdx, ColIdx, E->getEndLoc());
+ if (ElExpr.isInvalid())
+ return false;
+ if (!buildInitializerListImpl(ElExpr.get()))
+ return false;
+ ElExpr.get()->setType(ElemTy);
+ }
+ }
+ return true;
+ }
if (auto *ArrTy = dyn_cast<ConstantArrayType>(Ty.getTypePtr())) {
uint64_t Size = ArrTy->getZExtSize();
@@ -4177,14 +4209,17 @@ class InitListTransformer {
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()) {
+ if (Ty->isVectorType() || Ty->isConstantArrayType() ||
+ Ty->isConstantMatrixType()) {
QualType ElTy;
uint64_t Size = 0;
if (auto *ATy = Ty->getAs<VectorType>()) {
ElTy = ATy->getElementType();
Size = ATy->getNumElements();
+ } else if (auto *CMTy = Ty->getAs<ConstantMatrixType>()) {
+ ElTy = CMTy->getElementType();
+ Size = CMTy->getNumElementsFlattened();
} else {
auto *VTy = cast<ConstantArrayType>(Ty.getTypePtr());
ElTy = VTy->getElementType();
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 543db46fa0593..3b140b3f058ac 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/IgnoreExpr.h"
+#include "clang/AST/TypeBase.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Specifiers.h"
@@ -403,6 +404,9 @@ class InitListChecker {
unsigned &Index,
InitListExpr *StructuredList,
unsigned &StructuredIndex);
+ void CheckMatrixType(const InitializedEntity &Entity, InitListExpr *IList,
+ QualType DeclType, unsigned &Index,
+ InitListExpr *StructuredList, unsigned &StructuredIndex);
void CheckVectorType(const InitializedEntity &Entity,
InitListExpr *IList, QualType DeclType, unsigned &Index,
InitListExpr *StructuredList,
@@ -1003,7 +1007,8 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
return;
if (ElementEntity.getKind() == InitializedEntity::EK_ArrayElement ||
- ElementEntity.getKind() == InitializedEntity::EK_VectorElement)
+ ElementEntity.getKind() == InitializedEntity::EK_VectorElement ||
+ ElementEntity.getKind() == InitializedEntity::EK_MatrixElement)
ElementEntity.setElementIndex(Init);
if (Init >= NumInits && (ILE->hasArrayFiller() || SkipEmptyInitChecks))
@@ -1273,6 +1278,7 @@ static void warnBracedScalarInit(Sema &S, const InitializedEntity &Entity,
switch (Entity.getKind()) {
case InitializedEntity::EK_VectorElement:
+ case InitializedEntity::EK_MatrixElement:
case InitializedEntity::EK_ComplexElement:
case InitializedEntity::EK_ArrayElement:
case InitializedEntity::EK_Parameter:
@@ -1372,11 +1378,12 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity,
SemaRef.Diag(IList->getInit(Index)->getBeginLoc(), DK)
<< T << IList->getInit(Index)->getSourceRange();
} else {
- int initKind = T->isArrayType() ? 0 :
- T->isVectorType() ? 1 :
- T->isScalarType() ? 2 :
- T->isUnionType() ? 3 :
- 4;
+ int initKind = T->isArrayType() ? 0
+ : T->isVectorType() ? 1
+ : T->isMatrixType() ? 2
+ : T->isScalarType() ? 3
+ : T->isUnionType() ? 4
+ : 5;
unsigned DK = ExtraInitsIsError ? diag::err_excess_initializers
: diag::ext_excess_initializers;
@@ -1430,6 +1437,9 @@ void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity,
} else if (DeclType->isVectorType()) {
CheckVectorType(Entity, IList, DeclType, Index,
StructuredList, StructuredIndex);
+ } else if (DeclType->isMatrixType()) {
+ CheckMatrixType(Entity, IList, DeclType, Index, StructuredList,
+ StructuredIndex);
} else if (const RecordDecl *RD = DeclType->getAsRecordDecl()) {
auto Bases =
CXXRecordDecl::base_class_const_range(CXXRecordDecl::base_class_const_iterator(),
@@ -1877,6 +1887,93 @@ void InitListChecker::CheckReferenceType(const InitializedEntity &Entity,
AggrDeductionCandidateParamTypes->push_back(DeclType);
}
+void InitListChecker::CheckMatrixType(const InitializedEntity &Entity,
+ InitListExpr *IList, QualType DeclType,
+ unsigned &Index,
+ InitListExpr *StructuredList,
+ unsigned &StructuredIndex) {
+ if (!SemaRef.getLangOpts().HLSL)
+ return;
+
+ const ConstantMatrixType *MT = DeclType->castAs<ConstantMatrixType>();
+ QualType ElemTy = MT->getElementType();
+ const unsigned Rows = MT->getNumRows();
+ const unsigned Cols = MT->getNumColumns();
+ const unsigned MaxElts = Rows * Cols;
+
+ unsigned NumEltsInit = 0;
+ InitializedEntity ElemEnt =
+ InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity);
+
+ // A Matrix initalizer should be able to take scalars, vectors, and matrices.
+ auto HandleInit = [&](InitListExpr *List, unsigned &Idx) {
+ Expr *Init = List->getInit(Idx);
+ QualType ITy = Init->getType();
+
+ if (ITy->isVectorType()) {
+ const VectorType *IVT = ITy->castAs<VectorType>();
+ unsigned N = IVT->getNumElements();
+ QualType VTy =
+ ITy->isExtVectorType()
+ ? SemaRef.Context.getExtVectorType(ElemTy, N)
+ : SemaRef.Context.getVectorType(ElemTy, N, IVT->getVectorKind());
+ ElemEnt.setElementIndex(Idx);
+ CheckSubElementType(ElemEnt, List, VTy, Idx, StructuredList,
+ StructuredIndex);
+ NumEltsInit += N;
+ return;
+ }
+
+ if (ITy->isMatrixType()) {
+ const ConstantMatrixType *IMT = ITy->castAs<ConstantMatrixType>();
+ unsigned N = IMT->getNumRows() * IMT->getNumColumns();
+ QualType MTy = SemaRef.Context.getConstantMatrixType(
+ ElemTy, IMT->getNumRows(), IMT->getNumColumns());
+ ElemEnt.setElementIndex(Idx);
+ CheckSubElementType(ElemEnt, List, MTy, Idx, StructuredList,
+ StructuredIndex);
+ NumEltsInit += N;
+ return;
+ }
+
+ // Scalar element
+ ElemEnt.setElementIndex(Idx);
+ CheckSubElementType(ElemEnt, List, ElemTy, Idx, StructuredList,
+ StructuredIndex);
+ ++NumEltsInit;
+ };
+
+ // Column-major: each top-level sublist is treated as a column.
+ while (NumEltsInit < MaxElts && Index < IList->getNumInits()) {
+ Expr *Init = IList->getInit(Index);
+
+ if (auto *SubList = dyn_cast<InitListExpr>(Init)) {
+ unsigned SubIdx = 0;
+ unsigned Row = 0;
+ while (Row < Rows && SubIdx < SubList->getNumInits() &&
+ NumEltsInit < MaxElts) {
+ HandleInit(SubList, SubIdx);
+ ++Row;
+ }
+ ++Index; // advance past this column sublist
+ continue;
+ }
+
+ // Not a sublist: just consume directly.
+ HandleInit(IList, Index);
+ }
+
+ // HLSL requires exactly Rows*Cols initializers after flattening.
+ if (NumEltsInit != MaxElts) {
+ if (!VerifyOnly)
+ SemaRef.Diag(IList->getBeginLoc(),
+ diag::err_tensor_incorrect_num_elements)
+ << (NumEltsInit < MaxElts) << /*matrix*/ 1 << MaxElts << NumEltsInit
+ << /*initialization*/ 0;
+ hadError = true;
+ }
+}
+
void InitListChecker::CheckVectorType(const InitializedEntity &Entity,
InitListExpr *IList, QualType DeclType,
unsigned &Index,
@@ -2026,9 +2123,9 @@ void InitListChecker::CheckVectorType(const InitializedEntity &Entity,
if (numEltsInit != maxElements) {
if (!VerifyOnly)
SemaRef.Diag(IList->getBeginLoc(),
- diag::err_vector_incorrect_num_elements)
- << (numEltsInit < maxElements) << maxElements << numEltsInit
- << /*initialization*/ 0;
+ diag::err_tensor_incorrect_num_elements)
+ << (numEltsInit < maxElements) << /*vector*/ 0 << maxElements
+ << numEltsInit << /*initialization*/ 0;
hadError = true;
}
}
@@ -3639,6 +3736,9 @@ InitializedEntity::InitializedEntity(ASTContext &Context, unsigned Index,
} else if (const VectorType *VT = Parent.getType()->getAs<VectorType>()) {
Kind = EK_VectorElement;
Type = VT->getElementType();
+ } else if (const MatrixType *MT = Parent.getType()->getAs<MatrixType>()) {
+ Kind = EK_MatrixElement;
+ Type = MT->getElementType();
} else {
const ComplexType *CT = Parent.getType()->getAs<ComplexType>();
assert(CT && "Unexpected type");
@@ -3687,6 +3787,7 @@ DeclarationName InitializedEntity::getName() const {
case EK_Delegating:
case EK_ArrayElement:
case EK_VectorElement:
+ case EK_MatrixElement:
case EK_ComplexElement:
case EK_BlockElement:
case EK_LambdaToBlockConversionBlockElement:
@@ -3720,6 +3821,7 @@ ValueDecl *InitializedEntity::getDecl() const {
case EK_Delegating:
case EK_ArrayElement:
case EK_VectorElement:
+ case EK_MatrixElement:
case EK_ComplexElement:
case EK_BlockElement:
case EK_LambdaToBlockConversionBlockElement:
@@ -3753,6 +3855,7 @@ bool InitializedEntity::allowsNRVO() const {
case EK_Delegating:
case EK_ArrayElement:
case EK_VectorElement:
+ case EK_MatrixElement:
case EK_ComplexElement:
case EK_BlockElement:
case EK_LambdaToBlockConversionBlockElement:
@@ -3792,6 +3895,9 @@ unsigned InitializedEntity::dumpImpl(raw_ostream &OS) const {
case EK_Delegating: OS << "Delegating"; break;
case EK_ArrayElement: OS << "ArrayElement " << Index; break;
case EK_VectorElement: OS << "VectorElement " << Index; break;
+ case EK_MatrixElement:
+ OS << "MatrixElement " << Index;
+ break;
case EK_ComplexElement: OS << "ComplexElement " << Index; break;
case EK_BlockElement: OS << "Block"; break;
case EK_LambdaToBlockConversionBlockElement:
@@ -6029,7 +6135,7 @@ static void TryOrBuildParenListInitialization(
Sequence.SetFailed(InitializationSequence::FK_ParenthesizedListInitFailed);
if (!VerifyOnly) {
QualType T = Entity.getType();
- int InitKind = T->isArrayType() ? 0 : T->isUnionType() ? 3 : 4;
+ int InitKind = T->isArrayType() ? 0 : T->isUnionType() ? 4 : 5;
SourceRange ExcessInitSR(Args[EntityIndexToProcess]->getBeginLoc(),
Args.back()->getEndLoc());
S.Diag(Kind.getLocation(), diag::err_excess_initializers)
@@ -6822,7 +6928,8 @@ void InitializationSequence::InitializeFrom(Sema &S,
// For HLSL ext vector types we allow list initialization behavior for C++
// functional cast expressions which look like constructor syntax. This is
// accomplished by converting initialization arguments to InitListExpr.
- if (S.getLangOpts().HLSL && Args.size() > 1 && DestType->isExtVectorType() &&
+ if (S.getLangOpts().HLSL && Args.size() > 1 &&
+ (DestType->isExtVectorType() || DestType->isConstantMatrixType()) &&
(SourceType.isNull() ||
!Context.hasSameUnqualifiedType(SourceType, DestType))) {
InitListExpr *ILE = new (Context)
@@ -6987,6 +7094,7 @@ static AssignmentAction getAssignmentAction(const InitializedEntity &Entity,
case InitializedEntity::EK_Binding:
case InitializedEntity::EK_ArrayElement:
case InitializedEntity::EK_VectorElement:
+ case InitializedEntity::EK_MatrixElement:
case InitializedEntity::EK_ComplexElement:
case InitializedEntity::EK_BlockElement:
case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
@@ -7012,6 +7120,7 @@ static bool shouldBindAsTemporary(const InitializedEntity &Entity) {
case InitializedEntity::EK_Base:
case InitializedEntity::EK_Delegating:
case InitializedEntity::EK_VectorElement:
+ case InitializedEntity::EK_MatrixElement:
case InitializedEntity::EK_ComplexElement:
case InitializedEntity::EK_Exception:
case InitializedEntity::EK_BlockElement:
@@ -7042,6 +7151,7 @@ static bool shouldDestroyEntity(const InitializedEntity &Entity) {
case InitializedEntity::EK_Base:
case InitializedEntity::EK_Delegating:
case InitializedEntity::EK_VectorElement:
+ case InitializedEntity::EK_MatrixElement:
case InitializedEntity::EK_ComplexElement:
case InitializedEntity::EK_BlockElement:
case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
@@ -7095,6 +7205,7 @@ static SourceLocation getInitializationLoc(const InitializedEntity &Entity,
case InitializedEntity::EK_Base:
case InitializedEntity::EK_Delegating:
case InitializedEntity::EK_VectorElement:
+ case InitializedEntity::EK_MatrixElement:
case InitializedEntity::EK_ComplexElement:
case InitializedEntity::EK_BlockElement:
case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
@@ -7844,11 +7955,13 @@ ExprResult InitializationSequence::Perform(Sema &S,
ExprResult CurInit((Expr *)nullptr);
SmallVector<Expr*, 4> ArrayLoopCommonExprs;
- // HLSL allows vector initialization to function like list initialization, but
- // use the syntax of a C++-like construct...
[truncated]
|
if (!buildInitializerListImpl(ElExpr.get())) | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this line I copied from the ConstantArrayType
case. However the vector type case does
if (!buildInitializerListImpl(ElExpr.get())) | |
return false; | |
if (!castInitializer(ElExpr.get())) | |
return false; |
I couldn't find a material difference in behavior in my testing. suggestions on test cases to know which one is the right error handling would be appreicated.
AggrDeductionCandidateParamTypes->push_back(DeclType); | ||
} | ||
|
||
void InitListChecker::CheckMatrixType(const InitializedEntity &Entity, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why we need to do this checking. Shouldn't this all be done in the SemaHLSL code that validates the initializer list and transforms it to per-element initializers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well three things First SemaHLSL is validating vectors and yet we still have CheckVectorType
which even has HLSL copy initalization.
Second removing
} else if (DeclType->isMatrixType()) {
CheckMatrixType(Entity, IList, DeclType, Index, StructuredList,
StructuredIndex);
}
causes us to hit this else case:
llvm-project/clang/lib/Sema/SemaInit.cpp
Lines 1481 to 1486 in 0c2913a
} else { | |
if (!VerifyOnly) | |
SemaRef.Diag(IList->getBeginLoc(), diag::err_illegal_initializer_type) | |
<< DeclType; | |
hadError = true; | |
} |
Third even if we do something like below to avoid the err_illegal_initializer_type diag message
} else if (DeclType->isMatrixType()) {
return;
}
we still error with excess elements in matrix initializer
. So CheckMatrixType
is necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That said the diagnostics in CheckMatrixType
never trigger and are now preceded by the ones in SemaHLSL and the flatten mixed vector/matrix/scalar elements is also done in SemaHLSL so I will investigate to see if we can reduce the scope of what CheckMatrixType
is doing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@llvm-beanz the initializer list work simplifies but does not make us remove CheckMatrixType
. It simplifies it so that all we have to do is support the scalar case by looping over the number of inits and calling CheckSubElementType
. So I deleted all the vector and matrix type handeling
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your testing is focused on CXXFunctionalCastExpr
, but the implementation of that should be the same as the general initializer list implementation (it is for vectors), so the testing also needs to cover those cases.
Things like:
[numthreads(1,1,1)]
void main() {
float4x2 m = {1.xxx, 2.xx, 3.x, 4.xx};
struct S { float2x2 x; float2x2 y;};
S s = {m};
float2x2 m2 = {0.xxxx};
int4x4 m3 = {m2, m2, m2, m2};
}
fixes llvm#159434 In HLSL matrices are matrix_type in all respects except that they support a constructor style syntax for initializing matrices. This change adds a translation of vector constructor arguments into initializer lists. This supports the following HLSL syntax: (1) HLSL matrices support constructor syntax (2) HLSL matrices are expanded to constituate components in constructor using the same initalizer list behavior defined in transformInitList allows us to support struct element initalization via HLSLElementwiseCast
… types, because initalizer lists already do that for us
b77678f
to
a09e070
Compare
"block element|a complex element|a lambda capture|a compound literal " | ||
"initializer|a related result|a parameter of CF audited function|a " | ||
"base class|a constructor delegation|a vector element|a matrix element|a " | ||
"block element|a block element|a complex element|a lambda capture|a compound" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a block element
appears twice in this list
"block element|a block element|a complex element|a lambda capture|a compound" | |
"block element|a complex element|a lambda capture|a compound" |
|
||
/// When Kind == EK_ArrayElement, EK_VectorElement, or | ||
/// EK_ComplexElement, the index of the array or vector element being | ||
/// When Kind == EK_ArrayElement, EK_VectorElement, or EK_MatrixElement, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: the word "or" appears twice
/// When Kind == EK_ArrayElement, EK_VectorElement, or EK_MatrixElement, | |
/// When Kind == EK_ArrayElement, EK_VectorElement, EK_MatrixElement, |
fixes #159434
In HLSL matrices are matrix_type in all respects except that they support a constructor style syntax for initializing matrices.
This change adds a translation of vector constructor arguments into initializer lists.
This supports the following HLSL syntax:
(1) HLSL matrices support constructor syntax
(2) HLSL matrices are expanded to constituate components in constructor
using the same initalizer list behavior defined in transformInitList allows us to support struct element initalization via HLSLElementwiseCast