https://github.com/akash-manna-sky created 
https://github.com/llvm/llvm-project/pull/215480

## [clang][Diagnostics] Use `enum_select` for `err_builtin_invalid_arg_type`

`err_builtin_invalid_arg_type` has three `%select` components — a container
shape, an integer-like type and a floating-point type — and all 42 call sites in
`SemaChecking.cpp`, `SemaHLSL.cpp` and `SemaSPIRV.cpp` select them with bare
integer literals. Nothing checks those literals against the format string, and
two had already gone wrong:

- `BuiltinBswapg` and `BuiltinBitreverseg` documented `/*unsigned integer=*/1`,
  but `1` selects `integer`.
- `__builtin_hlsl_wave_active_bit_{or,xor,and}` passed its arguments in the
  wrong order entirely — `<< ArgTyExpr << SemaRef.Context.UnsignedIntTy << 1 << 
0 << 0`
  feeds a `QualType` into `%ordinal0` and a second `QualType` into the first
  `%select`. Any floating-point argument produced a malformed message and 
tripped
  the `assert(ModifierLen == 0)` in `Diagnostic::FormatDiagnostic`. The path had
  no test coverage.

This converts the three components to `%enum_select`, generating
`diag::BuiltinArgContainerKind`, `diag::BuiltinArgIntegerKind` and
`diag::BuiltinArgFloatingKind`, and updates every call site to name its
selection:

```c++
return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
       << ArgOrdinal << diag::BuiltinArgContainerKind::ScalarOrVectorOf
       << diag::BuiltinArgIntegerKind::None
       << diag::BuiltinArgFloatingKind::FloatingPoint << ArgTy;
```

Empty options are named `None` so callers spell out the "nothing selected" case
instead of passing a bare `0`. Enumerator values match the previous `%select`
indices, so the surrounding `%plural` logic and the rendered text are unchanged
apart from the corrected wave-builtin diagnostic.

Testing: added scalar and vector cases to
`clang/test/SemaHLSL/BuiltIns/WaveActiveBitOr-errors.hlsl` for the corrected
diagnostic, and a case to `clang/test/TableGen/select-enum.td` for a *named*
option with empty text (`%None{}`), which the `None` enumerators rely on and
nothing previously covered.

Fixes #123121

Assisted by Claude


>From 288fbb0066507c1b888b418c2c1c0853d9e53fff Mon Sep 17 00:00:00 2001
From: Akash Manna <[email protected]>
Date: Tue, 11 Aug 2026 12:33:08 +0530
Subject: [PATCH] [clang][Diagnostics] Use enum_select for
 err_builtin_invalid_arg_type

err_builtin_invalid_arg_type is built from three %select components -- a
container shape, an integer-like type and a floating-point type -- and each
of its 42 call sites across SemaChecking.cpp, SemaHLSL.cpp and SemaSPIRV.cpp
selects them with bare integer literals. Nothing checks those literals
against the format string, and the comments beside them had already drifted:
BuiltinBswapg and BuiltinBitreverseg documented /*unsigned integer=*/1 where
1 selects "integer", and the check for __builtin_hlsl_wave_active_bit_{or,
xor,and} passed its arguments in the wrong order entirely, feeding a QualType
into %ordinal0 and a second QualType into the first %select. Any
floating-point argument to those builtins produced a malformed message.

Convert the three components to %enum_select so TableGen emits
diag::BuiltinArgContainerKind, diag::BuiltinArgIntegerKind and
diag::BuiltinArgFloatingKind, and update every call site to name its
selection. Empty options are named None so callers spell out the "nothing
selected" case instead of passing a bare 0.

The enumerator values match the previous %select indices, so the rendered
text is unchanged apart from the corrected wave builtin diagnostic, which
gains test coverage along with the named-empty-option TableGen case that the
new enumerators depend on.

Towards #123121.
---
 .../clang/Basic/DiagnosticSemaKinds.td        |  13 +-
 clang/lib/Sema/SemaChecking.cpp               | 117 +++++++++++-------
 clang/lib/Sema/SemaHLSL.cpp                   |  60 +++++----
 clang/lib/Sema/SemaSPIRV.cpp                  |  30 +++--
 .../BuiltIns/WaveActiveBitOr-errors.hlsl      |  10 ++
 clang/test/TableGen/select-enum.td            |  10 ++
 6 files changed, 158 insertions(+), 82 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4e9c6fd8cbf0e..415c61d7e0676 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13403,21 +13403,26 @@ def err_builtin_is_within_lifetime_invalid_arg : 
