https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/104544
>From 6d5f8991a4ef9e79bc1bed30addf7b29b7ed0d2e Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Thu, 15 Aug 2024 19:03:29 -0700 Subject: [PATCH 1/5] Implement `__builtin_is_intangible` --- clang/include/clang/Basic/TokenKinds.def | 3 ++ clang/include/clang/Sema/SemaHLSL.h | 3 ++ clang/lib/Sema/SemaExprCXX.cpp | 8 ++++ clang/lib/Sema/SemaHLSL.cpp | 49 ++++++++++++++++++++++++ 4 files changed, 63 insertions(+) diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index d683106bb0e298..f4fc7c321d9c5a 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -660,6 +660,9 @@ KEYWORD(out , KEYHLSL) #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) KEYWORD(Name, KEYHLSL) #include "clang/Basic/HLSLIntangibleTypes.def" +// HLSL Type traits +TYPE_TRAIT_1(__builtin_is_intangible, IsIntangibleType, 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 d60cb2a57d4918..13e75a79ec6bf0 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -62,6 +62,9 @@ class SemaHLSL : public SemaBase { void handleParamModifierAttr(Decl *D, const ParsedAttr &AL); bool CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + + // HLSL Type trait implementations + bool IsIntangibleType(QualType T1) const; }; } // namespace clang diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 5356bcf172f752..f3f8d511a6e568 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -39,6 +39,7 @@ #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaCUDA.h" +#include "clang/Sema/SemaHLSL.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/SemaLambda.h" #include "clang/Sema/SemaObjC.h" @@ -5683,6 +5684,13 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, return true; return false; } + case UTT_IsIntangibleType: + if (!T->isVoidType() && !T->isIncompleteArrayType()) + if (Self.RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), T, + diag::err_incomplete_type)) + return true; + DiagnoseVLAInCXXTypeTrait(Self, TInfo, tok::kw___builtin_is_intangible); + return Self.HLSL().IsIntangibleType(T); } } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index e3e926465e799e..5978c14399ba32 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -12,6 +12,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/Type.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/TargetInfo.h" @@ -1154,3 +1155,51 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { } return false; } + +bool SemaHLSL::IsIntangibleType(QualType Ty) const { + if (Ty.isNull()) + return false; + + Ty = Ty.getCanonicalType().getUnqualifiedType(); + if (Ty->isBuiltinType()) + return Ty->isHLSLSpecificType(); + + llvm::SmallVector<QualType, 8> TypesToScan; + TypesToScan.push_back(Ty); + while (!TypesToScan.empty()) { + QualType T = TypesToScan.pop_back_val(); + assert(T == T.getCanonicalType().getUnqualifiedType() && "expected sugar-free type"); + assert(!isa<MatrixType>(T) && "Matrix types not yet supported in HLSL"); + + if (const auto *AT = dyn_cast<ConstantArrayType>(T)) { + QualType ElTy = AT->getElementType().getCanonicalType().getUnqualifiedType(); + if (ElTy->isBuiltinType()) + return ElTy->isHLSLSpecificType(); + TypesToScan.push_back(ElTy); + continue; + } + + if (const auto *VT = dyn_cast<VectorType>(T)) { + QualType ElTy = VT->getElementType().getCanonicalType().getUnqualifiedType(); + assert(ElTy->isBuiltinType() && "vectors can only contain builtin types"); + if (ElTy->isHLSLSpecificType()) + return true; + continue; + } + + if (const auto *RT = dyn_cast<RecordType>(T)) { + const RecordDecl *RD = RT->getDecl(); + for (const auto *FD : RD->fields()) { + QualType FieldTy = FD->getType().getCanonicalType().getUnqualifiedType(); + if (FieldTy->isBuiltinType()) { + if (FieldTy->isHLSLSpecificType()) + return true; + } else { + TypesToScan.push_back(FieldTy); + } + } + continue; + } + } + return false; +} >From d21ca2e2891acbd6c89864b57d864d881a8a8b96 Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Thu, 15 Aug 2024 20:52:24 -0700 Subject: [PATCH 2/5] add caching --- clang/include/clang/Sema/SemaHLSL.h | 5 ++++- clang/lib/Sema/SemaExprCXX.cpp | 1 + clang/lib/Sema/SemaHLSL.cpp | 22 +++++++++++++++++----- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index 13e75a79ec6bf0..663dea12880d1b 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -64,7 +64,10 @@ class SemaHLSL : public SemaBase { bool CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); // HLSL Type trait implementations - bool IsIntangibleType(QualType T1) const; + bool IsIntangibleType(const QualType T1); + +private: + llvm::DenseMap<const Type *, bool> IsIntangibleTypeCache; }; } // namespace clang diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index f3f8d511a6e568..d3964f5da01e00 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -5099,6 +5099,7 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT, case UTT_IsDestructible: case UTT_IsNothrowDestructible: case UTT_IsTriviallyDestructible: + case UTT_IsIntangibleType: if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType()) return true; diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 5978c14399ba32..e23240a380528d 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -28,7 +28,7 @@ using namespace clang; -SemaHLSL::SemaHLSL(Sema &S) : SemaBase(S) {} +SemaHLSL::SemaHLSL(Sema &S) : SemaBase(S), IsIntangibleTypeCache(8) {} Decl *SemaHLSL::ActOnStartBuffer(Scope *BufferScope, bool CBuffer, SourceLocation KwLoc, IdentifierInfo *Ident, @@ -1156,10 +1156,7 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return false; } -bool SemaHLSL::IsIntangibleType(QualType Ty) const { - if (Ty.isNull()) - return false; - +static bool calculateIsIntangibleType(QualType Ty) { Ty = Ty.getCanonicalType().getUnqualifiedType(); if (Ty->isBuiltinType()) return Ty->isHLSLSpecificType(); @@ -1203,3 +1200,18 @@ bool SemaHLSL::IsIntangibleType(QualType Ty) const { } return false; } + +bool SemaHLSL::IsIntangibleType(const clang::QualType Ty) { + if (Ty.isNull()) + return false; + + const auto CachedEntry = IsIntangibleTypeCache.find(Ty.getTypePtr()); + if (CachedEntry != IsIntangibleTypeCache.end()) { + assert(CachedEntry->second == calculateIsIntangibleType(Ty) && "IsIntangibleType mismatch"); + return CachedEntry->second; + } + + bool IsIntangible = calculateIsIntangibleType(Ty); + IsIntangibleTypeCache[Ty.getTypePtr()] = IsIntangible; + return IsIntangible; +} >From d7e8bce2e27f894196691435d2379edfdd6cd906 Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Thu, 15 Aug 2024 20:56:40 -0700 Subject: [PATCH 3/5] clang-format --- clang/lib/Sema/SemaHLSL.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index e23240a380528d..5e5917c40bc1cc 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -1165,19 +1165,22 @@ static bool calculateIsIntangibleType(QualType Ty) { TypesToScan.push_back(Ty); while (!TypesToScan.empty()) { QualType T = TypesToScan.pop_back_val(); - assert(T == T.getCanonicalType().getUnqualifiedType() && "expected sugar-free type"); + assert(T == T.getCanonicalType().getUnqualifiedType() && + "expected sugar-free type"); assert(!isa<MatrixType>(T) && "Matrix types not yet supported in HLSL"); if (const auto *AT = dyn_cast<ConstantArrayType>(T)) { - QualType ElTy = AT->getElementType().getCanonicalType().getUnqualifiedType(); + QualType ElTy = + AT->getElementType().getCanonicalType().getUnqualifiedType(); if (ElTy->isBuiltinType()) return ElTy->isHLSLSpecificType(); TypesToScan.push_back(ElTy); - continue; + continue; } if (const auto *VT = dyn_cast<VectorType>(T)) { - QualType ElTy = VT->getElementType().getCanonicalType().getUnqualifiedType(); + QualType ElTy = + VT->getElementType().getCanonicalType().getUnqualifiedType(); assert(ElTy->isBuiltinType() && "vectors can only contain builtin types"); if (ElTy->isHLSLSpecificType()) return true; @@ -1187,12 +1190,13 @@ static bool calculateIsIntangibleType(QualType Ty) { if (const auto *RT = dyn_cast<RecordType>(T)) { const RecordDecl *RD = RT->getDecl(); for (const auto *FD : RD->fields()) { - QualType FieldTy = FD->getType().getCanonicalType().getUnqualifiedType(); + QualType FieldTy = + FD->getType().getCanonicalType().getUnqualifiedType(); if (FieldTy->isBuiltinType()) { if (FieldTy->isHLSLSpecificType()) return true; } else { - TypesToScan.push_back(FieldTy); + TypesToScan.push_back(FieldTy); } } continue; @@ -1207,7 +1211,8 @@ bool SemaHLSL::IsIntangibleType(const clang::QualType Ty) { const auto CachedEntry = IsIntangibleTypeCache.find(Ty.getTypePtr()); if (CachedEntry != IsIntangibleTypeCache.end()) { - assert(CachedEntry->second == calculateIsIntangibleType(Ty) && "IsIntangibleType mismatch"); + assert(CachedEntry->second == calculateIsIntangibleType(Ty) && + "IsIntangibleType mismatch"); return CachedEntry->second; } >From 481c118d7d94f16c9cc9babbaaa794f951883088 Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Thu, 15 Aug 2024 21:16:19 -0700 Subject: [PATCH 4/5] add tests --- .../Types/Traits/IsIntangibleType.hlsl | 52 +++++++++++++++++++ .../Types/Traits/IsIntangibleTypeErrors.hlsl | 11 ++++ 2 files changed, 63 insertions(+) create mode 100644 clang/test/SemaHLSL/Types/Traits/IsIntangibleType.hlsl create mode 100644 clang/test/SemaHLSL/Types/Traits/IsIntangibleTypeErrors.hlsl diff --git a/clang/test/SemaHLSL/Types/Traits/IsIntangibleType.hlsl b/clang/test/SemaHLSL/Types/Traits/IsIntangibleType.hlsl new file mode 100644 index 00000000000000..ae6da681d5100e --- /dev/null +++ b/clang/test/SemaHLSL/Types/Traits/IsIntangibleType.hlsl @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -verify %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -verify %s +// expected-no-diagnostics + +_Static_assert(__builtin_is_intangible(__hlsl_resource_t), ""); +// no need to check array of __hlsl_resource_t, arrays of sizeless types are not supported + +_Static_assert(!__builtin_is_intangible(int), ""); +_Static_assert(!__builtin_is_intangible(float3), ""); +_Static_assert(!__builtin_is_intangible(half[4]), ""); + +typedef __hlsl_resource_t Res; +_Static_assert(__builtin_is_intangible(const Res), ""); +// no need to check array of Res, arrays of sizeless types are not supported + +struct ABuffer { + const int i[10]; + __hlsl_resource_t h; +}; +_Static_assert(__builtin_is_intangible(ABuffer), ""); +_Static_assert(__builtin_is_intangible(ABuffer[10]), ""); + +struct MyStruct { + half2 h2; + int3 i3; +}; +_Static_assert(!__builtin_is_intangible(MyStruct), ""); +_Static_assert(!__builtin_is_intangible(MyStruct[10]), ""); + +class MyClass { + int3 ivec; + float farray[12]; + MyStruct ms; + ABuffer buf; +}; +_Static_assert(__builtin_is_intangible(MyClass), ""); +_Static_assert(__builtin_is_intangible(MyClass[2]), ""); + +union U { + double d[4]; + Res buf; +}; +_Static_assert(__builtin_is_intangible(U), ""); +_Static_assert(__builtin_is_intangible(U[100]), ""); + +class MyClass2 { + int3 ivec; + float farray[12]; + U u; +}; +_Static_assert(__builtin_is_intangible(MyClass2), ""); +_Static_assert(__builtin_is_intangible(MyClass2[5]), ""); diff --git a/clang/test/SemaHLSL/Types/Traits/IsIntangibleTypeErrors.hlsl b/clang/test/SemaHLSL/Types/Traits/IsIntangibleTypeErrors.hlsl new file mode 100644 index 00000000000000..bfb654de0dcfca --- /dev/null +++ b/clang/test/SemaHLSL/Types/Traits/IsIntangibleTypeErrors.hlsl @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -verify %s + +struct Undefined; // expected-note {{forward declaration of 'Undefined'}} +_Static_assert(!__builtin_is_intangible(Undefined), ""); // expected-error{{incomplete type 'Undefined' used in type trait expression}} + +void fn(int X) { + // expected-error@#vla {{variable length arrays are not supported for the current target}} + // expected-error@#vla {{variable length arrays are not supported in '__builtin_is_intangible'}} + // expected-warning@#vla {{variable length arrays in C++ are a Clang extension}} + _Static_assert(!__builtin_is_intangible(int[X]), ""); // #vla +} \ No newline at end of file >From 2df05761de1df378cedec49430c327a21f8ee089 Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Thu, 15 Aug 2024 21:56:28 -0700 Subject: [PATCH 5/5] base classes! --- clang/lib/Sema/SemaHLSL.cpp | 21 +++++++++++-------- .../Types/Traits/IsIntangibleType.hlsl | 9 ++++++++ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 5e5917c40bc1cc..09d4d6e7f13c72 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -10,6 +10,7 @@ #include "clang/Sema/SemaHLSL.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Type.h" @@ -1157,7 +1158,7 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { } static bool calculateIsIntangibleType(QualType Ty) { - Ty = Ty.getCanonicalType().getUnqualifiedType(); + Ty = Ty->getCanonicalTypeUnqualified(); if (Ty->isBuiltinType()) return Ty->isHLSLSpecificType(); @@ -1165,13 +1166,11 @@ static bool calculateIsIntangibleType(QualType Ty) { TypesToScan.push_back(Ty); while (!TypesToScan.empty()) { QualType T = TypesToScan.pop_back_val(); - assert(T == T.getCanonicalType().getUnqualifiedType() && - "expected sugar-free type"); + assert(T == T->getCanonicalTypeUnqualified() && "expected sugar-free type"); assert(!isa<MatrixType>(T) && "Matrix types not yet supported in HLSL"); if (const auto *AT = dyn_cast<ConstantArrayType>(T)) { - QualType ElTy = - AT->getElementType().getCanonicalType().getUnqualifiedType(); + QualType ElTy = AT->getElementType()->getCanonicalTypeUnqualified(); if (ElTy->isBuiltinType()) return ElTy->isHLSLSpecificType(); TypesToScan.push_back(ElTy); @@ -1179,8 +1178,7 @@ static bool calculateIsIntangibleType(QualType Ty) { } if (const auto *VT = dyn_cast<VectorType>(T)) { - QualType ElTy = - VT->getElementType().getCanonicalType().getUnqualifiedType(); + QualType ElTy = VT->getElementType()->getCanonicalTypeUnqualified(); assert(ElTy->isBuiltinType() && "vectors can only contain builtin types"); if (ElTy->isHLSLSpecificType()) return true; @@ -1190,8 +1188,7 @@ static bool calculateIsIntangibleType(QualType Ty) { if (const auto *RT = dyn_cast<RecordType>(T)) { const RecordDecl *RD = RT->getDecl(); for (const auto *FD : RD->fields()) { - QualType FieldTy = - FD->getType().getCanonicalType().getUnqualifiedType(); + QualType FieldTy = FD->getType()->getCanonicalTypeUnqualified(); if (FieldTy->isBuiltinType()) { if (FieldTy->isHLSLSpecificType()) return true; @@ -1199,6 +1196,12 @@ static bool calculateIsIntangibleType(QualType Ty) { TypesToScan.push_back(FieldTy); } } + + if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { + for (const CXXBaseSpecifier &B : CXXRD->bases()) { + TypesToScan.push_back(B.getType()->getCanonicalTypeUnqualified()); + } + } continue; } } diff --git a/clang/test/SemaHLSL/Types/Traits/IsIntangibleType.hlsl b/clang/test/SemaHLSL/Types/Traits/IsIntangibleType.hlsl index ae6da681d5100e..f7ef7f543bfb5e 100644 --- a/clang/test/SemaHLSL/Types/Traits/IsIntangibleType.hlsl +++ b/clang/test/SemaHLSL/Types/Traits/IsIntangibleType.hlsl @@ -50,3 +50,12 @@ class MyClass2 { }; _Static_assert(__builtin_is_intangible(MyClass2), ""); _Static_assert(__builtin_is_intangible(MyClass2[5]), ""); + +class Simple { + int a; +}; + +class MyClass3 : MyClass2, Simple { + half h; +}; +_Static_assert(__builtin_is_intangible(MyClass3), ""); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits