|
@@ -60,6 +60,7 @@ enum ArBasicKind {
|
|
|
AR_BASIC_MIN12INT,
|
|
|
AR_BASIC_MIN16INT,
|
|
|
AR_BASIC_MIN16UINT,
|
|
|
+ AR_BASIC_ENUM,
|
|
|
|
|
|
AR_BASIC_COUNT,
|
|
|
|
|
@@ -77,6 +78,7 @@ enum ArBasicKind {
|
|
|
//
|
|
|
|
|
|
AR_BASIC_POINTER,
|
|
|
+ AR_BASIC_ENUM_CLASS,
|
|
|
|
|
|
AR_OBJECT_NULL,
|
|
|
AR_OBJECT_STRING,
|
|
@@ -247,6 +249,7 @@ enum ArBasicKind {
|
|
|
#define BPROP_PRIMITIVE 0x00100000 // Whether the type is a primitive scalar type.
|
|
|
#define BPROP_MIN_PRECISION 0x00200000 // Whether the type is qualified with a minimum precision.
|
|
|
#define BPROP_ROVBUFFER 0x00400000 // Whether the type is a ROV object.
|
|
|
+#define BPROP_ENUM 0x00800000 // Whether the type is a enum
|
|
|
|
|
|
#define GET_BPROP_PRIM_KIND(_Props) \
|
|
|
((_Props) & (BPROP_BOOLEAN | BPROP_INTEGER | BPROP_FLOATING))
|
|
@@ -289,6 +292,9 @@ enum ArBasicKind {
|
|
|
#define IS_BPROP_UNSIGNABLE(_Props) \
|
|
|
(IS_BPROP_AINT(_Props) && GET_BPROP_BITS(_Props) != BPROP_BITS12)
|
|
|
|
|
|
+#define IS_BPROP_ENUM(_Props) \
|
|
|
+ (((_Props) & BPROP_ENUM) != 0)
|
|
|
+
|
|
|
const UINT g_uBasicKindProps[] =
|
|
|
{
|
|
|
BPROP_PRIMITIVE | BPROP_BOOLEAN | BPROP_INTEGER | BPROP_NUMERIC | BPROP_BITS0, // AR_BASIC_BOOL
|
|
@@ -316,6 +322,7 @@ const UINT g_uBasicKindProps[] =
|
|
|
BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_BITS16 | BPROP_MIN_PRECISION, // AR_BASIC_MIN16INT
|
|
|
BPROP_PRIMITIVE | BPROP_NUMERIC | BPROP_INTEGER | BPROP_UNSIGNED | BPROP_BITS16 | BPROP_MIN_PRECISION, // AR_BASIC_MIN16UINT
|
|
|
|
|
|
+ BPROP_ENUM | BPROP_NUMERIC | BPROP_INTEGER, // AR_BASIC_ENUM
|
|
|
BPROP_OTHER, // AR_BASIC_COUNT
|
|
|
|
|
|
//
|
|
@@ -332,10 +339,12 @@ const UINT g_uBasicKindProps[] =
|
|
|
//
|
|
|
|
|
|
BPROP_POINTER, // AR_BASIC_POINTER
|
|
|
+ BPROP_ENUM, // AR_BASIC_ENUM_CLASS
|
|
|
|
|
|
BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_NULL
|
|
|
BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_STRING
|
|
|
|
|
|
+
|
|
|
// BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE
|
|
|
BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE1D
|
|
|
BPROP_OBJECT | BPROP_TEXTURE, // AR_OBJECT_TEXTURE1D_ARRAY
|
|
@@ -461,6 +470,9 @@ C_ASSERT(ARRAYSIZE(g_uBasicKindProps) == AR_BASIC_MAXIMUM_COUNT);
|
|
|
#define IS_BASIC_UNSIGNABLE(_Kind) \
|
|
|
IS_BPROP_UNSIGNABLE(GetBasicKindProps(_Kind))
|
|
|
|
|
|
+#define IS_BASIC_ENUM(_Kind) \
|
|
|
+ IS_BPROP_ENUM(GetBasicKindProps(_Kind))
|
|
|
+
|
|
|
#define BITWISE_ENUM_OPS(_Type) \
|
|
|
inline _Type operator|(_Type F1, _Type F2) \
|
|
|
{ \
|
|
@@ -1290,12 +1302,15 @@ const char* g_ArBasicTypeNames[] =
|
|
|
"int", "uint", "long", "ulong",
|
|
|
"min10float", "min16float",
|
|
|
"min12int", "min16int", "min16uint",
|
|
|
+ "enum",
|
|
|
|
|
|
"<count>",
|
|
|
"<none>",
|
|
|
"<unknown>",
|
|
|
"<nocast>",
|
|
|
"<pointer>",
|
|
|
+ "enum class",
|
|
|
+
|
|
|
"null",
|
|
|
"string",
|
|
|
// "texture",
|
|
@@ -3120,6 +3135,7 @@ public:
|
|
|
}
|
|
|
|
|
|
if (type->isBuiltinType()) return AR_TOBJ_BASIC;
|
|
|
+ if (type->isEnumeralType()) return AR_TOBJ_BASIC;
|
|
|
|
|
|
return AR_TOBJ_INVALID;
|
|
|
}
|
|
@@ -3210,7 +3226,11 @@ public:
|
|
|
case BuiltinType::LitInt: return AR_BASIC_LITERAL_INT;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+ if (const EnumType *ET = dyn_cast<EnumType>(type)) {
|
|
|
+ if (ET->getDecl()->isScopedUsingClassTag())
|
|
|
+ return AR_BASIC_ENUM_CLASS;
|
|
|
+ return AR_BASIC_ENUM;
|
|
|
+ }
|
|
|
return AR_BASIC_UNKNOWN;
|
|
|
}
|
|
|
|
|
@@ -3357,7 +3377,7 @@ public:
|
|
|
case AR_OBJECT_APPEND_STRUCTURED_BUFFER:
|
|
|
case AR_OBJECT_CONSUME_STRUCTURED_BUFFER:
|
|
|
case AR_OBJECT_WAVE:
|
|
|
- {
|
|
|
+{
|
|
|
const ArBasicKind* match = std::find(g_ArBasicKindsAsTypes, &g_ArBasicKindsAsTypes[_countof(g_ArBasicKindsAsTypes)], kind);
|
|
|
DXASSERT(match != &g_ArBasicKindsAsTypes[_countof(g_ArBasicKindsAsTypes)], "otherwise can't find constant in basic kinds");
|
|
|
size_t index = match - g_ArBasicKindsAsTypes;
|
|
@@ -5218,6 +5238,10 @@ static bool UnaryOperatorKindDisallowsBool(UnaryOperatorKind Opc)
|
|
|
Opc == UnaryOperatorKind::UO_PostDec || Opc == UnaryOperatorKind::UO_PostInc;
|
|
|
}
|
|
|
|
|
|
+static bool IsIncrementOp(UnaryOperatorKind Opc) {
|
|
|
+ return Opc == UnaryOperatorKind::UO_PreInc || Opc == UnaryOperatorKind::UO_PostInc;
|
|
|
+}
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// Checks whether the specified AR_TOBJ* value is a primitive or aggregate of primitive elements
|
|
|
/// (as opposed to a built-in object like a sampler or texture, or a void type).
|
|
@@ -7326,7 +7350,13 @@ bool HLSLExternalSource::CanConvert(
|
|
|
{
|
|
|
Remarks |= TYPE_CONVERSION_ELT_TRUNCATION;
|
|
|
}
|
|
|
-
|
|
|
+ // enum -> enum not allowed
|
|
|
+ if ((SourceInfo.EltKind == AR_BASIC_ENUM &&
|
|
|
+ TargetInfo.EltKind == AR_BASIC_ENUM) ||
|
|
|
+ SourceInfo.EltKind == AR_BASIC_ENUM_CLASS ||
|
|
|
+ TargetInfo.EltKind == AR_BASIC_ENUM_CLASS) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
if (SourceInfo.EltKind != TargetInfo.EltKind)
|
|
|
{
|
|
|
if (TargetInfo.EltKind == AR_BASIC_UNKNOWN ||
|
|
@@ -7338,6 +7368,16 @@ bool HLSLExternalSource::CanConvert(
|
|
|
{
|
|
|
ComponentConversion = ICK_Boolean_Conversion;
|
|
|
}
|
|
|
+ else if (IS_BASIC_ENUM(TargetInfo.EltKind))
|
|
|
+ {
|
|
|
+ // conversion to enum type not allowed
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ else if (IS_BASIC_ENUM(SourceInfo.EltKind))
|
|
|
+ {
|
|
|
+ // enum -> int/float
|
|
|
+ ComponentConversion = ICK_Integral_Conversion;
|
|
|
+ }
|
|
|
else
|
|
|
{
|
|
|
bool targetIsInt = IS_BASIC_AINT(TargetInfo.EltKind);
|
|
@@ -7824,6 +7864,12 @@ QualType HLSLExternalSource::CheckUnaryOpForHLSL(
|
|
|
ArBasicKind elementKind = GetTypeElementKind(expr->getType());
|
|
|
|
|
|
if (UnaryOperatorKindRequiresModifiableValue(Opc)) {
|
|
|
+ if (elementKind == AR_BASIC_ENUM) {
|
|
|
+ bool isInc = IsIncrementOp(Opc);
|
|
|
+ m_sema->Diag(OpLoc, diag::err_increment_decrement_enum) << isInc << expr->getType();
|
|
|
+ return QualType();
|
|
|
+ }
|
|
|
+
|
|
|
extern bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S);
|
|
|
if (CheckForModifiableLvalue(expr, OpLoc, *m_sema))
|
|
|
return QualType();
|