Error<
 def err_builtin_invalid_arg_type: Error<
   "%ordinal0 argument must be a "
   // First component: scalar or container types
-  "%select{|scalar|vector|matrix|vector of|scalar or vector of}1"
+  "%enum_select<BuiltinArgContainerKind>{%None{}|%Scalar{scalar}|"
+  "%Vector{vector}|%Matrix{matrix}|%VectorOf{vector of}|"
+  "%ScalarOrVectorOf{scalar or vector of}}1"
   // A comma after generic vector/matrix types if there are non-empty second
   // and third components, to initiate a list.
   "%plural{[2,3]:%plural{0:|:%plural{0:|:,}2}3|:}1"
   // A space after a non-empty first component
   "%plural{0:|: }1"
   // Second component: integer-like types
-  "%select{|integer|signed integer|unsigned integer|'int'|"
-  "pointer to a valid matrix element|boolean}2"
+  "%enum_select<BuiltinArgIntegerKind>{%None{}|%Integer{integer}|"
+  "%SignedInteger{signed integer}|%UnsignedInteger{unsigned integer}|"
+  "%Int{'int'}|%MatrixElementPointer{pointer to a valid matrix element}|"
+  "%Boolean{boolean}}2"
   // A space after a non-empty second component
   "%plural{0:|: }2"
   // An 'or' if non-empty second and third components are combined
   "%plural{0:|:%plural{0:|:or }2}3"
   // Third component: floating-point types
-  "%select{|floating-point|16 or 32 bit floating-point}3"
+  
"%enum_select<BuiltinArgFloatingKind>{%None{}|%FloatingPoint{floating-point}|"
+  "%Float16Or32{16 or 32 bit floating-point}}3"
   // A space after a non-empty third component
   "%plural{0:|: }3"
   "%plural{[0,3]:type|:types}1 (was %4)">;
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0db040ed90e3f..1639616e0d87b 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2354,30 +2354,34 @@ checkMathBuiltinElementType(Sema &S, SourceLocation 
Loc, QualType ArgTy,
   case Sema::EltwiseBuiltinArgTyRestriction::None:
     if (!ArgTy->getAs<VectorType>() && !isValidMathElementType(ArgTy)) {
       return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
-             << ArgOrdinal << /* vector */ 2 << /* integer */ 1 << /* fp */ 1
-             << ArgTy;
+             << ArgOrdinal << diag::BuiltinArgContainerKind::Vector
+             << diag::BuiltinArgIntegerKind::Integer
+             << diag::BuiltinArgFloatingKind::FloatingPoint << ArgTy;
     }
     break;
   case Sema::EltwiseBuiltinArgTyRestriction::FloatTy:
     if (!EltTy->isRealFloatingType()) {
       // FIXME: make diagnostic's wording correct for matrices
       return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
-             << ArgOrdinal << /* scalar or vector */ 5 << /* no int */ 0
-             << /* floating-point */ 1 << ArgTy;
+             << ArgOrdinal << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+             << diag::BuiltinArgIntegerKind::None
+             << diag::BuiltinArgFloatingKind::FloatingPoint << ArgTy;
     }
     break;
   case Sema::EltwiseBuiltinArgTyRestriction::IntegerTy:
     if (!EltTy->isIntegerType()) {
       return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
-             << ArgOrdinal << /* scalar or vector */ 5 << /* integer */ 1
-             << /* no fp */ 0 << ArgTy;
+             << ArgOrdinal << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+             << diag::BuiltinArgIntegerKind::Integer
+             << diag::BuiltinArgFloatingKind::None << ArgTy;
     }
     break;
   case Sema::EltwiseBuiltinArgTyRestriction::SignedIntOrFloatTy:
     if (!EltTy->isSignedIntegerType() && !EltTy->isRealFloatingType()) {
       return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
-             << 1 << /* scalar or vector */ 5 << /* signed int */ 2
-             << /* or fp */ 1 << ArgTy;
+             << 1 << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+             << diag::BuiltinArgIntegerKind::SignedInteger
+             << diag::BuiltinArgFloatingKind::FloatingPoint << ArgTy;
     }
     break;
   }
