[clang] [HLSL] add IsTypedResourceElementCompatible type trait (PR #114864)
Joshua Batista via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 4 12:26:16 PST 2024
https://github.com/bob80905 created https://github.com/llvm/llvm-project/pull/114864
This PR implements a new type trait as a builtin, __builtin_hlsl_is_typed_resource_element_compatible
This type traits verifies that the given input type is suitable as a typed resource element type.
It checks that the given input type is homogeneous, has no more than 4 sub elements, does not exceed 16 bytes, and does not contain any arrays, booleans, or enums.
Fixes https://github.com/llvm/llvm-project/issues/113223
>From a31199224c19c1087b114de29d864125b720e6d8 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Fri, 25 Oct 2024 12:33:05 -0700
Subject: [PATCH 1/7] add type trait
---
.../clang/AST/CXXRecordDeclDefinitionBits.def | 5 +
clang/include/clang/AST/DeclCXX.h | 5 +
clang/include/clang/AST/Type.h | 9 +-
clang/include/clang/Basic/TokenKinds.def | 1 +
clang/include/clang/Sema/SemaHLSL.h | 1 +
clang/lib/AST/DeclCXX.cpp | 6 +-
clang/lib/Sema/SemaExprCXX.cpp | 10 ++
clang/lib/Sema/SemaHLSL.cpp | 43 ++++++++
.../IsLineVectorLayoutCompatibleType.hlsl | 101 ++++++++++++++++++
...IsLineVectorLayoutCompatibleTypeErros.hlsl | 10 ++
10 files changed, 189 insertions(+), 2 deletions(-)
create mode 100644 clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleType.hlsl
create mode 100644 clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErros.hlsl
diff --git a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
index 6620840df0ced2..0411b244ed5eef 100644
--- a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
+++ b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
@@ -253,4 +253,9 @@ FIELD(IsAnyDestructorNoReturn, 1, NO_MERGE)
/// type that is intangible). HLSL only.
FIELD(IsHLSLIntangible, 1, NO_MERGE)
+/// Whether the record type is line vector layout compatible (that is,
+/// it has at most 4 elements, does not exceed 16 bytes, is homogenous,
+/// and does not contain any bool or enum types)
+FIELD(IsHLSLLineVectorLayoutCompatible, 1, NO_MERGE)
+
#undef FIELD
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 2693cc0e95b4b2..e2e4ed78195a81 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1551,6 +1551,11 @@ class CXXRecordDecl : public RecordDecl {
/// a field or in base class.
bool isHLSLIntangible() const { return data().IsHLSLIntangible; }
+ /// Returns true if the class is line vector layout compatible
+ bool isHLSLLineVectorLayoutCompatible() const {
+ return data().IsHLSLLineVectorLayoutCompatible;
+ }
+
/// If the class is a local class [class.local], returns
/// the enclosing function declaration.
const FunctionDecl *isLocalClass() const {
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index ba3161c366f4d9..bbc7708341b330 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2665,7 +2665,8 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
bool isHLSLAttributedResourceType() const;
bool isHLSLIntangibleType()
const; // Any HLSL intangible type (builtin, array, class)
-
+ bool isHLSLLineVectorLayoutCompatibleType()
+ const; // Any HLSL line vector layout compatible type
/// Determines if this type, which must satisfy
/// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
/// than implicitly __strong.
@@ -8459,6 +8460,12 @@ inline bool Type::isHLSLBuiltinIntangibleType() const {
false;
}
+inline bool Type::isHLSLLineVectorLayoutCompatibleType() const {
+#define HLSL_LINE_VECTOR_LAYOUT_COMPATIBLE_TYPE(Name, Id, SingletonId) \
+ is##Id##Type() ||
+ return isHLSLAttributedResourceType();
+}
+
inline bool Type::isHLSLSpecificType() const {
return isHLSLBuiltinIntangibleType() || isHLSLAttributedResourceType();
}
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index fdfb35de9cf287..0e4e2a8e45b810 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -662,6 +662,7 @@ KEYWORD(out , KEYHLSL)
// HLSL Type traits
TYPE_TRAIT_2(__builtin_hlsl_is_scalarized_layout_compatible, IsScalarizedLayoutCompatible, KEYHLSL)
TYPE_TRAIT_1(__builtin_hlsl_is_intangible, IsIntangibleType, KEYHLSL)
+TYPE_TRAIT_1(__builtin_hlsl_is_line_vector_layout_compatible, IsLineVectorLayoutCompatibleType, KEYHLSL)
// OpenMP Type Traits
UNARY_EXPR_OR_TYPE_TRAIT(__builtin_omp_required_simd_align, OpenMPRequiredSimdAlign, KEYALL)
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index e30acd87f77218..4c92b6170078b7 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -132,6 +132,7 @@ class SemaHLSL : public SemaBase {
// HLSL Type trait implementations
bool IsScalarizedLayoutCompatible(QualType T1, QualType T2) const;
+ bool IsLineVectorLayoutCompatibleType(QualType T1);
bool CheckCompatibleParameterABI(FunctionDecl *New, FunctionDecl *Old);
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index db0ea62a2323eb..c89dd4a05e26c4 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -109,7 +109,8 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
ImplicitCopyAssignmentHasConstParam(true),
HasDeclaredCopyConstructorWithConstParam(false),
HasDeclaredCopyAssignmentWithConstParam(false),
- IsAnyDestructorNoReturn(false), IsHLSLIntangible(false), IsLambda(false),
+ IsAnyDestructorNoReturn(false), IsHLSLIntangible(false),
+ IsHLSLLineVectorLayoutCompatible(false), IsLambda(false),
IsParsingBaseSpecifiers(false), ComputedVisibleConversions(false),
HasODRHash(false), Definition(D) {}
@@ -434,6 +435,9 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
if (BaseClassDecl->isHLSLIntangible())
data().IsHLSLIntangible = true;
+ if (BaseClassDecl->isHLSLLineVectorLayoutCompatible())
+ data().IsHLSLLineVectorLayoutCompatible = true;
+
// C++11 [class.copy]p18:
// The implicitly-declared copy assignment operator for a class X will
// have the form 'X& X::operator=(const X&)' if each direct base class B
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 50c1b24fce6da7..86c793065ceeef 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5032,6 +5032,7 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,
case UTT_IsScalar:
case UTT_IsCompound:
case UTT_IsMemberPointer:
+ case UTT_IsLineVectorLayoutCompatibleType:
// Fall-through
// These traits are modeled on type predicates in C++0x [meta.unary.prop]
@@ -5714,6 +5715,15 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
tok::kw___builtin_hlsl_is_intangible))
return false;
return T->isHLSLIntangibleType();
+
+ case UTT_IsLineVectorLayoutCompatibleType:
+ assert(Self.getLangOpts().HLSL &&
+ "line vector layout compatible types are HLSL-only feature");
+ if (Self.RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), T,
+ diag::err_incomplete_type))
+ return false;
+
+ return Self.HLSL().IsLineVectorLayoutCompatibleType(T);
}
}
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 1f6c5b8d4561bc..9c037eb637148d 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2163,6 +2163,49 @@ static void BuildFlattenedTypeList(QualType BaseTy,
}
}
+bool SemaHLSL::IsLineVectorLayoutCompatibleType(clang::QualType QT) {
+ if (QT.isNull())
+ return false;
+
+ llvm::SmallVector<QualType, 16> QTTypes;
+ BuildFlattenedTypeList(QT, QTTypes);
+
+ QualType FirstQT = QTTypes[0];
+
+ // element count cannot exceed 4
+ if (QTTypes.size() > 4)
+ return false;
+
+ // check if the outer type was an array type
+ if (llvm::isa<clang::ArrayType>(QT.getTypePtr()))
+ return false;
+
+ for (QualType TempQT : QTTypes) {
+ // ensure homogeneity
+ if (TempQT != FirstQT)
+ return false;
+
+ if (const BuiltinType *BT = TempQT->getAs<BuiltinType>()) {
+ if (BT->getKind() == BuiltinType::Bool ||
+ BT->getKind() == BuiltinType::Enum)
+ return false;
+
+ // Check if it is an array type.
+ if (llvm::isa<clang::ArrayType>(TempQT.getTypePtr()))
+ return false;
+ }
+ }
+
+ // if the loop above completes without returning, then
+ // we've guaranteed homogeneity
+ int TotalSizeInBytes =
+ (SemaRef.Context.getTypeSize(FirstQT) / 8) * QTTypes.size();
+ if (TotalSizeInBytes > 16)
+ return false;
+
+ return true;
+}
+
bool SemaHLSL::IsScalarizedLayoutCompatible(QualType T1, QualType T2) const {
if (T1.isNull() || T2.isNull())
return false;
diff --git a/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleType.hlsl b/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleType.hlsl
new file mode 100644
index 00000000000000..9c97a5af39a36c
--- /dev/null
+++ b/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleType.hlsl
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -verify %s
+// expected-no-diagnostics
+
+struct oneInt {
+ int i;
+};
+
+struct twoInt {
+ int aa;
+ int ab;
+};
+
+struct threeInts {
+ oneInt o;
+ twoInt t;
+};
+
+struct oneFloat {
+ float f;
+};
+struct depthDiff {
+ int i;
+ oneInt o;
+ oneFloat f;
+};
+
+struct notHomogenous{
+ int i;
+ float f;
+};
+
+struct EightElements {
+ twoInt x[2];
+ twoInt y[2];
+};
+
+struct EightHalves {
+half x[8];
+};
+
+struct intVec {
+ int2 i;
+};
+
+struct oneIntWithVec {
+ int i;
+ oneInt i2;
+ int2 i3;
+};
+
+struct weirdStruct {
+ int i;
+ intVec iv;
+};
+
+_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(int), "");
+_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(float), "");
+_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(float4), "");
+_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(double2), "");
+_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(oneInt), "");
+_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(oneFloat), "");
+_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(twoInt), "");
+_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(threeInts), "");
+_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(notHomogenous), "");
+_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(depthDiff), "");
+_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(EightElements), "");
+_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(EightHalves), "");
+_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(oneIntWithVec), "");
+_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(weirdStruct), "");
+_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(RWBuffer<int>), "");
+
+
+// arrays not allowed
+_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(half[4]), "");
+
+template<typename T> struct TemplatedBuffer {
+ T a;
+ __hlsl_resource_t h;
+};
+_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(TemplatedBuffer<int>), "");
+
+struct MyStruct1 : TemplatedBuffer<float> {
+ float x;
+};
+_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(MyStruct1), "");
+
+struct MyStruct2 {
+ const TemplatedBuffer<float> TB[10];
+};
+_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(MyStruct2), "");
+
+template<typename T> struct SimpleTemplate {
+ T a;
+};
+
+// though the element type is incomplete, the type trait should still technically return true
+_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(SimpleTemplate<__hlsl_resource_t>), "");
+
+_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(SimpleTemplate<float>), "");
+
+
diff --git a/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErros.hlsl b/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErros.hlsl
new file mode 100644
index 00000000000000..ae878202eeac9d
--- /dev/null
+++ b/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErros.hlsl
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -verify %s
+
+// expected-note at +1{{forward declaration of 'notComplete'}}
+struct notComplete;
+// expected-error at +1{{incomplete type 'notComplete' where a complete type is required}}
+_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(notComplete), "");
+
+
+// types must be complete
+_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(__hlsl_resource_t), "");
>From 7f24d4c68a53caf94e214f36ddb296e9c1449c98 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Fri, 25 Oct 2024 14:01:39 -0700
Subject: [PATCH 2/7] fix bug
---
.../Types/Traits/IsLineVectorLayoutCompatibleTypeErros.hlsl | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErros.hlsl b/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErros.hlsl
index ae878202eeac9d..2277649df54f79 100644
--- a/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErros.hlsl
+++ b/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErros.hlsl
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -verify %s
+// types must be complete
+_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(__hlsl_resource_t), "");
+
// expected-note at +1{{forward declaration of 'notComplete'}}
struct notComplete;
// expected-error at +1{{incomplete type 'notComplete' where a complete type is required}}
_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(notComplete), "");
-
-// types must be complete
-_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(__hlsl_resource_t), "");
>From 540398893200429ce0f396c1ed1c3aab0e06138f Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Fri, 25 Oct 2024 15:28:42 -0700
Subject: [PATCH 3/7] address Finn
---
clang/lib/Sema/SemaHLSL.cpp | 2 ++
...peErros.hlsl => IsLineVectorLayoutCompatibleTypeErrors.hlsl} | 0
2 files changed, 2 insertions(+)
rename clang/test/SemaHLSL/Types/Traits/{IsLineVectorLayoutCompatibleTypeErros.hlsl => IsLineVectorLayoutCompatibleTypeErrors.hlsl} (100%)
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 9c037eb637148d..03396cb9975bef 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2170,6 +2170,8 @@ bool SemaHLSL::IsLineVectorLayoutCompatibleType(clang::QualType QT) {
llvm::SmallVector<QualType, 16> QTTypes;
BuildFlattenedTypeList(QT, QTTypes);
+ assert(QTTypes.size() > 0 &&
+ "expected at least one constituent type from non-null type");
QualType FirstQT = QTTypes[0];
// element count cannot exceed 4
diff --git a/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErros.hlsl b/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErrors.hlsl
similarity index 100%
rename from clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErros.hlsl
rename to clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErrors.hlsl
>From 76243dfd229311655486cfc230d214a98fc55b92 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Wed, 30 Oct 2024 17:17:39 -0700
Subject: [PATCH 4/7] remove unused bits / unused functions
---
.../clang/AST/CXXRecordDeclDefinitionBits.def | 5 -----
clang/include/clang/AST/DeclCXX.h | 5 -----
clang/include/clang/AST/Type.h | 6 ------
clang/lib/AST/DeclCXX.cpp | 6 +-----
clang/lib/Sema/SemaHLSL.cpp | 12 ++++++------
5 files changed, 7 insertions(+), 27 deletions(-)
diff --git a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
index 0411b244ed5eef..6620840df0ced2 100644
--- a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
+++ b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
@@ -253,9 +253,4 @@ FIELD(IsAnyDestructorNoReturn, 1, NO_MERGE)
/// type that is intangible). HLSL only.
FIELD(IsHLSLIntangible, 1, NO_MERGE)
-/// Whether the record type is line vector layout compatible (that is,
-/// it has at most 4 elements, does not exceed 16 bytes, is homogenous,
-/// and does not contain any bool or enum types)
-FIELD(IsHLSLLineVectorLayoutCompatible, 1, NO_MERGE)
-
#undef FIELD
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index e2e4ed78195a81..2693cc0e95b4b2 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1551,11 +1551,6 @@ class CXXRecordDecl : public RecordDecl {
/// a field or in base class.
bool isHLSLIntangible() const { return data().IsHLSLIntangible; }
- /// Returns true if the class is line vector layout compatible
- bool isHLSLLineVectorLayoutCompatible() const {
- return data().IsHLSLLineVectorLayoutCompatible;
- }
-
/// If the class is a local class [class.local], returns
/// the enclosing function declaration.
const FunctionDecl *isLocalClass() const {
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index bbc7708341b330..2f568abe9d587c 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -8460,12 +8460,6 @@ inline bool Type::isHLSLBuiltinIntangibleType() const {
false;
}
-inline bool Type::isHLSLLineVectorLayoutCompatibleType() const {
-#define HLSL_LINE_VECTOR_LAYOUT_COMPATIBLE_TYPE(Name, Id, SingletonId) \
- is##Id##Type() ||
- return isHLSLAttributedResourceType();
-}
-
inline bool Type::isHLSLSpecificType() const {
return isHLSLBuiltinIntangibleType() || isHLSLAttributedResourceType();
}
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index c89dd4a05e26c4..db0ea62a2323eb 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -109,8 +109,7 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
ImplicitCopyAssignmentHasConstParam(true),
HasDeclaredCopyConstructorWithConstParam(false),
HasDeclaredCopyAssignmentWithConstParam(false),
- IsAnyDestructorNoReturn(false), IsHLSLIntangible(false),
- IsHLSLLineVectorLayoutCompatible(false), IsLambda(false),
+ IsAnyDestructorNoReturn(false), IsHLSLIntangible(false), IsLambda(false),
IsParsingBaseSpecifiers(false), ComputedVisibleConversions(false),
HasODRHash(false), Definition(D) {}
@@ -435,9 +434,6 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
if (BaseClassDecl->isHLSLIntangible())
data().IsHLSLIntangible = true;
- if (BaseClassDecl->isHLSLLineVectorLayoutCompatible())
- data().IsHLSLLineVectorLayoutCompatible = true;
-
// C++11 [class.copy]p18:
// The implicitly-declared copy assignment operator for a class X will
// have the form 'X& X::operator=(const X&)' if each direct base class B
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 03396cb9975bef..df66d123ae8186 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2167,7 +2167,11 @@ bool SemaHLSL::IsLineVectorLayoutCompatibleType(clang::QualType QT) {
if (QT.isNull())
return false;
- llvm::SmallVector<QualType, 16> QTTypes;
+ // check if the outer type was an array type
+ if (QT->isArrayType())
+ return false;
+
+ llvm::SmallVector<QualType, 4> QTTypes;
BuildFlattenedTypeList(QT, QTTypes);
assert(QTTypes.size() > 0 &&
@@ -2178,10 +2182,6 @@ bool SemaHLSL::IsLineVectorLayoutCompatibleType(clang::QualType QT) {
if (QTTypes.size() > 4)
return false;
- // check if the outer type was an array type
- if (llvm::isa<clang::ArrayType>(QT.getTypePtr()))
- return false;
-
for (QualType TempQT : QTTypes) {
// ensure homogeneity
if (TempQT != FirstQT)
@@ -2193,7 +2193,7 @@ bool SemaHLSL::IsLineVectorLayoutCompatibleType(clang::QualType QT) {
return false;
// Check if it is an array type.
- if (llvm::isa<clang::ArrayType>(TempQT.getTypePtr()))
+ if (TempQT->isArrayType())
return false;
}
}
>From 300f8e31aea5bbd0c6e8bc08e53de65998db09cc Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Thu, 31 Oct 2024 12:27:30 -0700
Subject: [PATCH 5/7] remove unused function
---
clang/include/clang/AST/Type.h | 2 -
clang/include/clang/Basic/TokenKinds.def | 2 +-
clang/include/clang/Sema/SemaHLSL.h | 2 +-
clang/lib/Sema/SemaExprCXX.cpp | 6 +-
clang/lib/Sema/SemaHLSL.cpp | 2 +-
.../IsLineVectorLayoutCompatibleType.hlsl | 101 ------------------
.../IsTypedResourceElementCompatible.hlsl | 101 ++++++++++++++++++
...TypedResourceElementCompatibleErrors.hlsl} | 4 +-
8 files changed, 109 insertions(+), 111 deletions(-)
delete mode 100644 clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleType.hlsl
create mode 100644 clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
rename clang/test/SemaHLSL/Types/Traits/{IsLineVectorLayoutCompatibleTypeErrors.hlsl => IsTypedResourceElementCompatibleErrors.hlsl} (62%)
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 2f568abe9d587c..0efbfbdf5625dd 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2665,8 +2665,6 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
bool isHLSLAttributedResourceType() const;
bool isHLSLIntangibleType()
const; // Any HLSL intangible type (builtin, array, class)
- bool isHLSLLineVectorLayoutCompatibleType()
- const; // Any HLSL line vector layout compatible type
/// Determines if this type, which must satisfy
/// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
/// than implicitly __strong.
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 0e4e2a8e45b810..2c692c999bdff5 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -662,7 +662,7 @@ KEYWORD(out , KEYHLSL)
// HLSL Type traits
TYPE_TRAIT_2(__builtin_hlsl_is_scalarized_layout_compatible, IsScalarizedLayoutCompatible, KEYHLSL)
TYPE_TRAIT_1(__builtin_hlsl_is_intangible, IsIntangibleType, KEYHLSL)
-TYPE_TRAIT_1(__builtin_hlsl_is_line_vector_layout_compatible, IsLineVectorLayoutCompatibleType, KEYHLSL)
+TYPE_TRAIT_1(__builtin_hlsl_is_typed_resource_element_compatible, IsTypedResourceElementCompatible, KEYHLSL)
// OpenMP Type Traits
UNARY_EXPR_OR_TYPE_TRAIT(__builtin_omp_required_simd_align, OpenMPRequiredSimdAlign, KEYALL)
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index 4c92b6170078b7..06c541dec08cc8 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -132,7 +132,7 @@ class SemaHLSL : public SemaBase {
// HLSL Type trait implementations
bool IsScalarizedLayoutCompatible(QualType T1, QualType T2) const;
- bool IsLineVectorLayoutCompatibleType(QualType T1);
+ bool IsTypedResourceElementCompatible(QualType T1);
bool CheckCompatibleParameterABI(FunctionDecl *New, FunctionDecl *Old);
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 86c793065ceeef..0001e343da84be 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5032,7 +5032,7 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,
case UTT_IsScalar:
case UTT_IsCompound:
case UTT_IsMemberPointer:
- case UTT_IsLineVectorLayoutCompatibleType:
+ case UTT_IsTypedResourceElementCompatible:
// Fall-through
// These traits are modeled on type predicates in C++0x [meta.unary.prop]
@@ -5716,14 +5716,14 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
return false;
return T->isHLSLIntangibleType();
- case UTT_IsLineVectorLayoutCompatibleType:
+ case UTT_IsTypedResourceElementCompatible:
assert(Self.getLangOpts().HLSL &&
"line vector layout compatible types are HLSL-only feature");
if (Self.RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), T,
diag::err_incomplete_type))
return false;
- return Self.HLSL().IsLineVectorLayoutCompatibleType(T);
+ return Self.HLSL().IsTypedResourceElementCompatible(T);
}
}
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index df66d123ae8186..f9b1af44cba388 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2163,7 +2163,7 @@ static void BuildFlattenedTypeList(QualType BaseTy,
}
}
-bool SemaHLSL::IsLineVectorLayoutCompatibleType(clang::QualType QT) {
+bool SemaHLSL::IsTypedResourceElementCompatible(clang::QualType QT) {
if (QT.isNull())
return false;
diff --git a/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleType.hlsl b/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleType.hlsl
deleted file mode 100644
index 9c97a5af39a36c..00000000000000
--- a/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleType.hlsl
+++ /dev/null
@@ -1,101 +0,0 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -verify %s
-// expected-no-diagnostics
-
-struct oneInt {
- int i;
-};
-
-struct twoInt {
- int aa;
- int ab;
-};
-
-struct threeInts {
- oneInt o;
- twoInt t;
-};
-
-struct oneFloat {
- float f;
-};
-struct depthDiff {
- int i;
- oneInt o;
- oneFloat f;
-};
-
-struct notHomogenous{
- int i;
- float f;
-};
-
-struct EightElements {
- twoInt x[2];
- twoInt y[2];
-};
-
-struct EightHalves {
-half x[8];
-};
-
-struct intVec {
- int2 i;
-};
-
-struct oneIntWithVec {
- int i;
- oneInt i2;
- int2 i3;
-};
-
-struct weirdStruct {
- int i;
- intVec iv;
-};
-
-_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(int), "");
-_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(float), "");
-_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(float4), "");
-_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(double2), "");
-_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(oneInt), "");
-_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(oneFloat), "");
-_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(twoInt), "");
-_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(threeInts), "");
-_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(notHomogenous), "");
-_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(depthDiff), "");
-_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(EightElements), "");
-_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(EightHalves), "");
-_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(oneIntWithVec), "");
-_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(weirdStruct), "");
-_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(RWBuffer<int>), "");
-
-
-// arrays not allowed
-_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(half[4]), "");
-
-template<typename T> struct TemplatedBuffer {
- T a;
- __hlsl_resource_t h;
-};
-_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(TemplatedBuffer<int>), "");
-
-struct MyStruct1 : TemplatedBuffer<float> {
- float x;
-};
-_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(MyStruct1), "");
-
-struct MyStruct2 {
- const TemplatedBuffer<float> TB[10];
-};
-_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(MyStruct2), "");
-
-template<typename T> struct SimpleTemplate {
- T a;
-};
-
-// though the element type is incomplete, the type trait should still technically return true
-_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(SimpleTemplate<__hlsl_resource_t>), "");
-
-_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(SimpleTemplate<float>), "");
-
-
diff --git a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
new file mode 100644
index 00000000000000..669c03ea39c8f7
--- /dev/null
+++ b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -verify %s
+// expected-no-diagnostics
+
+struct oneInt {
+ int i;
+};
+
+struct twoInt {
+ int aa;
+ int ab;
+};
+
+struct threeInts {
+ oneInt o;
+ twoInt t;
+};
+
+struct oneFloat {
+ float f;
+};
+struct depthDiff {
+ int i;
+ oneInt o;
+ oneFloat f;
+};
+
+struct notHomogenous{
+ int i;
+ float f;
+};
+
+struct EightElements {
+ twoInt x[2];
+ twoInt y[2];
+};
+
+struct EightHalves {
+half x[8];
+};
+
+struct intVec {
+ int2 i;
+};
+
+struct oneIntWithVec {
+ int i;
+ oneInt i2;
+ int2 i3;
+};
+
+struct weirdStruct {
+ int i;
+ intVec iv;
+};
+
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(int), "");
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(float), "");
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(float4), "");
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(double2), "");
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(oneInt), "");
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(oneFloat), "");
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(twoInt), "");
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(threeInts), "");
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(notHomogenous), "");
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(depthDiff), "");
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(EightElements), "");
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(EightHalves), "");
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(oneIntWithVec), "");
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(weirdStruct), "");
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(RWBuffer<int>), "");
+
+
+// arrays not allowed
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(half[4]), "");
+
+template<typename T> struct TemplatedBuffer {
+ T a;
+ __hlsl_resource_t h;
+};
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(TemplatedBuffer<int>), "");
+
+struct MyStruct1 : TemplatedBuffer<float> {
+ float x;
+};
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(MyStruct1), "");
+
+struct MyStruct2 {
+ const TemplatedBuffer<float> TB[10];
+};
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(MyStruct2), "");
+
+template<typename T> struct SimpleTemplate {
+ T a;
+};
+
+// though the element type is incomplete, the type trait should still technically return true
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(SimpleTemplate<__hlsl_resource_t>), "");
+
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(SimpleTemplate<float>), "");
+
+
diff --git a/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErrors.hlsl b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
similarity index 62%
rename from clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErrors.hlsl
rename to clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
index 2277649df54f79..167a5be6e93843 100644
--- a/clang/test/SemaHLSL/Types/Traits/IsLineVectorLayoutCompatibleTypeErrors.hlsl
+++ b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -verify %s
// types must be complete
-_Static_assert(__builtin_hlsl_is_line_vector_layout_compatible(__hlsl_resource_t), "");
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(__hlsl_resource_t), "");
// expected-note at +1{{forward declaration of 'notComplete'}}
struct notComplete;
// expected-error at +1{{incomplete type 'notComplete' where a complete type is required}}
-_Static_assert(!__builtin_hlsl_is_line_vector_layout_compatible(notComplete), "");
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(notComplete), "");
>From 65b3141aa104c8c98929a3533085ee42d8c2266e Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Fri, 1 Nov 2024 11:07:15 -0700
Subject: [PATCH 6/7] remove whitespace change
---
clang/include/clang/AST/Type.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 0efbfbdf5625dd..ba3161c366f4d9 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2665,6 +2665,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
bool isHLSLAttributedResourceType() const;
bool isHLSLIntangibleType()
const; // Any HLSL intangible type (builtin, array, class)
+
/// Determines if this type, which must satisfy
/// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
/// than implicitly __strong.
>From 010785c3d9ac7e697a8e8de0f8e2f316ba9ecc03 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Mon, 4 Nov 2024 12:25:02 -0800
Subject: [PATCH 7/7] remove comparison of diff types
---
clang/lib/Sema/SemaHLSL.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index f9b1af44cba388..b4cd4aa9c85afd 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2188,8 +2188,7 @@ bool SemaHLSL::IsTypedResourceElementCompatible(clang::QualType QT) {
return false;
if (const BuiltinType *BT = TempQT->getAs<BuiltinType>()) {
- if (BT->getKind() == BuiltinType::Bool ||
- BT->getKind() == BuiltinType::Enum)
+ if (BT->isBooleanType() || BT->isEnumeralType())
return false;
// Check if it is an array type.
More information about the cfe-commits
mailing list