浏览代码

[BitField] Fix crash on enum bit field. (#5260)

* [BitField] Fix crash on enum bit field.

Support bit field on enum type.
Fixes 5257 https://github.com/microsoft/DirectXShaderCompiler/issues/5257
Xiang Li 2 年之前
父节点
当前提交
451cd8be3c
共有 2 个文件被更改,包括 86 次插入1 次删除
  1. 7 1
      tools/clang/lib/CodeGen/CGHLSLMS.cpp
  2. 79 0
      tools/clang/test/HLSLFileCheck/d3dreflect/bitfield-enum.hlsl

+ 7 - 1
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -1009,7 +1009,13 @@ unsigned CGMSHLSLRuntime::ConstructStructAnnotation(DxilStructAnnotation *annota
         DxilFieldAnnotation bitfieldAnnotation;
         DxilFieldAnnotation bitfieldAnnotation;
 
 
         bitfieldAnnotation.SetBitFieldWidth(Field->getBitWidthValue(Context));
         bitfieldAnnotation.SetBitFieldWidth(Field->getBitWidthValue(Context));
-        const BuiltinType *BTy = Field->getType()->getAs<BuiltinType>();
+        QualType FieldTy = Field->getType().getCanonicalType();
+        const BuiltinType *BTy = FieldTy->getAs<BuiltinType>();
+        if (!BTy) {
+          // Should be enum type.
+          EnumDecl *Decl = FieldTy->getAs<EnumType>()->getDecl();
+          BTy = Decl->getPromotionType()->getAs<BuiltinType>();
+        }
         CompType::Kind kind =
         CompType::Kind kind =
             BuiltinTyToCompTy(BTy, /*bSNorm*/ false, /*bUNorm*/ false);
             BuiltinTyToCompTy(BTy, /*bSNorm*/ false, /*bUNorm*/ false);
         bitfieldAnnotation.SetCompType(kind);
         bitfieldAnnotation.SetCompType(kind);

+ 79 - 0
tools/clang/test/HLSLFileCheck/d3dreflect/bitfield-enum.hlsl

@@ -0,0 +1,79 @@
+// RUN: %dxc -T lib_6_6 -HV 2021 -E main %s | %D3DReflect %s | FileCheck %s
+
+// Make sure bit field on enum works.
+
+// CHECK:          ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:            D3D12_SHADER_VARIABLE_DESC: Name: ss
+// CHECK-NEXT:              Size: 4
+// CHECK-NEXT:              StartOffset: 0
+// CHECK-NEXT:              uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:              DefaultValue: <nullptr>
+// CHECK-NEXT:            ID3D12ShaderReflectionType:
+// CHECK-NEXT:              D3D12_SHADER_TYPE_DESC: Name: SomeStruct
+// CHECK-NEXT:                Class: D3D_SVC_STRUCT
+// CHECK-NEXT:                Type: D3D_SVT_VOID
+// CHECK-NEXT:                Elements: 0
+// CHECK-NEXT:                Rows: 1
+// CHECK-NEXT:                Columns: 1
+// CHECK-NEXT:                Members: 1
+// CHECK-NEXT:                Offset: 0
+// CHECK-NEXT:              {
+// CHECK-NEXT:                ID3D12ShaderReflectionType:
+// CHECK-NEXT:                  D3D12_SHADER_TYPE_DESC: Name: dword
+// CHECK-NEXT:                    Class: D3D_SVC_SCALAR
+// CHECK-NEXT:                    Type: D3D_SVT_UINT
+// CHECK-NEXT:                    Elements: 0
+// CHECK-NEXT:                    Rows: 1
+// CHECK-NEXT:                    Columns: 1
+// CHECK-NEXT:                    Members: 3
+// CHECK-NEXT:                    Offset: 0
+// CHECK-NEXT:                  {
+// CHECK-NEXT:                    ID3D12ShaderReflectionType:
+// CHECK-NEXT:                      D3D12_SHADER_TYPE_DESC: Name: dword
+// CHECK-NEXT:                        Class: D3D_SVC_BIT_FIELD
+// CHECK-NEXT:                        Type: D3D_SVT_UINT
+// CHECK-NEXT:                        Elements: 0
+// CHECK-NEXT:                        Rows: 1
+// CHECK-NEXT:                        Columns: 16
+// CHECK-NEXT:                        Members: 0
+// CHECK-NEXT:                        Offset: 0
+// CHECK-NEXT:                    ID3D12ShaderReflectionType:
+// CHECK-NEXT:                      D3D12_SHADER_TYPE_DESC: Name: dword
+// CHECK-NEXT:                        Class: D3D_SVC_BIT_FIELD
+// CHECK-NEXT:                        Type: D3D_SVT_UINT
+// CHECK-NEXT:                        Elements: 0
+// CHECK-NEXT:                        Rows: 1
+// CHECK-NEXT:                        Columns: 3
+// CHECK-NEXT:                        Members: 0
+// CHECK-NEXT:                        Offset: 16
+// CHECK-NEXT:                    ID3D12ShaderReflectionType:
+// CHECK-NEXT:                      D3D12_SHADER_TYPE_DESC: Name: dword
+// CHECK-NEXT:                        Class: D3D_SVC_BIT_FIELD
+// CHECK-NEXT:                        Type: D3D_SVT_UINT
+// CHECK-NEXT:                        Elements: 0
+// CHECK-NEXT:                        Rows: 1
+// CHECK-NEXT:                        Columns: 2
+// CHECK-NEXT:                        Members: 0
+// CHECK-NEXT:                        Offset: 19
+// CHECK-NEXT:                  }
+// CHECK-NEXT:              }
+// CHECK-NEXT:            CBuffer: $Globals
+enum SomeEnum { Val1 };
+
+using u32 = uint32_t;
+using SE = SomeEnum;
+typedef SomeEnum SE2;
+
+struct SomeStruct
+{
+    u32 m1 : 16;
+    SE m3 : 3;
+    SE2 m4 : 2;
+};
+
+SomeStruct ss;
+
+export int SomeFunc()
+{
+    return (int)ss.m3;
+}