@@ -2448,8 +2452,9 @@ static bool BuiltinBswapg(Sema &S, CallExpr *TheCall) {
 
   if (!ArgTy->isIntegerType()) {
     S.Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-        << 1 << /*scalar=*/1 << /*unsigned integer=*/1 << /*floating point=*/0
-        << ArgTy;
+        << 1 << diag::BuiltinArgContainerKind::Scalar
+        << diag::BuiltinArgIntegerKind::Integer
+        << diag::BuiltinArgFloatingKind::None << ArgTy;
     return true;
   }
   if (const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
@@ -2482,8 +2487,9 @@ static bool BuiltinBitreverseg(Sema &S, CallExpr 
*TheCall) {
 
   if (!ArgTy->isIntegerType()) {
     S.Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-        << 1 << /*scalar=*/1 << /*unsigned integer*/ 1 << /*float point*/ 0
-        << ArgTy;
+        << 1 << diag::BuiltinArgContainerKind::Scalar
+        << diag::BuiltinArgIntegerKind::Integer
+        << diag::BuiltinArgFloatingKind::None << ArgTy;
     return true;
   }
   TheCall->setType(ArgTy);
@@ -2507,8 +2513,9 @@ static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall) {
 
   if (!ArgTy->isUnsignedIntegerType() && !ArgTy->isExtVectorBoolType()) {
     S.Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-        << 1 << /* scalar */ 1 << /* unsigned integer ty */ 3 << /* no fp */ 0
-        << ArgTy;
+        << 1 << diag::BuiltinArgContainerKind::Scalar
+        << diag::BuiltinArgIntegerKind::UnsignedInteger
+        << diag::BuiltinArgFloatingKind::None << ArgTy;
     return true;
   }
   return false;
@@ -2571,8 +2578,9 @@ static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr 
*TheCall) {
 
   if (!Arg0Ty->isUnsignedIntegerType() && !Arg0Ty->isExtVectorBoolType()) {
     S.Diag(Arg0->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-        << 1 << /* scalar */ 1 << /* unsigned integer ty */ 3 << /* no fp */ 0
-        << Arg0Ty;
+        << 1 << diag::BuiltinArgContainerKind::Scalar
+        << diag::BuiltinArgIntegerKind::UnsignedInteger
+        << diag::BuiltinArgFloatingKind::None << Arg0Ty;
     return true;
   }
 
@@ -2588,7 +2596,9 @@ static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr 
*TheCall) {
 
     if (!Arg1Ty->isSpecificBuiltinType(BuiltinType::Int)) {
       S.Diag(Arg1->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-          << 2 << /* scalar */ 1 << /* 'int' ty */ 4 << /* no fp */ 0 << 
Arg1Ty;
+          << 2 << diag::BuiltinArgContainerKind::Scalar
+          << diag::BuiltinArgIntegerKind::Int
+          << diag::BuiltinArgFloatingKind::None << Arg1Ty;
       return true;
     }
   }
@@ -2603,9 +2613,10 @@ class RotateIntegerConverter : public 
Sema::ContextualImplicitConverter {
   Sema::SemaDiagnosticBuilder emitError(Sema &S, SourceLocation Loc,
                                         QualType T) {
     return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
-           << ArgIndex << /*scalar*/ 1
-           << (OnlyUnsigned ? /*unsigned integer*/ 3 : /*integer*/ 1)
-           << /*no fp*/ 0 << T;
+           << ArgIndex << diag::BuiltinArgContainerKind::Scalar
+           << (OnlyUnsigned ? diag::BuiltinArgIntegerKind::UnsignedInteger
+                            : diag::BuiltinArgIntegerKind::Integer)
+           << diag::BuiltinArgFloatingKind::None << T;
   }
 
 public:
@@ -2701,8 +2712,9 @@ static bool CheckMaskedBuiltinArgs(Sema &S, Expr 
*MaskArg, Expr *PtrArg,
   QualType MaskTy = MaskArg->getType();
   if (!MaskTy->isExtVectorBoolType())
     return S.Diag(MaskArg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-           << 1 << /* vector of */ 4 << /* booleans */ 6 << /* no fp */ 0
-           << MaskTy;
+           << 1 << diag::BuiltinArgContainerKind::VectorOf
+           << diag::BuiltinArgIntegerKind::Boolean
+           << diag::BuiltinArgFloatingKind::None << MaskTy;
 
   QualType PtrTy = PtrArg->getType();
   if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
@@ -2846,8 +2858,9 @@ static ExprResult BuiltinMaskedGather(Sema &S, CallExpr 
*TheCall) {
   const VectorType *IdxVecTy = IdxTy->getAs<VectorType>();
   if (!IdxTy->isVectorType() || !IdxVecTy->getElementType()->isIntegerType())
     return S.Diag(MaskArg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-           << 1 << /* vector of */ 4 << /* integer */ 1 << /* no fp */ 0
-           << IdxTy;
+           << 1 << diag::BuiltinArgContainerKind::VectorOf
+           << diag::BuiltinArgIntegerKind::Integer
+           << diag::BuiltinArgFloatingKind::None << IdxTy;
 
   QualType MaskTy = MaskArg->getType();
   QualType PtrTy = PtrArg->getType();
@@ -2897,8 +2910,9 @@ static ExprResult BuiltinMaskedScatter(Sema &S, CallExpr 
*TheCall) {
   const VectorType *IdxVecTy = IdxTy->getAs<VectorType>();
   if (!IdxTy->isVectorType() || !IdxVecTy->getElementType()->isIntegerType())
     return S.Diag(MaskArg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-           << 2 << /* vector of */ 4 << /* integer */ 1 << /* no fp */ 0
-           << IdxTy;
+           << 2 << diag::BuiltinArgContainerKind::VectorOf
+           << diag::BuiltinArgIntegerKind::Integer
+           << diag::BuiltinArgFloatingKind::None << IdxTy;
 
   QualType ValTy = ValArg->getType();
   QualType MaskTy = MaskArg->getType();
@@ -3951,8 +3965,9 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
 
     if (ElTy.isNull()) {
       Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-          << 1 << /* vector ty */ 2 << /* no int */ 0 << /* no fp */ 0
-          << Arg->getType();
+          << 1 << diag::BuiltinArgContainerKind::Vector
+          << diag::BuiltinArgIntegerKind::None
+          << diag::BuiltinArgFloatingKind::None << Arg->getType();
       return ExprError();
     }
 
@@ -3975,8 +3990,9 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
 
     if (ElTy.isNull() || !ElTy->isFloatingType()) {
       Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-          << 1 << /* vector of */ 4 << /* no int */ 0 << /* fp */ 1
-          << Arg->getType();
+          << 1 << diag::BuiltinArgContainerKind::VectorOf
+          << diag::BuiltinArgIntegerKind::None
+          << diag::BuiltinArgFloatingKind::FloatingPoint << Arg->getType();
       return ExprError();
     }
 
@@ -3999,8 +4015,9 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
     QualType ElTy = getVectorElementType(Context, Arg->getType());
     if (ElTy.isNull() || !ElTy->isIntegerType()) {
       Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-          << 1 << /* vector of */ 4 << /* int */ 1 << /* no fp */ 0
-          << Arg->getType();
+          << 1 << diag::BuiltinArgContainerKind::VectorOf
+          << diag::BuiltinArgIntegerKind::Integer
+          << diag::BuiltinArgFloatingKind::None << Arg->getType();
       return ExprError();
     }
 
@@ -4024,7 +4041,9 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
     QualType ElTy = getVectorElementType(Context, Vec.get()->getType());
     if (ElTy.isNull() || !ElTy->isRealFloatingType()) {
       Diag(Vec.get()->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-          << 1 << /* vector of */ 4 << /* no int */ 0 << /* fp */ 1
+          << 1 << diag::BuiltinArgContainerKind::VectorOf
+          << diag::BuiltinArgIntegerKind::None
+          << diag::BuiltinArgFloatingKind::FloatingPoint
           << Vec.get()->getType();
       return ExprError();
     }
@@ -4037,7 +4056,9 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
       if (!StartValue.get()->getType()->isRealFloatingType()) {
         Diag(StartValue.get()->getBeginLoc(),
              diag::err_builtin_invalid_arg_type)
-            << 2 << /* scalar */ 1 << /* no int */ 0 << /* fp */ 1
+            << 2 << diag::BuiltinArgContainerKind::Scalar
+            << diag::BuiltinArgIntegerKind::None
+            << diag::BuiltinArgFloatingKind::FloatingPoint
             << StartValue.get()->getType();
         return ExprError();
       }
@@ -17282,7 +17303,9 @@ bool Sema::BuiltinNonDeterministicValue(CallExpr 
*TheCall) {
   if (!TyArg->isBuiltinType() && !TyArg->isVectorType())
     return Diag(TheCall->getArg(0)->getBeginLoc(),
                 diag::err_builtin_invalid_arg_type)
-           << 1 << /* vector */ 2 << /* integer */ 1 << /* fp */ 1 << TyArg;
+           << 1 << diag::BuiltinArgContainerKind::Vector
+           << diag::BuiltinArgIntegerKind::Integer
+           << diag::BuiltinArgFloatingKind::FloatingPoint << TyArg;
 
   TheCall->setType(TyArg);
   return false;
@@ -17301,8 +17324,9 @@ ExprResult Sema::BuiltinMatrixTranspose(CallExpr 
*TheCall,
   auto *MType = Matrix->getType()->getAs<ConstantMatrixType>();
   if (!MType) {
     Diag(Matrix->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-        << 1 << /* matrix */ 3 << /* no int */ 0 << /* no fp */ 0
-        << Matrix->getType();
+        << 1 << diag::BuiltinArgContainerKind::Matrix
+        << diag::BuiltinArgIntegerKind::None
+        << diag::BuiltinArgFloatingKind::None << Matrix->getType();
     return ExprError();
   }
 
@@ -17379,16 +17403,18 @@ ExprResult 
Sema::BuiltinMatrixColumnMajorLoad(CallExpr *TheCall,
   QualType ElementTy;
   if (!PtrTy) {
     Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-        << PtrArgIdx + 1 << 0 << /* pointer to element ty */ 5 << /* no fp */ 0
-        << PtrExpr->getType();
+        << PtrArgIdx + 1 << diag::BuiltinArgContainerKind::None
+        << diag::BuiltinArgIntegerKind::MatrixElementPointer
+        << diag::BuiltinArgFloatingKind::None << PtrExpr->getType();
     ArgError = true;
   } else {
     ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
 
     if (!ConstantMatrixType::isValidElementType(ElementTy, getLangOpts())) {
       Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-          << PtrArgIdx + 1 << 0 << /* pointer to element ty */ 5
-          << /* no fp */ 0 << PtrExpr->getType();
+          << PtrArgIdx + 1 << diag::BuiltinArgContainerKind::None
+          << diag::BuiltinArgIntegerKind::MatrixElementPointer
+          << diag::BuiltinArgFloatingKind::None << PtrExpr->getType();
       ArgError = true;
     }
   }
@@ -17500,7 +17526,9 @@ ExprResult Sema::BuiltinMatrixColumnMajorStore(CallExpr 
*TheCall,
   auto *MatrixTy = MatrixExpr->getType()->getAs<ConstantMatrixType>();
   if (!MatrixTy) {
     Diag(MatrixExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-        << 1 << /* matrix ty */ 3 << 0 << 0 << MatrixExpr->getType();
+        << 1 << diag::BuiltinArgContainerKind::Matrix
+        << diag::BuiltinArgIntegerKind::None
+        << diag::BuiltinArgFloatingKind::None << MatrixExpr->getType();
     ArgError = true;
   }
 
@@ -17520,8 +17548,9 @@ ExprResult Sema::BuiltinMatrixColumnMajorStore(CallExpr 
*TheCall,
   auto *PtrTy = PtrExpr->getType()->getAs<PointerType>();
   if (!PtrTy) {
     Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-        << PtrArgIdx + 1 << 0 << /* pointer to element ty */ 5 << 0
-        << PtrExpr->getType();
+        << PtrArgIdx + 1 << diag::BuiltinArgContainerKind::None
+        << diag::BuiltinArgIntegerKind::MatrixElementPointer
+        << diag::BuiltinArgFloatingKind::None << PtrExpr->getType();
     ArgError = true;
   } else {
     QualType ElementTy = PtrTy->getPointeeType();
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 3b9d9e4ed964b..83d9571f3593e 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3387,8 +3387,9 @@ static bool CheckFloatRepresentation(Sema *S, 
SourceLocation Loc,
           : PassedType;
   if (!BaseType->isFloat32Type())
     return S->Diag(Loc, diag::err_builtin_invalid_arg_type)
-           << ArgOrdinal << /* scalar or vector of */ 5 << /* no int */ 0
-           << /* float */ 1 << PassedType;
+           << ArgOrdinal << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+           << diag::BuiltinArgIntegerKind::None
+           << diag::BuiltinArgFloatingKind::FloatingPoint << PassedType;
   return false;
 }
 
@@ -3403,8 +3404,9 @@ static bool CheckFloatOrHalfRepresentation(Sema *S, 
SourceLocation Loc,
 
   if (!BaseType->isHalfType() && !BaseType->isFloat32Type())
     return S->Diag(Loc, diag::err_builtin_invalid_arg_type)
-           << ArgOrdinal << /* scalar or vector of */ 5 << /* no int */ 0
-           << /* half or float */ 2 << PassedType;
+           << ArgOrdinal << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+           << diag::BuiltinArgIntegerKind::None
+           << diag::BuiltinArgFloatingKind::Float16Or32 << PassedType;
   return false;
 }
 
@@ -3460,8 +3462,9 @@ static bool CheckNoDoubleVectors(Sema *S, SourceLocation 
Loc, int ArgOrdinal,
 
   if (VecTy->getElementType()->isDoubleType())
     return S->Diag(Loc, diag::err_builtin_invalid_arg_type)
-           << ArgOrdinal << /* scalar */ 1 << /* no int */ 0 << /* fp */ 1
-           << PassedType;
+           << ArgOrdinal << diag::BuiltinArgContainerKind::Scalar
+           << diag::BuiltinArgIntegerKind::None
+           << diag::BuiltinArgFloatingKind::FloatingPoint << PassedType;
   return false;
 }
 
@@ -3471,8 +3474,9 @@ static bool CheckFloatingOrIntRepresentation(Sema *S, 
SourceLocation Loc,
   if (!PassedType->hasIntegerRepresentation() &&
       !PassedType->hasFloatingRepresentation())
     return S->Diag(Loc, diag::err_builtin_invalid_arg_type)
-           << ArgOrdinal << /* scalar or vector of */ 5 << /* integer */ 1
-           << /* fp */ 1 << PassedType;
+           << ArgOrdinal << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+           << diag::BuiltinArgIntegerKind::Integer
+           << diag::BuiltinArgFloatingKind::FloatingPoint << PassedType;
   return false;
 }
 
@@ -3484,8 +3488,9 @@ static bool CheckUnsignedIntVecRepresentation(Sema *S, 
SourceLocation Loc,
       return false;
 
   return S->Diag(Loc, diag::err_builtin_invalid_arg_type)
-         << ArgOrdinal << /* vector of */ 4 << /* uint */ 3 << /* no fp */ 0
-         << PassedType;
+         << ArgOrdinal << diag::BuiltinArgContainerKind::VectorOf
+         << diag::BuiltinArgIntegerKind::UnsignedInteger
+         << diag::BuiltinArgFloatingKind::None << PassedType;
 }
 
 // checks for unsigned ints of all sizes
@@ -3494,8 +3499,9 @@ static bool CheckUnsignedIntRepresentation(Sema *S, 
SourceLocation Loc,
                                            clang::QualType PassedType) {
   if (!PassedType->hasUnsignedIntegerRepresentation())
     return S->Diag(Loc, diag::err_builtin_invalid_arg_type)
-           << ArgOrdinal << /* scalar or vector of */ 5 << /* unsigned int */ 3
-           << /* no fp */ 0 << PassedType;
+           << ArgOrdinal << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+           << diag::BuiltinArgIntegerKind::UnsignedInteger
+           << diag::BuiltinArgFloatingKind::None << PassedType;
   return false;
 }
 
@@ -4397,8 +4403,9 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
 
     if (!EltTy->isIntegerType()) {
       Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-          << 1 << /* scalar or vector of */ 5 << /* integer ty */ 1
-          << /* no fp */ 0 << ArgTy;
+          << 1 << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+          << diag::BuiltinArgIntegerKind::Integer
+          << diag::BuiltinArgFloatingKind::None << ArgTy;
       return true;
     }
 
@@ -4428,8 +4435,10 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
              ->hasFloatingRepresentation()) // half or float or double
       return SemaRef.Diag(TheCall->getArg(0)->getBeginLoc(),
                           diag::err_builtin_invalid_arg_type)
-             << /* ordinal */ 1 << /* scalar or vector */ 5 << /* no int */ 0
-             << /* fp */ 1 << TheCall->getArg(0)->getType();
+             << 1 << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+             << diag::BuiltinArgIntegerKind::None
+             << diag::BuiltinArgFloatingKind::FloatingPoint
+             << TheCall->getArg(0)->getType();
     if (SemaRef.PrepareBuiltinElementwiseMathOneArgCall(TheCall))
       return true;
     break;
@@ -4563,7 +4572,9 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
     const auto *MatTy = ArgTy->getAs<ConstantMatrixType>();
     if (!MatTy) {
       SemaRef.Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-          << 1 << /* matrix */ 3 << /* no int */ 0 << /* no fp */ 0 << ArgTy;
+          << 1 << diag::BuiltinArgContainerKind::Matrix
+          << diag::BuiltinArgIntegerKind::None
+          << diag::BuiltinArgFloatingKind::None << ArgTy;
       return true;
     }
 
@@ -4644,7 +4655,9 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
           (VTy && VTy->getElementType()->isIntegerType()))) {
       SemaRef.Diag(TheCall->getArg(0)->getBeginLoc(),
                    diag::err_builtin_invalid_arg_type)
-          << ArgTyExpr << SemaRef.Context.UnsignedIntTy << 1 << 0 << 0;
+          << 1 << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+          << diag::BuiltinArgIntegerKind::Integer
+          << diag::BuiltinArgFloatingKind::None << ArgTyExpr;
       return true;
     }
 
@@ -4676,8 +4689,9 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
     if (!DestTy->isIntegerType()) {
       SemaRef.Diag(TheCall->getArg(0)->getBeginLoc(),
                    diag::err_builtin_invalid_arg_type)
-          << /*ordinal=*/1 << /*scalar*/ 1 << /*integer*/ 1 << /*no float*/ 0
-          << DestTy;
+          << 1 << diag::BuiltinArgContainerKind::Scalar
+          << diag::BuiltinArgIntegerKind::Integer
+          << diag::BuiltinArgFloatingKind::None << DestTy;
       return true;
     }
 
@@ -4893,8 +4907,10 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
     if (ArgTy->isBooleanType()) {
       SemaRef.Diag(TheCall->getArg(0)->getBeginLoc(),
                    diag::err_builtin_invalid_arg_type)
-          << 1 << /* scalar or vector of */ 5 << /* unsigned int */ 3
-          << /* no fp */ 0 << TheCall->getArg(0)->getType();
+          << 1 << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+          << diag::BuiltinArgIntegerKind::UnsignedInteger
+          << diag::BuiltinArgFloatingKind::None
+          << TheCall->getArg(0)->getType();
       return true;
     }
 
diff --git a/clang/lib/Sema/SemaSPIRV.cpp b/clang/lib/Sema/SemaSPIRV.cpp
index 8c2af5053bde2..ceef9265f4f49 100644
--- a/clang/lib/Sema/SemaSPIRV.cpp
+++ b/clang/lib/Sema/SemaSPIRV.cpp
@@ -73,8 +73,9 @@ static bool CheckFloatOrHalfRepresentation(Sema *S, 
SourceLocation Loc,
   if (!BaseType->isHalfType() && !BaseType->isFloat16Type() &&
       !BaseType->isFloat32Type())
     return S->Diag(Loc, diag::err_builtin_invalid_arg_type)
-           << ArgOrdinal << /* scalar or vector of */ 5 << /* no int */ 0
-           << /* half or float */ 2 << PassedType;
+           << ArgOrdinal << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+           << diag::BuiltinArgIntegerKind::None
+           << diag::BuiltinArgFloatingKind::Float16Or32 << PassedType;
   return false;
 }
 
@@ -84,8 +85,9 @@ static bool CheckFloatOrHalfScalarRepresentation(Sema *S, 
SourceLocation Loc,
   if (!PassedType->isHalfType() && !PassedType->isFloat16Type() &&
       !PassedType->isFloat32Type())
     return S->Diag(Loc, diag::err_builtin_invalid_arg_type)
-           << ArgOrdinal << /* scalar */ 1 << /* no int */ 0
-           << /* half or float */ 2 << PassedType;
+           << ArgOrdinal << diag::BuiltinArgContainerKind::Scalar
+           << diag::BuiltinArgIntegerKind::None
+           << diag::BuiltinArgFloatingKind::Float16Or32 << PassedType;
   return false;
 }
 
@@ -324,8 +326,9 @@ bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(const 
TargetInfo &TI,
     QualType ArgTyA = A.get()->getType();
     if (!ArgTyA->hasFloatingRepresentation()) {
       SemaRef.Diag(A.get()->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-          << /* ordinal */ 1 << /* scalar or vector */ 5 << /* no int */ 0
-          << /* fp */ 1 << ArgTyA;
+          << 1 << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+          << diag::BuiltinArgIntegerKind::None
+          << diag::BuiltinArgFloatingKind::FloatingPoint << ArgTyA;
       return true;
     }
 
@@ -345,8 +348,9 @@ bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(const 
TargetInfo &TI,
     QualType ArgTyA = A.get()->getType();
     if (!ArgTyA->hasFloatingRepresentation()) {
       SemaRef.Diag(A.get()->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-          << /* ordinal */ 1 << /* scalar or vector */ 5 << /* no int */ 0
-          << /* fp */ 1 << ArgTyA;
+          << 1 << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+          << diag::BuiltinArgIntegerKind::None
+          << diag::BuiltinArgFloatingKind::FloatingPoint << ArgTyA;
       return true;
     }
 
@@ -371,8 +375,9 @@ bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(const 
TargetInfo &TI,
     QualType ArgTyA = A.get()->getType();
     if (!ArgTyA->hasFloatingRepresentation()) {
       SemaRef.Diag(A.get()->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-          << /* ordinal */ 1 << /* scalar or vector */ 5 << /* no int */ 0
-          << /* fp */ 1 << ArgTyA;
+          << 1 << diag::BuiltinArgContainerKind::ScalarOrVectorOf
+          << diag::BuiltinArgIntegerKind::None
+          << diag::BuiltinArgFloatingKind::FloatingPoint << ArgTyA;
       return true;
     }
 
@@ -393,8 +398,9 @@ bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(const 
TargetInfo &TI,
     QualType ArgTyA = A.get()->getType();
     if (!ArgTyA->isIntegerType() && !ArgTyA->isFloatingType()) {
       SemaRef.Diag(A.get()->getBeginLoc(), diag::err_builtin_invalid_arg_type)
-          << /* ordinal */ 1 << /* scalar */ 1 << /* no int */ 0
-          << /* no fp */ 0 << ArgTyA;
+          << 1 << diag::BuiltinArgContainerKind::Scalar
+          << diag::BuiltinArgIntegerKind::None
+          << diag::BuiltinArgFloatingKind::None << ArgTyA;
       return true;
     }
 
diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveBitOr-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/WaveActiveBitOr-errors.hlsl
index 5df1c7288045f..a9f710c1fde26 100644
--- a/clang/test/SemaHLSL/BuiltIns/WaveActiveBitOr-errors.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/WaveActiveBitOr-errors.hlsl
@@ -21,3 +21,13 @@ bool test_expr_bool_type_check(bool p0) {
   return __builtin_hlsl_wave_active_bit_or(p0);
   // expected-error@-1 {{invalid operand of type 'bool'}}
 }
+
+double test_expr_double_type_check(double p0) {
+  return __builtin_hlsl_wave_active_bit_or(p0);
+  // expected-error@-1 {{1st argument must be a scalar or vector of integer 
types (was 'double')}}
+}
+
+float2 test_expr_float_vector_type_check(float2 p0) {
+  return __builtin_hlsl_wave_active_bit_or(p0);
+  // expected-error@-1 {{1st argument must be a scalar or vector of integer 
types (was 'float2' (aka 'vector<float, 2>'))}}
+}
diff --git a/clang/test/TableGen/select-enum.td 
b/clang/test/TableGen/select-enum.td
index 8a92acec62cfb..c1e8eb7ee7d05 100644
--- a/clang/test/TableGen/select-enum.td
+++ b/clang/test/TableGen/select-enum.td
@@ -24,3 +24,13 @@ def Missing3 : 
Error<"%enum_select<DupeEnumName3>{%Val1{V1}|%Val2{V2}|V3}0">;
 // CHECK-NEXT: DIAG_ENUM_ITEM(0, Val1)
 // CHECK-NEXT: DIAG_ENUM_ITEM(1, Val2)
 // CHECK-NEXT: DIAG_ENUM_END()
+
+// An option with empty text can still be named, which lets callers spell out
+// the 'nothing selected' case instead of passing a bare 0. Note that the
+// enumerations are emitted in order of the record names, so this has to sort
+// after the ones checked above.
+def NamedEmpty : Error<"%enum_select<EmptyOptEnumName>{%None{}|%Val2{V2}}0">;
+// CHECK: DIAG_ENUM(EmptyOptEnumName)
+// CHECK-NEXT: DIAG_ENUM_ITEM(0, None)
+// CHECK-NEXT: DIAG_ENUM_ITEM(1, Val2)
+// CHECK-NEXT: DIAG_ENUM_END()

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to