Browse Source

Merge remote-tracking branch 'ms/master' into user/texr/integrate-master

# Conflicts:
#	tools/clang/tools/dxcompiler/dxcompilerobj.cpp
#	tools/clang/unittests/HLSL/ValidationTest.cpp
#	tools/clang/unittests/HLSL/VerifierTest.cpp
Tex Riddell 7 years ago
parent
commit
2330c74b1a
52 changed files with 1721 additions and 1820 deletions
  1. 1 0
      .travis.yml
  2. 8 3
      docs/SPIR-V.rst
  3. 1 0
      include/dxc/Support/HLSLOptions.h
  4. 3 1
      include/dxc/Support/HLSLOptions.td
  5. 1 1
      include/dxc/Support/WinAdapter.h
  6. 9 15
      lib/DxcSupport/FileIOHelper.cpp
  7. 2 0
      lib/DxcSupport/HLSLOptions.cpp
  8. 2 1
      tools/clang/include/clang/SPIRV/EmitSPIRVOptions.h
  9. 7 552
      tools/clang/include/clang/SPIRV/InstBuilder.h
  10. 6 0
      tools/clang/include/clang/SPIRV/ModuleBuilder.h
  11. 6 0
      tools/clang/include/clang/SPIRV/Structure.h
  12. 8 1
      tools/clang/lib/Frontend/CompilerInvocation.cpp
  13. 18 1
      tools/clang/lib/SPIRV/DeclResultIdMapper.cpp
  14. 7 3
      tools/clang/lib/SPIRV/DeclResultIdMapper.h
  15. 266 342
      tools/clang/lib/SPIRV/InstBuilderAuto.cpp
  16. 30 1
      tools/clang/lib/SPIRV/InstBuilderManual.cpp
  17. 4 45
      tools/clang/lib/SPIRV/ModuleBuilder.cpp
  18. 10 1
      tools/clang/lib/SPIRV/SPIRVEmitter.cpp
  19. 38 1
      tools/clang/lib/SPIRV/Structure.cpp
  20. 5 0
      tools/clang/lib/Sema/SemaHLSL.cpp
  21. 11 0
      tools/clang/test/CodeGenHLSL/quick-test/min10float.hlsl
  22. 21 0
      tools/clang/test/CodeGenHLSL/quick-test/min10float_to_float.hlsl
  23. 11 0
      tools/clang/test/CodeGenHLSL/quick-test/min12int.hlsl
  24. 21 0
      tools/clang/test/CodeGenHLSL/quick-test/min12int_to_int.hlsl
  25. 7 0
      tools/clang/test/CodeGenSPIRV/spirv.debug.opsource.hlsl
  26. 29 0
      tools/clang/test/CodeGenSPIRV/vk.cloption.invert-w.ds.hlsl
  27. 12 0
      tools/clang/test/CodeGenSPIRV/vk.cloption.invert-w.ps.hlsl
  28. 2 0
      tools/clang/tools/dxcompiler/CMakeLists.txt
  29. 40 11
      tools/clang/tools/dxcompiler/dxcompilerobj.cpp
  30. 182 177
      tools/clang/tools/libclang/dxcisenseimpl.cpp
  31. 12 12
      tools/clang/tools/libclang/dxcisenseimpl.h
  32. 20 8
      tools/clang/unittests/HLSL/AllocatorTest.cpp
  33. 18 6
      tools/clang/unittests/HLSL/CMakeLists.txt
  34. 3 168
      tools/clang/unittests/HLSL/CompilerTest.cpp
  35. 59 54
      tools/clang/unittests/HLSL/DXIsenseTest.cpp
  36. 372 0
      tools/clang/unittests/HLSL/DxcTestUtils.cpp
  37. 4 0
      tools/clang/unittests/HLSL/DxcTestUtils.h
  38. 10 10
      tools/clang/unittests/HLSL/DxilModuleTest.cpp
  39. 16 16
      tools/clang/unittests/HLSL/ExtensionTest.cpp
  40. 3 3
      tools/clang/unittests/HLSL/FunctionTest.cpp
  41. 2 1
      tools/clang/unittests/HLSL/HLSLTestOptions.cpp
  42. 49 18
      tools/clang/unittests/HLSL/HlslTestUtils.h
  43. 6 6
      tools/clang/unittests/HLSL/MSFileSysTest.cpp
  44. 27 15
      tools/clang/unittests/HLSL/Objects.cpp
  45. 0 27
      tools/clang/unittests/HLSL/OptimizerTest.cpp
  46. 5 1
      tools/clang/unittests/HLSL/RewriterTest.cpp
  47. 3 0
      tools/clang/unittests/HLSL/TestMain.cpp
  48. 84 211
      tools/clang/unittests/HLSL/ValidationTest.cpp
  49. 51 71
      tools/clang/unittests/HLSL/VerifierTest.cpp
  50. 155 0
      tools/clang/unittests/HLSL/WEXAdapter.h
  51. 7 0
      tools/clang/unittests/SPIRV/CodeGenSPIRVTest.cpp
  52. 47 37
      utils/hct/VerifierHelper.py

+ 1 - 0
.travis.yml

@@ -75,3 +75,4 @@ script:
   - ./bin/dxc -T ps_6_0 -Fo passthru-ps.spv ../tools/clang/test/CodeGenSPIRV/passthru-ps.hlsl2spv -spirv
   - cmp passthru-ps.spv ../tools/clang/test/CodeGenSPIRV/passthru-ps.spv
   - ./bin/clang-spirv-tests --spirv-test-root ../tools/clang/test/CodeGenSPIRV/
+  - ./bin/clang-hlsl-tests --HlslDataDir $PWD/../tools/clang/test/HLSL/

+ 8 - 3
docs/SPIR-V.rst

@@ -2716,9 +2716,14 @@ codegen for Vulkan:
 - ``-fvk-use-gl-layout``: Uses strict OpenGL ``std140``/``std430``
   layout rules for resources.
 - ``-fvk-use-dx-layout``: Uses DirectX layout rules for resources.
-- ``-fvk-invert-y``: Inverts SV_Position.y before writing to stage output.
-  Used to accommodate the difference between Vulkan's coordinate system and
-  DirectX's. Only allowed in VS/DS/GS.
+- ``-fvk-invert-y``: Negates (additively inverts) SV_Position.y before writing
+  to stage output. Used to accommodate the difference between Vulkan's
+  coordinate system and DirectX's. Only allowed in VS/DS/GS.
+- ``-fvk-use-dx-position-w``: Reciprocates (multiplicatively inverts)
+  SV_Position.w after reading from stage input. Used to accommodate the
+  difference between Vulkan DirectX: the w component of SV_Position in PS is
+  stored as 1/w in Vulkan. Only recognized in PS; applying to other stages
+  is no-op.
 - ``-fvk-stage-io-order={alpha|decl}``: Assigns the stage input/output variable
   location number according to alphabetical order or declaration order. See
   `HLSL semantic and Vulkan Location`_ for more details.

+ 1 - 0
include/dxc/Support/HLSLOptions.h

@@ -165,6 +165,7 @@ public:
 #ifdef ENABLE_SPIRV_CODEGEN
   bool GenSPIRV;                           // OPT_spirv
   bool VkInvertY;                          // OPT_fvk_invert_y
+  bool VkInvertW;                          // OPT_fvk_use_dx_position_w
   bool VkUseGlLayout;                      // OPT_fvk_use_gl_layout
   bool VkUseDxLayout;                      // OPT_fvk_use_dx_layout
   bool SpvEnableReflect;                   // OPT_fspv_reflect

+ 3 - 1
include/dxc/Support/HLSLOptions.td

@@ -253,7 +253,9 @@ def fvk_s_shift : MultiArg<["-"], "fvk-s-shift", 2>, MetaVarName<"<shift> <space
 def fvk_u_shift : MultiArg<["-"], "fvk-u-shift", 2>, MetaVarName<"<shift> <space>">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
   HelpText<"Specify Vulkan binding number shift for u-type register">;
 def fvk_invert_y: Flag<["-"], "fvk-invert-y">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
-  HelpText<"Invert SV_Position.y in VS/DS/GS to accommodate Vulkan's coordinate system">;
+  HelpText<"Negate SV_Position.y before writing to stage output in VS/DS/GS to accommodate Vulkan's coordinate system">;
+def fvk_use_dx_position_w: Flag<["-"], "fvk-use-dx-position-w">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
+  HelpText<"Reciprocate SV_Position.w after reading from stage input in PS to accommodate the difference between Vulkan and DirectX">;
 def fvk_use_gl_layout: Flag<["-"], "fvk-use-gl-layout">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
   HelpText<"Use strict OpenGL std140/std430 memory layout for Vulkan resources">;
 def fvk_use_dx_layout: Flag<["-"], "fvk-use-dx-layout">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,

+ 1 - 1
include/dxc/Support/WinAdapter.h

@@ -598,7 +598,7 @@ protected:
   }
 
 public:
-  virtual ~CComPtrBase() throw() {
+  ~CComPtrBase() throw() {
     if (p) {
       p->Release();
       p = nullptr;

+ 9 - 15
lib/DxcSupport/FileIOHelper.cpp

@@ -28,33 +28,29 @@
 
 struct HeapMalloc : public IMalloc {
 public:
-  ULONG STDMETHODCALLTYPE AddRef() {
-    return 1;
-  }
-  ULONG STDMETHODCALLTYPE Release() {
-    return 1;
-  }
+  ULONG STDMETHODCALLTYPE AddRef() override { return 1; }
+  ULONG STDMETHODCALLTYPE Release() override { return 1; }
   STDMETHODIMP QueryInterface(REFIID iid, void** ppvObject) override {
     return DoBasicQueryInterface<IMalloc>(this, iid, ppvObject);
   }
-  virtual void *STDMETHODCALLTYPE Alloc(
+  virtual void *STDMETHODCALLTYPE Alloc (
     /* [annotation][in] */
-    _In_  SIZE_T cb) {
+    _In_  SIZE_T cb) override {
     return HeapAlloc(GetProcessHeap(), 0, cb);
   }
 
-  virtual void *STDMETHODCALLTYPE Realloc(
+  virtual void *STDMETHODCALLTYPE Realloc (
     /* [annotation][in] */
     _In_opt_  void *pv,
     /* [annotation][in] */
-    _In_  SIZE_T cb)
+    _In_  SIZE_T cb) override
   {
     return HeapReAlloc(GetProcessHeap(), 0, pv, cb);
   }
 
-  virtual void STDMETHODCALLTYPE Free(
+  virtual void STDMETHODCALLTYPE Free (
     /* [annotation][in] */
-    _In_opt_  void *pv)
+    _In_opt_  void *pv) override
   {
     HeapFree(GetProcessHeap(), 0, pv);
   }
@@ -75,9 +71,7 @@ public:
   }
 
 
-  virtual void STDMETHODCALLTYPE HeapMinimize(void)
-  {
-  }
+  virtual void STDMETHODCALLTYPE HeapMinimize(void) {}
 };
 
 static HeapMalloc g_HeapMalloc;

+ 2 - 0
lib/DxcSupport/HLSLOptions.cpp

@@ -544,6 +544,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
 #ifdef ENABLE_SPIRV_CODEGEN
   const bool genSpirv = opts.GenSPIRV = Args.hasFlag(OPT_spirv, OPT_INVALID, false);
   opts.VkInvertY = Args.hasFlag(OPT_fvk_invert_y, OPT_INVALID, false);
+  opts.VkInvertW = Args.hasFlag(OPT_fvk_use_dx_position_w, OPT_INVALID, false);
   opts.VkUseGlLayout = Args.hasFlag(OPT_fvk_use_gl_layout, OPT_INVALID, false);
   opts.VkUseDxLayout = Args.hasFlag(OPT_fvk_use_dx_layout, OPT_INVALID, false);
   opts.SpvEnableReflect = Args.hasFlag(OPT_fspv_reflect, OPT_INVALID, false);
@@ -609,6 +610,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
 #else
   if (Args.hasFlag(OPT_spirv, OPT_INVALID, false) ||
       Args.hasFlag(OPT_fvk_invert_y, OPT_INVALID, false) ||
+      Args.hasFlag(OPT_fvk_use_dx_position_w, OPT_INVALID, false) ||
       Args.hasFlag(OPT_fvk_use_gl_layout, OPT_INVALID, false) ||
       Args.hasFlag(OPT_fvk_use_dx_layout, OPT_INVALID, false) ||
       Args.hasFlag(OPT_fspv_reflect, OPT_INVALID, false) ||

+ 2 - 1
tools/clang/include/clang/SPIRV/EmitSPIRVOptions.h

@@ -32,7 +32,8 @@ struct EmitSPIRVOptions {
   bool codeGenHighLevel;
   bool defaultRowMajor;
   bool disableValidation;
-  bool invertY;
+  bool invertY; // Additive inverse
+  bool invertW; // Multiplicative inverse
   bool useGlLayout;
   bool useDxLayout;
   bool enable16BitTypes;

+ 7 - 552
tools/clang/include/clang/SPIRV/InstBuilder.h

@@ -23,6 +23,7 @@
 #include "spirv/unified1/spirv.hpp11"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
 
 namespace clang {
 namespace spirv {
@@ -93,10 +94,10 @@ public:
   // Instruction building methods.
   InstBuilder &opNop();
   InstBuilder &opUndef(uint32_t result_type, uint32_t result_id);
-  InstBuilder &opSourceContinued(std::string continued_source);
+  InstBuilder &opSourceContinued(llvm::StringRef continued_source);
   InstBuilder &opSource(spv::SourceLanguage source_language, uint32_t version,
                         llvm::Optional<uint32_t> file,
-                        llvm::Optional<std::string> source);
+                        llvm::Optional<llvm::StringRef> source);
   InstBuilder &opSourceExtension(std::string extension);
   InstBuilder &opName(uint32_t target, std::string name);
   InstBuilder &opMemberName(uint32_t type, uint32_t member, std::string name);
@@ -307,179 +308,9 @@ public:
                                   uint32_t image);
   InstBuilder &opImageQuerySamples(uint32_t result_type, uint32_t result_id,
                                    uint32_t image);
-  InstBuilder &opConvertFToU(uint32_t result_type, uint32_t result_id,
-                             uint32_t float_value);
-  InstBuilder &opConvertFToS(uint32_t result_type, uint32_t result_id,
-                             uint32_t float_value);
-  InstBuilder &opConvertSToF(uint32_t result_type, uint32_t result_id,
-                             uint32_t signed_value);
-  InstBuilder &opConvertUToF(uint32_t result_type, uint32_t result_id,
-                             uint32_t unsigned_value);
-  InstBuilder &opUConvert(uint32_t result_type, uint32_t result_id,
-                          uint32_t unsigned_value);
-  InstBuilder &opSConvert(uint32_t result_type, uint32_t result_id,
-                          uint32_t signed_value);
-  InstBuilder &opFConvert(uint32_t result_type, uint32_t result_id,
-                          uint32_t float_value);
-  InstBuilder &opQuantizeToF16(uint32_t result_type, uint32_t result_id,
-                               uint32_t value);
-  InstBuilder &opConvertPtrToU(uint32_t result_type, uint32_t result_id,
-                               uint32_t pointer);
-  InstBuilder &opSatConvertSToU(uint32_t result_type, uint32_t result_id,
-                                uint32_t signed_value);
-  InstBuilder &opSatConvertUToS(uint32_t result_type, uint32_t result_id,
-                                uint32_t unsigned_value);
-  InstBuilder &opConvertUToPtr(uint32_t result_type, uint32_t result_id,
-                               uint32_t integer_value);
-  InstBuilder &opPtrCastToGeneric(uint32_t result_type, uint32_t result_id,
-                                  uint32_t pointer);
-  InstBuilder &opGenericCastToPtr(uint32_t result_type, uint32_t result_id,
-                                  uint32_t pointer);
-  InstBuilder &opGenericCastToPtrExplicit(uint32_t result_type,
-                                          uint32_t result_id, uint32_t pointer,
-                                          spv::StorageClass storage);
-  InstBuilder &opBitcast(uint32_t result_type, uint32_t result_id,
-                         uint32_t operand);
-  InstBuilder &opSNegate(uint32_t result_type, uint32_t result_id,
-                         uint32_t operand);
-  InstBuilder &opFNegate(uint32_t result_type, uint32_t result_id,
-                         uint32_t operand);
-  InstBuilder &opIAdd(uint32_t result_type, uint32_t result_id,
-                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFAdd(uint32_t result_type, uint32_t result_id,
-                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opISub(uint32_t result_type, uint32_t result_id,
-                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFSub(uint32_t result_type, uint32_t result_id,
-                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opIMul(uint32_t result_type, uint32_t result_id,
-                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFMul(uint32_t result_type, uint32_t result_id,
-                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opUDiv(uint32_t result_type, uint32_t result_id,
-                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opSDiv(uint32_t result_type, uint32_t result_id,
-                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFDiv(uint32_t result_type, uint32_t result_id,
-                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opUMod(uint32_t result_type, uint32_t result_id,
-                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opSRem(uint32_t result_type, uint32_t result_id,
-                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opSMod(uint32_t result_type, uint32_t result_id,
-                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFRem(uint32_t result_type, uint32_t result_id,
-                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFMod(uint32_t result_type, uint32_t result_id,
-                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opVectorTimesScalar(uint32_t result_type, uint32_t result_id,
-                                   uint32_t vector, uint32_t scalar);
-  InstBuilder &opMatrixTimesScalar(uint32_t result_type, uint32_t result_id,
-                                   uint32_t matrix, uint32_t scalar);
-  InstBuilder &opVectorTimesMatrix(uint32_t result_type, uint32_t result_id,
-                                   uint32_t vector, uint32_t matrix);
-  InstBuilder &opMatrixTimesVector(uint32_t result_type, uint32_t result_id,
-                                   uint32_t matrix, uint32_t vector);
-  InstBuilder &opMatrixTimesMatrix(uint32_t result_type, uint32_t result_id,
-                                   uint32_t left_matrix, uint32_t right_matrix);
-  InstBuilder &opOuterProduct(uint32_t result_type, uint32_t result_id,
-                              uint32_t vector_1, uint32_t vector_2);
-  InstBuilder &opDot(uint32_t result_type, uint32_t result_id,
-                     uint32_t vector_1, uint32_t vector_2);
-  InstBuilder &opIAddCarry(uint32_t result_type, uint32_t result_id,
-                           uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opISubBorrow(uint32_t result_type, uint32_t result_id,
-                            uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opUMulExtended(uint32_t result_type, uint32_t result_id,
-                              uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opSMulExtended(uint32_t result_type, uint32_t result_id,
-                              uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opAny(uint32_t result_type, uint32_t result_id, uint32_t vector);
-  InstBuilder &opAll(uint32_t result_type, uint32_t result_id, uint32_t vector);
-  InstBuilder &opIsNan(uint32_t result_type, uint32_t result_id, uint32_t x);
-  InstBuilder &opIsInf(uint32_t result_type, uint32_t result_id, uint32_t x);
-  InstBuilder &opIsFinite(uint32_t result_type, uint32_t result_id, uint32_t x);
-  InstBuilder &opIsNormal(uint32_t result_type, uint32_t result_id, uint32_t x);
-  InstBuilder &opSignBitSet(uint32_t result_type, uint32_t result_id,
-                            uint32_t x);
-  InstBuilder &opLessOrGreater(uint32_t result_type, uint32_t result_id,
-                               uint32_t x, uint32_t y);
-  InstBuilder &opOrdered(uint32_t result_type, uint32_t result_id, uint32_t x,
-                         uint32_t y);
-  InstBuilder &opUnordered(uint32_t result_type, uint32_t result_id, uint32_t x,
-                           uint32_t y);
-  InstBuilder &opLogicalEqual(uint32_t result_type, uint32_t result_id,
-                              uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opLogicalNotEqual(uint32_t result_type, uint32_t result_id,
-                                 uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opLogicalOr(uint32_t result_type, uint32_t result_id,
-                           uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opLogicalAnd(uint32_t result_type, uint32_t result_id,
-                            uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opLogicalNot(uint32_t result_type, uint32_t result_id,
-                            uint32_t operand);
   InstBuilder &opSelect(uint32_t result_type, uint32_t result_id,
                         uint32_t condition, uint32_t object_1,
                         uint32_t object_2);
-  InstBuilder &opIEqual(uint32_t result_type, uint32_t result_id,
-                        uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opINotEqual(uint32_t result_type, uint32_t result_id,
-                           uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opUGreaterThan(uint32_t result_type, uint32_t result_id,
-                              uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opSGreaterThan(uint32_t result_type, uint32_t result_id,
-                              uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opUGreaterThanEqual(uint32_t result_type, uint32_t result_id,
-                                   uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opSGreaterThanEqual(uint32_t result_type, uint32_t result_id,
-                                   uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opULessThan(uint32_t result_type, uint32_t result_id,
-                           uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opSLessThan(uint32_t result_type, uint32_t result_id,
-                           uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opULessThanEqual(uint32_t result_type, uint32_t result_id,
-                                uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opSLessThanEqual(uint32_t result_type, uint32_t result_id,
-                                uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFOrdEqual(uint32_t result_type, uint32_t result_id,
-                           uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFUnordEqual(uint32_t result_type, uint32_t result_id,
-                             uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFOrdNotEqual(uint32_t result_type, uint32_t result_id,
-                              uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFUnordNotEqual(uint32_t result_type, uint32_t result_id,
-                                uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFOrdLessThan(uint32_t result_type, uint32_t result_id,
-                              uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFUnordLessThan(uint32_t result_type, uint32_t result_id,
-                                uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFOrdGreaterThan(uint32_t result_type, uint32_t result_id,
-                                 uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFUnordGreaterThan(uint32_t result_type, uint32_t result_id,
-                                   uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFOrdLessThanEqual(uint32_t result_type, uint32_t result_id,
-                                   uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFUnordLessThanEqual(uint32_t result_type, uint32_t result_id,
-                                     uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFOrdGreaterThanEqual(uint32_t result_type, uint32_t result_id,
-                                      uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opFUnordGreaterThanEqual(uint32_t result_type,
-                                        uint32_t result_id, uint32_t operand_1,
-                                        uint32_t operand_2);
-  InstBuilder &opShiftRightLogical(uint32_t result_type, uint32_t result_id,
-                                   uint32_t base, uint32_t shift);
-  InstBuilder &opShiftRightArithmetic(uint32_t result_type, uint32_t result_id,
-                                      uint32_t base, uint32_t shift);
-  InstBuilder &opShiftLeftLogical(uint32_t result_type, uint32_t result_id,
-                                  uint32_t base, uint32_t shift);
-  InstBuilder &opBitwiseOr(uint32_t result_type, uint32_t result_id,
-                           uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opBitwiseXor(uint32_t result_type, uint32_t result_id,
-                            uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opBitwiseAnd(uint32_t result_type, uint32_t result_id,
-                            uint32_t operand_1, uint32_t operand_2);
-  InstBuilder &opNot(uint32_t result_type, uint32_t result_id,
-                     uint32_t operand);
   InstBuilder &opBitFieldInsert(uint32_t result_type, uint32_t result_id,
                                 uint32_t base, uint32_t insert, uint32_t offset,
                                 uint32_t count);
@@ -536,33 +367,6 @@ public:
   InstBuilder &opAtomicIDecrement(uint32_t result_type, uint32_t result_id,
                                   uint32_t pointer, uint32_t scope,
                                   uint32_t semantics);
-  InstBuilder &opAtomicIAdd(uint32_t result_type, uint32_t result_id,
-                            uint32_t pointer, uint32_t scope,
-                            uint32_t semantics, uint32_t value);
-  InstBuilder &opAtomicISub(uint32_t result_type, uint32_t result_id,
-                            uint32_t pointer, uint32_t scope,
-                            uint32_t semantics, uint32_t value);
-  InstBuilder &opAtomicSMin(uint32_t result_type, uint32_t result_id,
-                            uint32_t pointer, uint32_t scope,
-                            uint32_t semantics, uint32_t value);
-  InstBuilder &opAtomicUMin(uint32_t result_type, uint32_t result_id,
-                            uint32_t pointer, uint32_t scope,
-                            uint32_t semantics, uint32_t value);
-  InstBuilder &opAtomicSMax(uint32_t result_type, uint32_t result_id,
-                            uint32_t pointer, uint32_t scope,
-                            uint32_t semantics, uint32_t value);
-  InstBuilder &opAtomicUMax(uint32_t result_type, uint32_t result_id,
-                            uint32_t pointer, uint32_t scope,
-                            uint32_t semantics, uint32_t value);
-  InstBuilder &opAtomicAnd(uint32_t result_type, uint32_t result_id,
-                           uint32_t pointer, uint32_t scope, uint32_t semantics,
-                           uint32_t value);
-  InstBuilder &opAtomicOr(uint32_t result_type, uint32_t result_id,
-                          uint32_t pointer, uint32_t scope, uint32_t semantics,
-                          uint32_t value);
-  InstBuilder &opAtomicXor(uint32_t result_type, uint32_t result_id,
-                           uint32_t pointer, uint32_t scope, uint32_t semantics,
-                           uint32_t value);
   InstBuilder &
   opPhi(uint32_t result_type, uint32_t result_id,
         llvm::ArrayRef<std::pair<uint32_t, uint32_t>> variable_parent_);
@@ -581,145 +385,6 @@ public:
   InstBuilder &opReturn();
   InstBuilder &opReturnValue(uint32_t value);
   InstBuilder &opUnreachable();
-  InstBuilder &opLifetimeStart(uint32_t pointer, uint32_t size);
-  InstBuilder &opLifetimeStop(uint32_t pointer, uint32_t size);
-  InstBuilder &opGroupAsyncCopy(uint32_t result_type, uint32_t result_id,
-                                uint32_t execution, uint32_t destination,
-                                uint32_t source, uint32_t num_elements,
-                                uint32_t stride, uint32_t event);
-  InstBuilder &opGroupWaitEvents(uint32_t execution, uint32_t num_events,
-                                 uint32_t events_list);
-  InstBuilder &opGroupAll(uint32_t result_type, uint32_t result_id,
-                          uint32_t execution, uint32_t predicate);
-  InstBuilder &opGroupAny(uint32_t result_type, uint32_t result_id,
-                          uint32_t execution, uint32_t predicate);
-  InstBuilder &opGroupBroadcast(uint32_t result_type, uint32_t result_id,
-                                uint32_t execution, uint32_t value,
-                                uint32_t local_id);
-  InstBuilder &opGroupIAdd(uint32_t result_type, uint32_t result_id,
-                           uint32_t execution, spv::GroupOperation operation,
-                           uint32_t x);
-  InstBuilder &opGroupFAdd(uint32_t result_type, uint32_t result_id,
-                           uint32_t execution, spv::GroupOperation operation,
-                           uint32_t x);
-  InstBuilder &opGroupFMin(uint32_t result_type, uint32_t result_id,
-                           uint32_t execution, spv::GroupOperation operation,
-                           uint32_t x);
-  InstBuilder &opGroupUMin(uint32_t result_type, uint32_t result_id,
-                           uint32_t execution, spv::GroupOperation operation,
-                           uint32_t x);
-  InstBuilder &opGroupSMin(uint32_t result_type, uint32_t result_id,
-                           uint32_t execution, spv::GroupOperation operation,
-                           uint32_t x);
-  InstBuilder &opGroupFMax(uint32_t result_type, uint32_t result_id,
-                           uint32_t execution, spv::GroupOperation operation,
-                           uint32_t x);
-  InstBuilder &opGroupUMax(uint32_t result_type, uint32_t result_id,
-                           uint32_t execution, spv::GroupOperation operation,
-                           uint32_t x);
-  InstBuilder &opGroupSMax(uint32_t result_type, uint32_t result_id,
-                           uint32_t execution, spv::GroupOperation operation,
-                           uint32_t x);
-  InstBuilder &opReadPipe(uint32_t result_type, uint32_t result_id,
-                          uint32_t pipe, uint32_t pointer, uint32_t packet_size,
-                          uint32_t packet_alignment);
-  InstBuilder &opWritePipe(uint32_t result_type, uint32_t result_id,
-                           uint32_t pipe, uint32_t pointer,
-                           uint32_t packet_size, uint32_t packet_alignment);
-  InstBuilder &opReservedReadPipe(uint32_t result_type, uint32_t result_id,
-                                  uint32_t pipe, uint32_t reserve_id,
-                                  uint32_t index, uint32_t pointer,
-                                  uint32_t packet_size,
-                                  uint32_t packet_alignment);
-  InstBuilder &opReservedWritePipe(uint32_t result_type, uint32_t result_id,
-                                   uint32_t pipe, uint32_t reserve_id,
-                                   uint32_t index, uint32_t pointer,
-                                   uint32_t packet_size,
-                                   uint32_t packet_alignment);
-  InstBuilder &opReserveReadPipePackets(uint32_t result_type,
-                                        uint32_t result_id, uint32_t pipe,
-                                        uint32_t num_packets,
-                                        uint32_t packet_size,
-                                        uint32_t packet_alignment);
-  InstBuilder &opReserveWritePipePackets(uint32_t result_type,
-                                         uint32_t result_id, uint32_t pipe,
-                                         uint32_t num_packets,
-                                         uint32_t packet_size,
-                                         uint32_t packet_alignment);
-  InstBuilder &opCommitReadPipe(uint32_t pipe, uint32_t reserve_id,
-                                uint32_t packet_size,
-                                uint32_t packet_alignment);
-  InstBuilder &opCommitWritePipe(uint32_t pipe, uint32_t reserve_id,
-                                 uint32_t packet_size,
-                                 uint32_t packet_alignment);
-  InstBuilder &opIsValidReserveId(uint32_t result_type, uint32_t result_id,
-                                  uint32_t reserve_id);
-  InstBuilder &opGetNumPipePackets(uint32_t result_type, uint32_t result_id,
-                                   uint32_t pipe, uint32_t packet_size,
-                                   uint32_t packet_alignment);
-  InstBuilder &opGetMaxPipePackets(uint32_t result_type, uint32_t result_id,
-                                   uint32_t pipe, uint32_t packet_size,
-                                   uint32_t packet_alignment);
-  InstBuilder &opGroupReserveReadPipePackets(uint32_t result_type,
-                                             uint32_t result_id,
-                                             uint32_t execution, uint32_t pipe,
-                                             uint32_t num_packets,
-                                             uint32_t packet_size,
-                                             uint32_t packet_alignment);
-  InstBuilder &opGroupReserveWritePipePackets(uint32_t result_type,
-                                              uint32_t result_id,
-                                              uint32_t execution, uint32_t pipe,
-                                              uint32_t num_packets,
-                                              uint32_t packet_size,
-                                              uint32_t packet_alignment);
-  InstBuilder &opGroupCommitReadPipe(uint32_t execution, uint32_t pipe,
-                                     uint32_t reserve_id, uint32_t packet_size,
-                                     uint32_t packet_alignment);
-  InstBuilder &opGroupCommitWritePipe(uint32_t execution, uint32_t pipe,
-                                      uint32_t reserve_id, uint32_t packet_size,
-                                      uint32_t packet_alignment);
-  InstBuilder &opEnqueueMarker(uint32_t result_type, uint32_t result_id,
-                               uint32_t queue, uint32_t num_events,
-                               uint32_t wait_events, uint32_t ret_event);
-  InstBuilder &opEnqueueKernel(uint32_t result_type, uint32_t result_id,
-                               uint32_t queue, uint32_t flags,
-                               uint32_t nd_range, uint32_t num_events,
-                               uint32_t wait_events, uint32_t ret_event,
-                               uint32_t invoke, uint32_t param,
-                               uint32_t param_size, uint32_t param_align,
-                               llvm::ArrayRef<uint32_t> local_size);
-  InstBuilder &opGetKernelNDrangeSubGroupCount(uint32_t result_type,
-                                               uint32_t result_id,
-                                               uint32_t nd_range,
-                                               uint32_t invoke, uint32_t param,
-                                               uint32_t param_size,
-                                               uint32_t param_align);
-  InstBuilder &
-  opGetKernelNDrangeMaxSubGroupSize(uint32_t result_type, uint32_t result_id,
-                                    uint32_t nd_range, uint32_t invoke,
-                                    uint32_t param, uint32_t param_size,
-                                    uint32_t param_align);
-  InstBuilder &opGetKernelWorkGroupSize(uint32_t result_type,
-                                        uint32_t result_id, uint32_t invoke,
-                                        uint32_t param, uint32_t param_size,
-                                        uint32_t param_align);
-  InstBuilder &opGetKernelPreferredWorkGroupSizeMultiple(
-      uint32_t result_type, uint32_t result_id, uint32_t invoke, uint32_t param,
-      uint32_t param_size, uint32_t param_align);
-  InstBuilder &opRetainEvent(uint32_t event);
-  InstBuilder &opReleaseEvent(uint32_t event);
-  InstBuilder &opCreateUserEvent(uint32_t result_type, uint32_t result_id);
-  InstBuilder &opIsValidEvent(uint32_t result_type, uint32_t result_id,
-                              uint32_t event);
-  InstBuilder &opSetUserEventStatus(uint32_t event, uint32_t status);
-  InstBuilder &opCaptureEventProfilingInfo(uint32_t event,
-                                           uint32_t profiling_info,
-                                           uint32_t value);
-  InstBuilder &opGetDefaultQueue(uint32_t result_type, uint32_t result_id);
-  InstBuilder &opBuildNDRange(uint32_t result_type, uint32_t result_id,
-                              uint32_t global_work_size,
-                              uint32_t local_work_size,
-                              uint32_t global_work_offset);
   InstBuilder &opImageSparseSampleImplicitLod(
       uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
       uint32_t coordinate,
@@ -806,219 +471,6 @@ public:
   InstBuilder &opModuleProcessed(std::string process);
   InstBuilder &opExecutionModeId(uint32_t entry_point, spv::ExecutionMode mode);
   InstBuilder &opDecorateId(uint32_t target, spv::Decoration decoration);
-  InstBuilder &opGroupNonUniformElect(uint32_t result_type, uint32_t result_id,
-                                      uint32_t execution);
-  InstBuilder &opGroupNonUniformAll(uint32_t result_type, uint32_t result_id,
-                                    uint32_t execution, uint32_t predicate);
-  InstBuilder &opGroupNonUniformAny(uint32_t result_type, uint32_t result_id,
-                                    uint32_t execution, uint32_t predicate);
-  InstBuilder &opGroupNonUniformAllEqual(uint32_t result_type,
-                                         uint32_t result_id, uint32_t execution,
-                                         uint32_t value);
-  InstBuilder &opGroupNonUniformBroadcast(uint32_t result_type,
-                                          uint32_t result_id,
-                                          uint32_t execution, uint32_t value,
-                                          uint32_t id);
-  InstBuilder &opGroupNonUniformBroadcastFirst(uint32_t result_type,
-                                               uint32_t result_id,
-                                               uint32_t execution,
-                                               uint32_t value);
-  InstBuilder &opGroupNonUniformBallot(uint32_t result_type, uint32_t result_id,
-                                       uint32_t execution, uint32_t predicate);
-  InstBuilder &opGroupNonUniformInverseBallot(uint32_t result_type,
-                                              uint32_t result_id,
-                                              uint32_t execution,
-                                              uint32_t value);
-  InstBuilder &opGroupNonUniformBallotBitExtract(uint32_t result_type,
-                                                 uint32_t result_id,
-                                                 uint32_t execution,
-                                                 uint32_t value,
-                                                 uint32_t index);
-  InstBuilder &opGroupNonUniformBallotBitCount(uint32_t result_type,
-                                               uint32_t result_id,
-                                               uint32_t execution,
-                                               spv::GroupOperation operation,
-                                               uint32_t value);
-  InstBuilder &opGroupNonUniformBallotFindLSB(uint32_t result_type,
-                                              uint32_t result_id,
-                                              uint32_t execution,
-                                              uint32_t value);
-  InstBuilder &opGroupNonUniformBallotFindMSB(uint32_t result_type,
-                                              uint32_t result_id,
-                                              uint32_t execution,
-                                              uint32_t value);
-  InstBuilder &opGroupNonUniformShuffle(uint32_t result_type,
-                                        uint32_t result_id, uint32_t execution,
-                                        uint32_t value, uint32_t id);
-  InstBuilder &opGroupNonUniformShuffleXor(uint32_t result_type,
-                                           uint32_t result_id,
-                                           uint32_t execution, uint32_t value,
-                                           uint32_t mask);
-  InstBuilder &opGroupNonUniformShuffleUp(uint32_t result_type,
-                                          uint32_t result_id,
-                                          uint32_t execution, uint32_t value,
-                                          uint32_t delta);
-  InstBuilder &opGroupNonUniformShuffleDown(uint32_t result_type,
-                                            uint32_t result_id,
-                                            uint32_t execution, uint32_t value,
-                                            uint32_t delta);
-  InstBuilder &opGroupNonUniformIAdd(uint32_t result_type, uint32_t result_id,
-                                     uint32_t execution,
-                                     spv::GroupOperation operation,
-                                     uint32_t value,
-                                     llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &opGroupNonUniformFAdd(uint32_t result_type, uint32_t result_id,
-                                     uint32_t execution,
-                                     spv::GroupOperation operation,
-                                     uint32_t value,
-                                     llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &opGroupNonUniformIMul(uint32_t result_type, uint32_t result_id,
-                                     uint32_t execution,
-                                     spv::GroupOperation operation,
-                                     uint32_t value,
-                                     llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &opGroupNonUniformFMul(uint32_t result_type, uint32_t result_id,
-                                     uint32_t execution,
-                                     spv::GroupOperation operation,
-                                     uint32_t value,
-                                     llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &opGroupNonUniformSMin(uint32_t result_type, uint32_t result_id,
-                                     uint32_t execution,
-                                     spv::GroupOperation operation,
-                                     uint32_t value,
-                                     llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &opGroupNonUniformUMin(uint32_t result_type, uint32_t result_id,
-                                     uint32_t execution,
-                                     spv::GroupOperation operation,
-                                     uint32_t value,
-                                     llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &opGroupNonUniformFMin(uint32_t result_type, uint32_t result_id,
-                                     uint32_t execution,
-                                     spv::GroupOperation operation,
-                                     uint32_t value,
-                                     llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &opGroupNonUniformSMax(uint32_t result_type, uint32_t result_id,
-                                     uint32_t execution,
-                                     spv::GroupOperation operation,
-                                     uint32_t value,
-                                     llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &opGroupNonUniformUMax(uint32_t result_type, uint32_t result_id,
-                                     uint32_t execution,
-                                     spv::GroupOperation operation,
-                                     uint32_t value,
-                                     llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &opGroupNonUniformFMax(uint32_t result_type, uint32_t result_id,
-                                     uint32_t execution,
-                                     spv::GroupOperation operation,
-                                     uint32_t value,
-                                     llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &
-  opGroupNonUniformBitwiseAnd(uint32_t result_type, uint32_t result_id,
-                              uint32_t execution, spv::GroupOperation operation,
-                              uint32_t value,
-                              llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &
-  opGroupNonUniformBitwiseOr(uint32_t result_type, uint32_t result_id,
-                             uint32_t execution, spv::GroupOperation operation,
-                             uint32_t value,
-                             llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &
-  opGroupNonUniformBitwiseXor(uint32_t result_type, uint32_t result_id,
-                              uint32_t execution, spv::GroupOperation operation,
-                              uint32_t value,
-                              llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &
-  opGroupNonUniformLogicalAnd(uint32_t result_type, uint32_t result_id,
-                              uint32_t execution, spv::GroupOperation operation,
-                              uint32_t value,
-                              llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &
-  opGroupNonUniformLogicalOr(uint32_t result_type, uint32_t result_id,
-                             uint32_t execution, spv::GroupOperation operation,
-                             uint32_t value,
-                             llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &
-  opGroupNonUniformLogicalXor(uint32_t result_type, uint32_t result_id,
-                              uint32_t execution, spv::GroupOperation operation,
-                              uint32_t value,
-                              llvm::Optional<uint32_t> cluster_size);
-  InstBuilder &opGroupNonUniformQuadBroadcast(uint32_t result_type,
-                                              uint32_t result_id,
-                                              uint32_t execution,
-                                              uint32_t value, uint32_t index);
-  InstBuilder &opGroupNonUniformQuadSwap(uint32_t result_type,
-                                         uint32_t result_id, uint32_t execution,
-                                         uint32_t value, uint32_t direction);
-  InstBuilder &opSubgroupBallotKHR(uint32_t result_type, uint32_t result_id,
-                                   uint32_t predicate);
-  InstBuilder &opSubgroupFirstInvocationKHR(uint32_t result_type,
-                                            uint32_t result_id, uint32_t value);
-  InstBuilder &opSubgroupAllKHR(uint32_t result_type, uint32_t result_id,
-                                uint32_t predicate);
-  InstBuilder &opSubgroupAnyKHR(uint32_t result_type, uint32_t result_id,
-                                uint32_t predicate);
-  InstBuilder &opSubgroupAllEqualKHR(uint32_t result_type, uint32_t result_id,
-                                     uint32_t predicate);
-  InstBuilder &opSubgroupReadInvocationKHR(uint32_t result_type,
-                                           uint32_t result_id, uint32_t value,
-                                           uint32_t index);
-  InstBuilder &opGroupIAddNonUniformAMD(uint32_t result_type,
-                                        uint32_t result_id, uint32_t execution,
-                                        spv::GroupOperation operation,
-                                        uint32_t x);
-  InstBuilder &opGroupFAddNonUniformAMD(uint32_t result_type,
-                                        uint32_t result_id, uint32_t execution,
-                                        spv::GroupOperation operation,
-                                        uint32_t x);
-  InstBuilder &opGroupFMinNonUniformAMD(uint32_t result_type,
-                                        uint32_t result_id, uint32_t execution,
-                                        spv::GroupOperation operation,
-                                        uint32_t x);
-  InstBuilder &opGroupUMinNonUniformAMD(uint32_t result_type,
-                                        uint32_t result_id, uint32_t execution,
-                                        spv::GroupOperation operation,
-                                        uint32_t x);
-  InstBuilder &opGroupSMinNonUniformAMD(uint32_t result_type,
-                                        uint32_t result_id, uint32_t execution,
-                                        spv::GroupOperation operation,
-                                        uint32_t x);
-  InstBuilder &opGroupFMaxNonUniformAMD(uint32_t result_type,
-                                        uint32_t result_id, uint32_t execution,
-                                        spv::GroupOperation operation,
-                                        uint32_t x);
-  InstBuilder &opGroupUMaxNonUniformAMD(uint32_t result_type,
-                                        uint32_t result_id, uint32_t execution,
-                                        spv::GroupOperation operation,
-                                        uint32_t x);
-  InstBuilder &opGroupSMaxNonUniformAMD(uint32_t result_type,
-                                        uint32_t result_id, uint32_t execution,
-                                        spv::GroupOperation operation,
-                                        uint32_t x);
-  InstBuilder &opFragmentMaskFetchAMD(uint32_t result_type, uint32_t result_id,
-                                      uint32_t image, uint32_t coordinate);
-  InstBuilder &opFragmentFetchAMD(uint32_t result_type, uint32_t result_id,
-                                  uint32_t image, uint32_t coordinate,
-                                  uint32_t fragment_index);
-  InstBuilder &opSubgroupShuffleINTEL(uint32_t result_type, uint32_t result_id,
-                                      uint32_t data, uint32_t invocation_id);
-  InstBuilder &opSubgroupShuffleDownINTEL(uint32_t result_type,
-                                          uint32_t result_id, uint32_t current,
-                                          uint32_t next, uint32_t delta);
-  InstBuilder &opSubgroupShuffleUpINTEL(uint32_t result_type,
-                                        uint32_t result_id, uint32_t previous,
-                                        uint32_t current, uint32_t delta);
-  InstBuilder &opSubgroupShuffleXorINTEL(uint32_t result_type,
-                                         uint32_t result_id, uint32_t data,
-                                         uint32_t value);
-  InstBuilder &opSubgroupBlockReadINTEL(uint32_t result_type,
-                                        uint32_t result_id, uint32_t ptr);
-  InstBuilder &opSubgroupBlockWriteINTEL(uint32_t ptr, uint32_t data);
-  InstBuilder &opSubgroupImageBlockReadINTEL(uint32_t result_type,
-                                             uint32_t result_id, uint32_t image,
-                                             uint32_t coordinate);
-  InstBuilder &opSubgroupImageBlockWriteINTEL(uint32_t image,
-                                              uint32_t coordinate,
-                                              uint32_t data);
   InstBuilder &opDecorateStringGOOGLE(uint32_t target,
                                       spv::Decoration decoration);
   InstBuilder &opMemberDecorateStringGOOGLE(uint32_t struct_type,
@@ -1033,6 +485,9 @@ public:
   InstBuilder &specConstantBinaryOp(spv::Op op, uint32_t result_type,
                                     uint32_t result_id, uint32_t lhs,
                                     uint32_t rhs);
+  InstBuilder &atomicOp(spv::Op op, uint32_t result_type, uint32_t result_id,
+                        uint32_t pointer, uint32_t scope, uint32_t semantics,
+                        uint32_t value);
 
   // All-in-one methods for creating OpGroupNonUniform* operations.
   InstBuilder &groupNonUniformOp(spv::Op op, uint32_t result_type,
@@ -1092,7 +547,7 @@ private:
   void encodeMemoryAccess(spv::MemoryAccessMask value);
   void encodeExecutionMode(spv::ExecutionMode value);
   void encodeDecoration(spv::Decoration value);
-  void encodeString(std::string value);
+  void encodeString(llvm::StringRef value);
 
   WordConsumer TheConsumer;
   std::vector<uint32_t> TheInst;       ///< The instruction under construction.

+ 6 - 0
tools/clang/include/clang/SPIRV/ModuleBuilder.h

@@ -341,6 +341,8 @@ public:
   /// \brief Sets the source file name and the <result-id> for the OpString for
   /// the file name.
   inline void setSourceFileName(uint32_t id, std::string name);
+  /// \brief Sets the main source file content.
+  inline void setSourceFileContent(llvm::StringRef content);
 
   /// \brief Adds an execution mode to the module under construction.
   void addExecutionMode(uint32_t entryPointId, spv::ExecutionMode em,
@@ -553,6 +555,10 @@ void ModuleBuilder::setSourceFileName(uint32_t id, std::string name) {
   theModule.setSourceFileName(id, std::move(name));
 }
 
+void ModuleBuilder::setSourceFileContent(llvm::StringRef content) {
+  theModule.setSourceFileContent(content);
+}
+
 } // end namespace spirv
 } // end namespace clang
 

+ 6 - 0
tools/clang/include/clang/SPIRV/Structure.h

@@ -308,6 +308,7 @@ public:
   inline void addExecutionMode(Instruction &&);
   inline void setShaderModelVersion(uint32_t);
   inline void setSourceFileName(uint32_t id, std::string name);
+  inline void setSourceFileContent(llvm::StringRef content);
   // TODO: source code debug information
   inline void addDebugName(uint32_t targetId, llvm::StringRef name,
                            llvm::Optional<uint32_t> memberIndex = llvm::None);
@@ -341,6 +342,7 @@ private:
   uint32_t shaderModelVersion;
   uint32_t sourceFileNameId; // The <result-id> for the OpString for file name
   std::string sourceFileName;
+  llvm::StringRef sourceFileContent;
   // TODO: source code debug information
   std::set<DebugName> debugNames;
   llvm::SetVector<std::pair<uint32_t, const Decoration *>> decorations;
@@ -503,6 +505,10 @@ void SPIRVModule::setSourceFileName(uint32_t id, std::string name) {
   sourceFileName = std::move(name);
 }
 
+void SPIRVModule::setSourceFileContent(llvm::StringRef content) {
+  sourceFileContent = content;
+}
+
 void SPIRVModule::addDebugName(uint32_t targetId, llvm::StringRef name,
                                llvm::Optional<uint32_t> memberIndex) {
 

+ 8 - 1
tools/clang/lib/Frontend/CompilerInvocation.cpp

@@ -1910,10 +1910,17 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
   // where we have a dxc-based command-line. We choose to accept additional
   // options even if they don't get applied.
   const unsigned IncludedFlagsBitmask = 0;
+#ifdef _WIN32
+  const unsigned ExcludedFlagsBitmask = 0;
+#else
+  // Exception: Exclude cl.exe like arguments that can trip up Unix systems
+  const unsigned ExcludedFlagsBitmask = options::CLOption;
+#endif
+  // End HLSL Change
   unsigned MissingArgIndex, MissingArgCount;
   InputArgList Args =
       Opts->ParseArgs(llvm::makeArrayRef(ArgBegin, ArgEnd), MissingArgIndex,
-                      MissingArgCount, IncludedFlagsBitmask);
+                      MissingArgCount, IncludedFlagsBitmask, ExcludedFlagsBitmask);
 
   // Check for missing argument error.
   if (MissingArgCount) {

+ 18 - 1
tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

@@ -1498,12 +1498,16 @@ bool DeclResultIdMapper::createStageVars(const hlsl::SigPoint *sigPoint,
               theBuilder.getVecType(srcVecElemTypeId, 2), *value, *value,
               {0, 1});
       }
+
+      // Reciprocate SV_Position.w if requested
+      if (semanticKind == hlsl::Semantic::Kind::Position)
+        *value = invertWIfRequested(*value);
     } else {
       if (noWriteBack)
         return true;
 
       // Negate SV_Position.y if requested
-      if (semanticToUse->semantic->GetKind() == hlsl::Semantic::Kind::Position)
+      if (semanticKind == hlsl::Semantic::Kind::Position)
         *value = invertYIfRequested(*value);
 
       uint32_t ptr = varId;
@@ -1790,6 +1794,19 @@ uint32_t DeclResultIdMapper::invertYIfRequested(uint32_t position) {
   return position;
 }
 
+uint32_t DeclResultIdMapper::invertWIfRequested(uint32_t position) {
+  // Reciprocate SV_Position.w if requested
+  if (spirvOptions.invertW && shaderModel.IsPS()) {
+    const auto f32Type = theBuilder.getFloat32Type();
+    const auto v4f32Type = theBuilder.getVecType(f32Type, 4);
+    const auto oldW = theBuilder.createCompositeExtract(f32Type, position, {3});
+    const auto newW = theBuilder.createBinaryOp(
+        spv::Op::OpFDiv, f32Type, theBuilder.getConstantFloat32(1), oldW);
+    position = theBuilder.createCompositeInsert(v4f32Type, position, {3}, newW);
+  }
+  return position;
+}
+
 void DeclResultIdMapper::decoratePSInterpolationMode(const NamedDecl *decl,
                                                      QualType type,
                                                      uint32_t varId) {

+ 7 - 3
tools/clang/lib/SPIRV/DeclResultIdMapper.h

@@ -433,9 +433,13 @@ public:
   bool writeBackOutputStream(const NamedDecl *decl, QualType type,
                              uint32_t value);
 
-  /// \brief Inverts SV_Position.y is requested.
+  /// \brief Negates to get the additive inverse of SV_Position.y if requested.
   uint32_t invertYIfRequested(uint32_t position);
 
+  /// \brief Reciprocates to get the multiplicative inverse of SV_Position.w
+  /// if requested.
+  uint32_t invertWIfRequested(uint32_t position);
+
   /// \brief Decorates all stage input and output variables with proper
   /// location and returns true on success.
   ///
@@ -744,8 +748,8 @@ DeclResultIdMapper::DeclResultIdMapper(const hlsl::ShaderModel &model,
                                        const EmitSPIRVOptions &options)
     : shaderModel(model), theBuilder(builder), spirvOptions(options),
       astContext(context), diags(context.getDiagnostics()),
-      typeTranslator(translator), entryFunctionId(0),
-      laneCountBuiltinId(0), laneIndexBuiltinId(0), needsLegalization(false),
+      typeTranslator(translator), entryFunctionId(0), laneCountBuiltinId(0),
+      laneIndexBuiltinId(0), needsLegalization(false),
       glPerVertex(model, context, builder, typeTranslator) {}
 
 bool DeclResultIdMapper::decorateStageIOLocations() {

File diff suppressed because it is too large
+ 266 - 342
tools/clang/lib/SPIRV/InstBuilderAuto.cpp


+ 30 - 1
tools/clang/lib/SPIRV/InstBuilderManual.cpp

@@ -84,6 +84,35 @@ InstBuilder &InstBuilder::specConstantBinaryOp(spv::Op op, uint32_t result_type,
   return *this;
 }
 
+InstBuilder &InstBuilder::atomicOp(spv::Op op, uint32_t result_type,
+                                   uint32_t result_id, uint32_t pointer,
+                                   uint32_t scope, uint32_t semantics,
+                                   uint32_t value) {
+  if (!TheInst.empty()) {
+    TheStatus = Status::NestedInst;
+    return *this;
+  }
+  if (result_type == 0) {
+    TheStatus = Status::ZeroResultType;
+    return *this;
+  }
+  if (result_id == 0) {
+    TheStatus = Status::ZeroResultId;
+    return *this;
+  }
+
+  TheInst.reserve(7);
+  TheInst.emplace_back(static_cast<uint32_t>(op));
+  TheInst.emplace_back(result_type);
+  TheInst.emplace_back(result_id);
+  TheInst.emplace_back(pointer);
+  TheInst.emplace_back(scope);
+  TheInst.emplace_back(semantics);
+  TheInst.emplace_back(value);
+
+  return *this;
+}
+
 InstBuilder &InstBuilder::groupNonUniformOp(spv::Op op, uint32_t result_type,
                                             uint32_t result_id,
                                             uint32_t exec_scope) {
@@ -234,7 +263,7 @@ InstBuilder &InstBuilder::opSpecConstant(uint32_t resultType, uint32_t resultId,
   return *this;
 }
 
-void InstBuilder::encodeString(std::string value) {
+void InstBuilder::encodeString(llvm::StringRef value) {
   const auto &words = string::encodeSPIRVString(value);
   TheInst.insert(TheInst.end(), words.begin(), words.end());
 }

+ 4 - 45
tools/clang/lib/SPIRV/ModuleBuilder.cpp

@@ -301,51 +301,10 @@ uint32_t ModuleBuilder::createAtomicOp(spv::Op opcode, uint32_t resultType,
                                        uint32_t valueToOp) {
   assert(insertPoint && "null insert point");
   const uint32_t id = theContext.takeNextId();
-  switch (opcode) {
-  case spv::Op::OpAtomicIAdd:
-    instBuilder.opAtomicIAdd(resultType, id, orignalValuePtr, scopeId,
-                             memorySemanticsId, valueToOp);
-    break;
-  case spv::Op::OpAtomicISub:
-    instBuilder.opAtomicISub(resultType, id, orignalValuePtr, scopeId,
-                             memorySemanticsId, valueToOp);
-    break;
-  case spv::Op::OpAtomicAnd:
-    instBuilder.opAtomicAnd(resultType, id, orignalValuePtr, scopeId,
-                            memorySemanticsId, valueToOp);
-    break;
-  case spv::Op::OpAtomicOr:
-    instBuilder.opAtomicOr(resultType, id, orignalValuePtr, scopeId,
-                           memorySemanticsId, valueToOp);
-    break;
-  case spv::Op::OpAtomicXor:
-    instBuilder.opAtomicXor(resultType, id, orignalValuePtr, scopeId,
-                            memorySemanticsId, valueToOp);
-    break;
-  case spv::Op::OpAtomicUMax:
-    instBuilder.opAtomicUMax(resultType, id, orignalValuePtr, scopeId,
-                             memorySemanticsId, valueToOp);
-    break;
-  case spv::Op::OpAtomicUMin:
-    instBuilder.opAtomicUMin(resultType, id, orignalValuePtr, scopeId,
-                             memorySemanticsId, valueToOp);
-    break;
-  case spv::Op::OpAtomicSMax:
-    instBuilder.opAtomicSMax(resultType, id, orignalValuePtr, scopeId,
-                             memorySemanticsId, valueToOp);
-    break;
-  case spv::Op::OpAtomicSMin:
-    instBuilder.opAtomicSMin(resultType, id, orignalValuePtr, scopeId,
-                             memorySemanticsId, valueToOp);
-    break;
-  case spv::Op::OpAtomicExchange:
-    instBuilder.opAtomicExchange(resultType, id, orignalValuePtr, scopeId,
-                                 memorySemanticsId, valueToOp);
-    break;
-  default:
-    assert(false && "unimplemented atomic opcode");
-  }
-  instBuilder.x();
+  instBuilder
+      .atomicOp(opcode, resultType, id, orignalValuePtr, scopeId,
+                memorySemanticsId, valueToOp)
+      .x();
   insertPoint->appendInstruction(std::move(constructSite));
   return id;
 }

+ 10 - 1
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -610,9 +610,18 @@ SPIRVEmitter::SPIRVEmitter(CompilerInstance &ci, EmitSPIRVOptions &options)
 
   // Set debug info
   const auto &inputFiles = ci.getFrontendOpts().Inputs;
-  if (options.enableDebugInfo && !inputFiles.empty())
+  if (options.enableDebugInfo && !inputFiles.empty()) {
+    // File name
     theBuilder.setSourceFileName(theContext.takeNextId(),
                                  inputFiles.front().getFile().str());
+
+    // Source code
+    const auto &sm = ci.getSourceManager();
+    const llvm::MemoryBuffer *mainFile =
+        sm.getBuffer(sm.getMainFileID(), SourceLocation());
+    theBuilder.setSourceFileContent(
+        StringRef(mainFile->getBufferStart(), mainFile->getBufferSize()));
+  }
 }
 
 void SPIRVEmitter::HandleTranslationUnit(ASTContext &context) {

+ 38 - 1
tools/clang/lib/SPIRV/Structure.cpp

@@ -17,6 +17,32 @@ namespace spirv {
 namespace {
 constexpr uint32_t kGeneratorNumber = 14;
 constexpr uint32_t kToolVersion = 0;
+
+/// Chops the given original string into multiple smaller ones to make sure they
+/// can be encoded in a sequence of OpSourceContinued instructions following an
+/// OpSource instruction.
+void chopString(llvm::StringRef original,
+                llvm::SmallVectorImpl<llvm::StringRef> *chopped) {
+  const uint32_t maxCharInOpSource = 0xFFFFu - 5u; // Minus operands and nul
+  const uint32_t maxCharInContinue = 0xFFFFu - 2u; // Minus opcode and nul
+
+  chopped->clear();
+  if (original.size() > maxCharInOpSource) {
+    chopped->push_back(llvm::StringRef(original.data(), maxCharInOpSource));
+    original = llvm::StringRef(original.data() + maxCharInOpSource,
+                               original.size() - maxCharInOpSource);
+    while (original.size() > maxCharInContinue) {
+      chopped->push_back(llvm::StringRef(original.data(), maxCharInContinue));
+      original = llvm::StringRef(original.data() + maxCharInContinue,
+                                 original.size() - maxCharInContinue);
+    }
+    if (!original.empty()) {
+      chopped->push_back(original);
+    }
+  } else if (!original.empty()) {
+    chopped->push_back(original);
+  }
+}
 } // namespace
 
 // === Instruction implementations ===
@@ -289,10 +315,21 @@ void SPIRVModule::take(InstBuilder *builder) {
       fileName = sourceFileNameId;
     }
 
+    llvm::SmallVector<llvm::StringRef, 2> choppedSrcCode;
+    llvm::Optional<llvm::StringRef> firstSnippet;
+    chopString(sourceFileContent, &choppedSrcCode);
+    if (!choppedSrcCode.empty()) {
+      firstSnippet = llvm::Optional<llvm::StringRef>(choppedSrcCode.front());
+    }
+
     builder
         ->opSource(spv::SourceLanguage::HLSL, shaderModelVersion, fileName,
-                   llvm::None)
+                   firstSnippet)
         .x();
+
+    for (uint32_t i = 1; i < choppedSrcCode.size(); ++i) {
+      builder->opSourceContinued(choppedSrcCode[i]).x();
+    }
   }
 
   // BasicBlock debug names should be emitted only for blocks that are

+ 5 - 0
tools/clang/lib/Sema/SemaHLSL.cpp

@@ -3736,6 +3736,11 @@ public:
     DXASSERT_VALIDBASICKIND(componentType);
 
     QualType pType;  // The type to return.
+    if (componentType < AR_BASIC_COUNT) {
+      // If basic numeric, call LookupScalarTypeDef to ensure on-demand
+      // initialization
+      LookupScalarTypeDef(ScalarTypeForBasic(componentType));
+    }
     QualType pEltType = GetBasicKindType(componentType);
     DXASSERT(!pEltType.isNull(), "otherwise caller is specifying an incorrect basic kind type");
 

+ 11 - 0
tools/clang/test/CodeGenHLSL/quick-test/min10float.hlsl

@@ -0,0 +1,11 @@
+// RUN: %dxc -E main -T ps_6_0 -Zi %s | FileCheck %s
+
+// CHECK: warning: min10float is promoted to min16float
+// CHECK: define void @main
+// CHECK: ret void
+
+[RootSignature("")]
+min10float main( min10float mf:P ) : SV_Target
+{
+    return  mf * 2;
+}

+ 21 - 0
tools/clang/test/CodeGenHLSL/quick-test/min10float_to_float.hlsl

@@ -0,0 +1,21 @@
+// RUN: %dxc -E main -T ps_6_0 -Zi %s | FileCheck %s
+
+// CHECK: warning: min10float is promoted to min16float
+// CHECK: define void @main
+// CHECK: ret void
+
+[RootSignature("")]
+float2 main( min10float mf:P , int s:Q) : SV_Target
+{
+    if(s > 1)
+    {
+        min10float new_mf = mf * mf;
+        new_mf = new_mf / 2.0;
+        float f = float(new_mf);
+        f = (f * 4.0) / 3.3;
+        min10float new_mf1 = min10float(f);
+        new_mf1 = new_mf1 + new_mf;
+        return float2(new_mf1, new_mf1);
+    }
+    return float2(1.0, 1.0);
+}

+ 11 - 0
tools/clang/test/CodeGenHLSL/quick-test/min12int.hlsl

@@ -0,0 +1,11 @@
+// RUN: %dxc -E main -T ps_6_0 -Zi %s | FileCheck %s
+
+// CHECK: warning: min12int is promoted to min16int
+// CHECK: define void @main
+// CHECK: ret void
+
+[RootSignature("")]
+min12int main( min12int mi:P ) : SV_Target
+{
+    return  mi * 2;
+}

+ 21 - 0
tools/clang/test/CodeGenHLSL/quick-test/min12int_to_int.hlsl

@@ -0,0 +1,21 @@
+// RUN: %dxc -E main -T ps_6_0 -Zi %s | FileCheck %s
+
+// CHECK: warning: min12int is promoted to min16int
+// CHECK: define void @main
+// CHECK: ret void
+
+[RootSignature("")]
+int2 main( min12int mi:P , int s:Q) : SV_Target
+{
+    if(s > 1)
+    {
+        min12int new_mi = mi * mi;
+        new_mi = min12int(new_mi * 2);
+        int f = int(new_mi);
+        f = (f * 4) / 3;
+        min12int new_mi1 = min12int(f);
+        new_mi1 = new_mi1 + new_mi;
+        return int2(new_mi1, new_mi1);
+    }
+    return int2(1, 1);
+}

+ 7 - 0
tools/clang/test/CodeGenSPIRV/spirv.debug.opsource.hlsl

@@ -4,6 +4,13 @@
 // CHECK-SAME: spirv.debug.opsource.hlsl
 // CHECK:      OpSource HLSL 610 [[str]]
 
+// Make sure we have #line directive emitted by the preprocessor
+// CHECK-SAME: #line 1
+
+// Make sure we have the original source code
+// CHECK:      numthreads(8, 1, 1)
+// CHECK-NEXT: void main()
+
 [numthreads(8, 1, 1)]
 void main() {
 }

+ 29 - 0
tools/clang/test/CodeGenSPIRV/vk.cloption.invert-w.ds.hlsl

@@ -0,0 +1,29 @@
+// Run: %dxc -T ds_6_0 -E main -fvk-use-dx-position-w
+
+// HS PCF output
+struct HsPcfOut {
+  float  outTessFactor[4]   : SV_TessFactor;
+  float  inTessFactor[2]    : SV_InsideTessFactor;
+};
+
+// Per-vertex input structs
+struct DsCpIn {
+    float4 pos : SV_Position;
+};
+
+// Per-vertex output structs
+struct DsCpOut {
+    float4 pos : SV_Position;
+};
+
+[domain("quad")]
+DsCpOut main(OutputPatch<DsCpIn, 3> patch,
+             HsPcfOut pcfData) {
+  DsCpOut dsOut;
+  dsOut = (DsCpOut)0;
+  return dsOut;
+}
+
+// Make sure -fvk-use-dx-position-w is ignored for non-PS stages
+// CHECK:     OpLoad %_arr_v4float_uint_3 %gl_Position
+// CHECK-NOT: OpCompositeInsert %v4float {{%\d+}} {{%\d+}} 3

+ 12 - 0
tools/clang/test/CodeGenSPIRV/vk.cloption.invert-w.ps.hlsl

@@ -0,0 +1,12 @@
+// Run: %dxc -T ps_6_0 -E main -fvk-use-dx-position-w
+
+float4 main(float4 pos: SV_Position) : SV_Target {
+    return pos;
+}
+
+// CHECK:       [[old:%\d+]] = OpLoad %v4float %gl_FragCoord
+// CHECK-NEXT: [[oldW:%\d+]] = OpCompositeExtract %float [[old]] 3
+// CHECK-NEXT: [[newW:%\d+]] = OpFDiv %float %float_1 [[oldW]]
+// CHECK-NEXT:  [[new:%\d+]] = OpCompositeInsert %v4float [[newW]] [[old]] 3
+// CHECK-NEXT:                 OpStore %param_var_pos [[new]]
+// CHECK-NEXT:                 OpFunctionCall %v4float %src_main %param_var_pos

+ 2 - 0
tools/clang/tools/dxcompiler/CMakeLists.txt

@@ -140,6 +140,8 @@ if ( HLSL_SUPPORT_QUERY_GIT_COMMIT_INFO )
     ${CMAKE_COMMAND} -E touch ${GET_GIT_COMMIT_SCRIPT}
     COMMENT "Touch GetCommitInfo.py to trigger rebuild"
   )
+  set_property(TARGET GIT_COMMIT_INFO_ALWAYS_REBUILD
+    PROPERTY FOLDER "Utils")
   set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/dxcompilerobj.cpp
     PROPERTIES OBJECT_DEPENDS "${GIT_COMMIT_INFO_FILE}")
   set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/dxcvalidator.cpp

+ 40 - 11
tools/clang/tools/dxcompiler/dxcompilerobj.cpp

@@ -294,6 +294,7 @@ public:
         (argCount > 0 && pArguments == nullptr) || pEntryPoint == nullptr ||
         pTargetProfile == nullptr)
       return E_INVALIDARG;
+
     *ppResult = nullptr;
     AssignToOutOpt(nullptr, ppDebugBlobName);
     AssignToOutOpt(nullptr, ppDebugBlob);
@@ -302,23 +303,15 @@ public:
     CComPtr<IDxcBlobEncoding> utf8Source;
     CComPtr<AbstractMemoryStream> pOutputStream;
     CHeapPtr<wchar_t> DebugBlobName;
+
     DxcEtw_DXCompilerCompile_Start();
     pSourceName = (pSourceName && *pSourceName) ? pSourceName : L"hlsl.hlsl"; // declared optional, so pick a default
     DxcThreadMalloc TM(m_pMalloc);
-    IFC(hlsl::DxcGetBlobAsUtf8(pSource, &utf8Source));
 
     try {
-      CComPtr<IDxcBlob> pOutputBlob;
-      dxcutil::DxcArgsFileSystem *msfPtr =
-        dxcutil::CreateDxcArgsFileSystem(utf8Source, pSourceName, pIncludeHandler);
-      std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
-
-      ::llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
-      IFTLLVM(pts.error_code());
-
       IFT(CreateMemoryStream(m_pMalloc, &pOutputStream));
-      IFT(pOutputStream.QueryInterface(&pOutputBlob));
 
+      // Parse command-line options into DxcOpts
       int argCountInt;
       IFT(UIntToInt(argCount, &argCountInt));
       hlsl::options::MainArgs mainArgs(argCountInt, pArguments, 0);
@@ -326,12 +319,46 @@ public:
       CW2A pUtf8TargetProfile(pTargetProfile, CP_UTF8);
       // Set target profile before reading options and validate
       opts.TargetProfile = pUtf8TargetProfile.m_psz;
-      bool finished;
+      bool finished = false;
       dxcutil::ReadOptsAndValidate(mainArgs, opts, pOutputStream, ppResult, finished);
       if (finished) {
         hr = S_OK;
         goto Cleanup;
       }
+
+#ifdef ENABLE_SPIRV_CODEGEN
+      // We want to embed the preprocessed source code in the final SPIR-V if
+      // debug information is enabled. Therefore, we invoke Preprocess() here
+      // first for such case. Then we invoke the compilation process over the
+      // preprocessed source code, so that line numbers are consistent with the
+      // embedded source code.
+      CComPtr<IDxcBlob> ppSrcCode;
+      if (opts.GenSPIRV && opts.DebugInfo) {
+        CComPtr<IDxcOperationResult> ppSrcCodeResult;
+        IFT(Preprocess(pSource, pSourceName, pArguments, argCount, pDefines,
+                       defineCount, pIncludeHandler, &ppSrcCodeResult));
+        HRESULT status;
+        IFT(ppSrcCodeResult->GetStatus(&status));
+        if (SUCCEEDED(status)) {
+          IFT(ppSrcCodeResult->GetResult(&ppSrcCode));
+        }
+        pSource = ppSrcCode;
+      }
+#endif // ENABLE_SPIRV_CODEGEN
+
+      // Convert source code encoding
+      IFC(hlsl::DxcGetBlobAsUtf8(pSource, &utf8Source));
+
+      CComPtr<IDxcBlob> pOutputBlob;
+      dxcutil::DxcArgsFileSystem *msfPtr =
+        dxcutil::CreateDxcArgsFileSystem(utf8Source, pSourceName, pIncludeHandler);
+      std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
+
+      ::llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
+      IFTLLVM(pts.error_code());
+
+      IFT(pOutputStream.QueryInterface(&pOutputBlob));
+
       if (opts.DisplayIncludeProcess)
         msfPtr->EnableDisplayIncludeProcess();
 
@@ -472,6 +499,7 @@ public:
           spirvOpts.codeGenHighLevel = opts.CodeGenHighLevel;
           spirvOpts.disableValidation = opts.DisableValidation;
           spirvOpts.invertY = opts.VkInvertY;
+          spirvOpts.invertW = opts.VkInvertW;
           spirvOpts.useGlLayout = opts.VkUseGlLayout;
           spirvOpts.useDxLayout = opts.VkUseDxLayout;
           spirvOpts.enableReflect = opts.SpvEnableReflect;
@@ -486,6 +514,7 @@ public:
           spirvOpts.targetEnv = opts.SpvTargetEnv;
           spirvOpts.enable16BitTypes = opts.Enable16BitTypes;
           spirvOpts.enableDebugInfo = opts.DebugInfo;
+
           clang::EmitSPIRVAction action(spirvOpts);
           FrontendInputFile file(utf8SourceName.m_psz, IK_HLSL);
           action.BeginSourceFile(compiler, file);

+ 182 - 177
tools/clang/tools/libclang/dxcisenseimpl.cpp

@@ -60,7 +60,7 @@ private:
   unsigned m_length;
 public:
   DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL()
-  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject)
+  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject) override
   {
     return DoBasicQueryInterface<IDxcUnsavedFile>(this, iid, ppvObject);
   }
@@ -360,10 +360,15 @@ HRESULT SetupUnsavedFiles(
       break;
     }
 
-    hr = unsaved_files[i]->GetFileName((LPSTR*)&localFiles[i].Filename);
+    LPSTR strPtr;
+    hr = unsaved_files[i]->GetFileName(&strPtr);
     if (FAILED(hr)) break;
-    hr = unsaved_files[i]->GetContents((LPSTR*)&localFiles[i].Contents);
+    localFiles[i].Filename = strPtr;
+
+    hr = unsaved_files[i]->GetContents(&strPtr);
     if (FAILED(hr)) break;
+    localFiles[i].Contents = strPtr;
+
     hr = unsaved_files[i]->GetLength((unsigned*)&localFiles[i].Length);
     if (FAILED(hr)) break;
   }
@@ -509,7 +514,7 @@ CXChildVisitResult LIBCLANG_CC SourceCursorVisit(CXCursor cursor, CXCursor paren
     bool cursorIsBetter =
       context->found == false ||
       (cursorStartOffset < context->resultOffset) ||
-      (cursorStartOffset == context->resultOffset && cursor.kind == DxcCursor_DeclRefExpr);
+      (cursorStartOffset == context->resultOffset && (int)cursor.kind == (int)DxcCursor_DeclRefExpr);
     if (cursorIsBetter)
     {
       context->found = true;
@@ -1028,7 +1033,7 @@ HRESULT DxcFile::IsEqualTo(IDxcFile* other, BOOL* pResult)
 ///////////////////////////////////////////////////////////////////////////////
 
 DxcInclusion::DxcInclusion()
-    : m_file(nullptr), m_locationLength(0), m_locations(nullptr) {
+    : m_file(nullptr), m_locations(nullptr), m_locationLength(0) {
   m_pMalloc = DxcGetThreadMallocNoRef();
 }
 
@@ -1171,7 +1176,7 @@ HRESULT DxcIndex::ParseTranslationUnit(
     // TODO: until an interface to file access is defined and implemented, simply fall back to pure Win32/CRT calls.
     ::llvm::sys::fs::MSFileSystem* msfPtr;
     IFT(CreateMSFileSystemForDisk(&msfPtr));
-    std::auto_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
+    std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
 
     ::llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
     IFTLLVM(pts.error_code());
@@ -1499,7 +1504,7 @@ DxcTranslationUnit::~DxcTranslationUnit() {
     ::llvm::sys::fs::MSFileSystem* msfPtr;
     CreateMSFileSystemForDisk(&msfPtr);
     assert(msfPtr != nullptr);
-    std::auto_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
+    std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
 
     ::llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
     assert(!pts.error_code());
@@ -1619,7 +1624,7 @@ HRESULT DxcTranslationUnit::GetFile(LPCSTR name, IDxcFile** pResult)
   DxcThreadMalloc TM(m_pMalloc);
   ::llvm::sys::fs::MSFileSystem* msfPtr;
   IFR(CreateMSFileSystemForDisk(&msfPtr));
-  std::auto_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
+  std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
   ::llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
 
   CXFile localFile = clang_getFile(m_tu, name);
@@ -1878,172 +1883,172 @@ HRESULT DxcType::GetKind(DxcTypeKind* pResult)
 
 ///////////////////////////////////////////////////////////////////////////////
 
-C_ASSERT(DxcCursor_UnexposedDecl == CXCursor_UnexposedDecl);
-C_ASSERT(DxcCursor_StructDecl == CXCursor_StructDecl);
-C_ASSERT(DxcCursor_UnionDecl == CXCursor_UnionDecl);
-C_ASSERT(DxcCursor_ClassDecl == CXCursor_ClassDecl);
-C_ASSERT(DxcCursor_EnumDecl == CXCursor_EnumDecl);
-C_ASSERT(DxcCursor_FieldDecl == CXCursor_FieldDecl);
-C_ASSERT(DxcCursor_EnumConstantDecl == CXCursor_EnumConstantDecl);
-C_ASSERT(DxcCursor_FunctionDecl == CXCursor_FunctionDecl);
-C_ASSERT(DxcCursor_VarDecl == CXCursor_VarDecl);
-C_ASSERT(DxcCursor_ParmDecl == CXCursor_ParmDecl);
-C_ASSERT(DxcCursor_ObjCInterfaceDecl == CXCursor_ObjCInterfaceDecl);
-C_ASSERT(DxcCursor_ObjCCategoryDecl == CXCursor_ObjCCategoryDecl);
-C_ASSERT(DxcCursor_ObjCProtocolDecl == CXCursor_ObjCProtocolDecl);
-C_ASSERT(DxcCursor_ObjCPropertyDecl == CXCursor_ObjCPropertyDecl);
-C_ASSERT(DxcCursor_ObjCIvarDecl == CXCursor_ObjCIvarDecl);
-C_ASSERT(DxcCursor_ObjCInstanceMethodDecl == CXCursor_ObjCInstanceMethodDecl);
-C_ASSERT(DxcCursor_ObjCClassMethodDecl == CXCursor_ObjCClassMethodDecl);
-C_ASSERT(DxcCursor_ObjCImplementationDecl == CXCursor_ObjCImplementationDecl);
-C_ASSERT(DxcCursor_ObjCCategoryImplDecl == CXCursor_ObjCCategoryImplDecl);
-C_ASSERT(DxcCursor_TypedefDecl == CXCursor_TypedefDecl);
-C_ASSERT(DxcCursor_CXXMethod == CXCursor_CXXMethod);
-C_ASSERT(DxcCursor_Namespace == CXCursor_Namespace);
-C_ASSERT(DxcCursor_LinkageSpec == CXCursor_LinkageSpec);
-C_ASSERT(DxcCursor_Constructor == CXCursor_Constructor);
-C_ASSERT(DxcCursor_Destructor == CXCursor_Destructor);
-C_ASSERT(DxcCursor_ConversionFunction == CXCursor_ConversionFunction);
-C_ASSERT(DxcCursor_TemplateTypeParameter == CXCursor_TemplateTypeParameter);
-C_ASSERT(DxcCursor_NonTypeTemplateParameter == CXCursor_NonTypeTemplateParameter);
-C_ASSERT(DxcCursor_TemplateTemplateParameter == CXCursor_TemplateTemplateParameter);
-C_ASSERT(DxcCursor_FunctionTemplate == CXCursor_FunctionTemplate);
-C_ASSERT(DxcCursor_ClassTemplate == CXCursor_ClassTemplate);
-C_ASSERT(DxcCursor_ClassTemplatePartialSpecialization == CXCursor_ClassTemplatePartialSpecialization);
-C_ASSERT(DxcCursor_NamespaceAlias == CXCursor_NamespaceAlias);
-C_ASSERT(DxcCursor_UsingDirective == CXCursor_UsingDirective);
-C_ASSERT(DxcCursor_UsingDeclaration == CXCursor_UsingDeclaration);
-C_ASSERT(DxcCursor_TypeAliasDecl == CXCursor_TypeAliasDecl);
-C_ASSERT(DxcCursor_ObjCSynthesizeDecl == CXCursor_ObjCSynthesizeDecl);
-C_ASSERT(DxcCursor_ObjCDynamicDecl == CXCursor_ObjCDynamicDecl);
-C_ASSERT(DxcCursor_CXXAccessSpecifier == CXCursor_CXXAccessSpecifier);
-C_ASSERT(DxcCursor_FirstDecl == CXCursor_FirstDecl);
-C_ASSERT(DxcCursor_LastDecl == CXCursor_LastDecl);
-C_ASSERT(DxcCursor_FirstRef == CXCursor_FirstRef);
-C_ASSERT(DxcCursor_ObjCSuperClassRef == CXCursor_ObjCSuperClassRef);
-C_ASSERT(DxcCursor_ObjCProtocolRef == CXCursor_ObjCProtocolRef);
-C_ASSERT(DxcCursor_ObjCClassRef == CXCursor_ObjCClassRef);
-C_ASSERT(DxcCursor_TypeRef == CXCursor_TypeRef);
-C_ASSERT(DxcCursor_CXXBaseSpecifier == CXCursor_CXXBaseSpecifier);
-C_ASSERT(DxcCursor_TemplateRef == CXCursor_TemplateRef);
-C_ASSERT(DxcCursor_NamespaceRef == CXCursor_NamespaceRef);
-C_ASSERT(DxcCursor_MemberRef == CXCursor_MemberRef);
-C_ASSERT(DxcCursor_LabelRef == CXCursor_LabelRef);
-C_ASSERT(DxcCursor_OverloadedDeclRef == CXCursor_OverloadedDeclRef);
-C_ASSERT(DxcCursor_VariableRef == CXCursor_VariableRef);
-C_ASSERT(DxcCursor_LastRef == CXCursor_LastRef);
-C_ASSERT(DxcCursor_FirstInvalid == CXCursor_FirstInvalid);
-C_ASSERT(DxcCursor_InvalidFile == CXCursor_InvalidFile);
-C_ASSERT(DxcCursor_NoDeclFound == CXCursor_NoDeclFound);
-C_ASSERT(DxcCursor_NotImplemented == CXCursor_NotImplemented);
-C_ASSERT(DxcCursor_InvalidCode == CXCursor_InvalidCode);
-C_ASSERT(DxcCursor_LastInvalid == CXCursor_LastInvalid);
-C_ASSERT(DxcCursor_FirstExpr == CXCursor_FirstExpr);
-C_ASSERT(DxcCursor_UnexposedExpr == CXCursor_UnexposedExpr);
-C_ASSERT(DxcCursor_DeclRefExpr == CXCursor_DeclRefExpr);
-C_ASSERT(DxcCursor_MemberRefExpr == CXCursor_MemberRefExpr);
-C_ASSERT(DxcCursor_CallExpr == CXCursor_CallExpr);
-C_ASSERT(DxcCursor_ObjCMessageExpr == CXCursor_ObjCMessageExpr);
-C_ASSERT(DxcCursor_BlockExpr == CXCursor_BlockExpr);
-C_ASSERT(DxcCursor_IntegerLiteral == CXCursor_IntegerLiteral);
-C_ASSERT(DxcCursor_FloatingLiteral == CXCursor_FloatingLiteral);
-C_ASSERT(DxcCursor_ImaginaryLiteral == CXCursor_ImaginaryLiteral);
-C_ASSERT(DxcCursor_StringLiteral == CXCursor_StringLiteral);
-C_ASSERT(DxcCursor_CharacterLiteral == CXCursor_CharacterLiteral);
-C_ASSERT(DxcCursor_ParenExpr == CXCursor_ParenExpr);
-C_ASSERT(DxcCursor_UnaryOperator == CXCursor_UnaryOperator);
-C_ASSERT(DxcCursor_ArraySubscriptExpr == CXCursor_ArraySubscriptExpr);
-C_ASSERT(DxcCursor_BinaryOperator == CXCursor_BinaryOperator);
-C_ASSERT(DxcCursor_CompoundAssignOperator == CXCursor_CompoundAssignOperator);
-C_ASSERT(DxcCursor_ConditionalOperator == CXCursor_ConditionalOperator);
-C_ASSERT(DxcCursor_CStyleCastExpr == CXCursor_CStyleCastExpr);
-C_ASSERT(DxcCursor_CompoundLiteralExpr == CXCursor_CompoundLiteralExpr);
-C_ASSERT(DxcCursor_InitListExpr == CXCursor_InitListExpr);
-C_ASSERT(DxcCursor_AddrLabelExpr == CXCursor_AddrLabelExpr);
-C_ASSERT(DxcCursor_StmtExpr == CXCursor_StmtExpr);
-C_ASSERT(DxcCursor_GenericSelectionExpr == CXCursor_GenericSelectionExpr);
-C_ASSERT(DxcCursor_GNUNullExpr == CXCursor_GNUNullExpr);
-C_ASSERT(DxcCursor_CXXStaticCastExpr == CXCursor_CXXStaticCastExpr);
-C_ASSERT(DxcCursor_CXXDynamicCastExpr == CXCursor_CXXDynamicCastExpr);
-C_ASSERT(DxcCursor_CXXReinterpretCastExpr == CXCursor_CXXReinterpretCastExpr);
-C_ASSERT(DxcCursor_CXXConstCastExpr == CXCursor_CXXConstCastExpr);
-C_ASSERT(DxcCursor_CXXFunctionalCastExpr == CXCursor_CXXFunctionalCastExpr);
-C_ASSERT(DxcCursor_CXXTypeidExpr == CXCursor_CXXTypeidExpr);
-C_ASSERT(DxcCursor_CXXBoolLiteralExpr == CXCursor_CXXBoolLiteralExpr);
-C_ASSERT(DxcCursor_CXXNullPtrLiteralExpr == CXCursor_CXXNullPtrLiteralExpr);
-C_ASSERT(DxcCursor_CXXThisExpr == CXCursor_CXXThisExpr);
-C_ASSERT(DxcCursor_CXXThrowExpr == CXCursor_CXXThrowExpr);
-C_ASSERT(DxcCursor_CXXNewExpr == CXCursor_CXXNewExpr);
-C_ASSERT(DxcCursor_CXXDeleteExpr == CXCursor_CXXDeleteExpr);
-C_ASSERT(DxcCursor_UnaryExpr == CXCursor_UnaryExpr);
-C_ASSERT(DxcCursor_ObjCStringLiteral == CXCursor_ObjCStringLiteral);
-C_ASSERT(DxcCursor_ObjCEncodeExpr == CXCursor_ObjCEncodeExpr);
-C_ASSERT(DxcCursor_ObjCSelectorExpr == CXCursor_ObjCSelectorExpr);
-C_ASSERT(DxcCursor_ObjCProtocolExpr == CXCursor_ObjCProtocolExpr);
-C_ASSERT(DxcCursor_ObjCBridgedCastExpr == CXCursor_ObjCBridgedCastExpr);
-C_ASSERT(DxcCursor_PackExpansionExpr == CXCursor_PackExpansionExpr);
-C_ASSERT(DxcCursor_SizeOfPackExpr == CXCursor_SizeOfPackExpr);
-C_ASSERT(DxcCursor_LambdaExpr == CXCursor_LambdaExpr);
-C_ASSERT(DxcCursor_ObjCBoolLiteralExpr == CXCursor_ObjCBoolLiteralExpr);
-C_ASSERT(DxcCursor_ObjCSelfExpr == CXCursor_ObjCSelfExpr);
-C_ASSERT(DxcCursor_LastExpr == CXCursor_LastExpr);
-C_ASSERT(DxcCursor_FirstStmt == CXCursor_FirstStmt);
-C_ASSERT(DxcCursor_UnexposedStmt == CXCursor_UnexposedStmt);
-C_ASSERT(DxcCursor_LabelStmt == CXCursor_LabelStmt);
-C_ASSERT(DxcCursor_CompoundStmt == CXCursor_CompoundStmt);
-C_ASSERT(DxcCursor_CaseStmt == CXCursor_CaseStmt);
-C_ASSERT(DxcCursor_DefaultStmt == CXCursor_DefaultStmt);
-C_ASSERT(DxcCursor_IfStmt == CXCursor_IfStmt);
-C_ASSERT(DxcCursor_SwitchStmt == CXCursor_SwitchStmt);
-C_ASSERT(DxcCursor_WhileStmt == CXCursor_WhileStmt);
-C_ASSERT(DxcCursor_DoStmt == CXCursor_DoStmt);
-C_ASSERT(DxcCursor_ForStmt == CXCursor_ForStmt);
-C_ASSERT(DxcCursor_GotoStmt == CXCursor_GotoStmt);
-C_ASSERT(DxcCursor_IndirectGotoStmt == CXCursor_IndirectGotoStmt);
-C_ASSERT(DxcCursor_ContinueStmt == CXCursor_ContinueStmt);
-C_ASSERT(DxcCursor_BreakStmt == CXCursor_BreakStmt);
-C_ASSERT(DxcCursor_ReturnStmt == CXCursor_ReturnStmt);
-C_ASSERT(DxcCursor_GCCAsmStmt == CXCursor_GCCAsmStmt);
-C_ASSERT(DxcCursor_AsmStmt == CXCursor_AsmStmt);
-C_ASSERT(DxcCursor_ObjCAtTryStmt == CXCursor_ObjCAtTryStmt);
-C_ASSERT(DxcCursor_ObjCAtCatchStmt == CXCursor_ObjCAtCatchStmt);
-C_ASSERT(DxcCursor_ObjCAtFinallyStmt == CXCursor_ObjCAtFinallyStmt);
-C_ASSERT(DxcCursor_ObjCAtThrowStmt == CXCursor_ObjCAtThrowStmt);
-C_ASSERT(DxcCursor_ObjCAtSynchronizedStmt == CXCursor_ObjCAtSynchronizedStmt);
-C_ASSERT(DxcCursor_ObjCAutoreleasePoolStmt == CXCursor_ObjCAutoreleasePoolStmt);
-C_ASSERT(DxcCursor_ObjCForCollectionStmt == CXCursor_ObjCForCollectionStmt);
-C_ASSERT(DxcCursor_CXXCatchStmt == CXCursor_CXXCatchStmt);
-C_ASSERT(DxcCursor_CXXTryStmt == CXCursor_CXXTryStmt);
-C_ASSERT(DxcCursor_CXXForRangeStmt == CXCursor_CXXForRangeStmt);
-C_ASSERT(DxcCursor_SEHTryStmt == CXCursor_SEHTryStmt);
-C_ASSERT(DxcCursor_SEHExceptStmt == CXCursor_SEHExceptStmt);
-C_ASSERT(DxcCursor_SEHFinallyStmt == CXCursor_SEHFinallyStmt);
-C_ASSERT(DxcCursor_MSAsmStmt == CXCursor_MSAsmStmt);
-C_ASSERT(DxcCursor_NullStmt == CXCursor_NullStmt);
-C_ASSERT(DxcCursor_DeclStmt == CXCursor_DeclStmt);
-C_ASSERT(DxcCursor_OMPParallelDirective == CXCursor_OMPParallelDirective);
-C_ASSERT(DxcCursor_LastStmt == CXCursor_LastStmt);
-C_ASSERT(DxcCursor_TranslationUnit == CXCursor_TranslationUnit);
-C_ASSERT(DxcCursor_FirstAttr == CXCursor_FirstAttr);
-C_ASSERT(DxcCursor_UnexposedAttr == CXCursor_UnexposedAttr);
-C_ASSERT(DxcCursor_IBActionAttr == CXCursor_IBActionAttr);
-C_ASSERT(DxcCursor_IBOutletAttr == CXCursor_IBOutletAttr);
-C_ASSERT(DxcCursor_IBOutletCollectionAttr == CXCursor_IBOutletCollectionAttr);
-C_ASSERT(DxcCursor_CXXFinalAttr == CXCursor_CXXFinalAttr);
-C_ASSERT(DxcCursor_CXXOverrideAttr == CXCursor_CXXOverrideAttr);
-C_ASSERT(DxcCursor_AnnotateAttr == CXCursor_AnnotateAttr);
-C_ASSERT(DxcCursor_AsmLabelAttr == CXCursor_AsmLabelAttr);
-C_ASSERT(DxcCursor_PackedAttr == CXCursor_PackedAttr);
-C_ASSERT(DxcCursor_LastAttr == CXCursor_LastAttr);
-C_ASSERT(DxcCursor_PreprocessingDirective == CXCursor_PreprocessingDirective);
-C_ASSERT(DxcCursor_MacroDefinition == CXCursor_MacroDefinition);
-C_ASSERT(DxcCursor_MacroExpansion == CXCursor_MacroExpansion);
-C_ASSERT(DxcCursor_MacroInstantiation == CXCursor_MacroInstantiation);
-C_ASSERT(DxcCursor_InclusionDirective == CXCursor_InclusionDirective);
-C_ASSERT(DxcCursor_FirstPreprocessing == CXCursor_FirstPreprocessing);
-C_ASSERT(DxcCursor_LastPreprocessing == CXCursor_LastPreprocessing);
-C_ASSERT(DxcCursor_ModuleImportDecl == CXCursor_ModuleImportDecl);
-C_ASSERT(DxcCursor_FirstExtraDecl == CXCursor_FirstExtraDecl);
-C_ASSERT(DxcCursor_LastExtraDecl == CXCursor_LastExtraDecl);
-
-C_ASSERT(DxcTranslationUnitFlags_UseCallerThread == CXTranslationUnit_UseCallerThread);
+C_ASSERT((int)DxcCursor_UnexposedDecl == (int)CXCursor_UnexposedDecl);
+C_ASSERT((int)DxcCursor_StructDecl == (int)CXCursor_StructDecl);
+C_ASSERT((int)DxcCursor_UnionDecl == (int)CXCursor_UnionDecl);
+C_ASSERT((int)DxcCursor_ClassDecl == (int)CXCursor_ClassDecl);
+C_ASSERT((int)DxcCursor_EnumDecl == (int)CXCursor_EnumDecl);
+C_ASSERT((int)DxcCursor_FieldDecl == (int)CXCursor_FieldDecl);
+C_ASSERT((int)DxcCursor_EnumConstantDecl == (int)CXCursor_EnumConstantDecl);
+C_ASSERT((int)DxcCursor_FunctionDecl == (int)CXCursor_FunctionDecl);
+C_ASSERT((int)DxcCursor_VarDecl == (int)CXCursor_VarDecl);
+C_ASSERT((int)DxcCursor_ParmDecl == (int)CXCursor_ParmDecl);
+C_ASSERT((int)DxcCursor_ObjCInterfaceDecl == (int)CXCursor_ObjCInterfaceDecl);
+C_ASSERT((int)DxcCursor_ObjCCategoryDecl == (int)CXCursor_ObjCCategoryDecl);
+C_ASSERT((int)DxcCursor_ObjCProtocolDecl == (int)CXCursor_ObjCProtocolDecl);
+C_ASSERT((int)DxcCursor_ObjCPropertyDecl == (int)CXCursor_ObjCPropertyDecl);
+C_ASSERT((int)DxcCursor_ObjCIvarDecl == (int)CXCursor_ObjCIvarDecl);
+C_ASSERT((int)DxcCursor_ObjCInstanceMethodDecl == (int)CXCursor_ObjCInstanceMethodDecl);
+C_ASSERT((int)DxcCursor_ObjCClassMethodDecl == (int)CXCursor_ObjCClassMethodDecl);
+C_ASSERT((int)DxcCursor_ObjCImplementationDecl == (int)CXCursor_ObjCImplementationDecl);
+C_ASSERT((int)DxcCursor_ObjCCategoryImplDecl == (int)CXCursor_ObjCCategoryImplDecl);
+C_ASSERT((int)DxcCursor_TypedefDecl == (int)CXCursor_TypedefDecl);
+C_ASSERT((int)DxcCursor_CXXMethod == (int)CXCursor_CXXMethod);
+C_ASSERT((int)DxcCursor_Namespace == (int)CXCursor_Namespace);
+C_ASSERT((int)DxcCursor_LinkageSpec == (int)CXCursor_LinkageSpec);
+C_ASSERT((int)DxcCursor_Constructor == (int)CXCursor_Constructor);
+C_ASSERT((int)DxcCursor_Destructor == (int)CXCursor_Destructor);
+C_ASSERT((int)DxcCursor_ConversionFunction == (int)CXCursor_ConversionFunction);
+C_ASSERT((int)DxcCursor_TemplateTypeParameter == (int)CXCursor_TemplateTypeParameter);
+C_ASSERT((int)DxcCursor_NonTypeTemplateParameter == (int)CXCursor_NonTypeTemplateParameter);
+C_ASSERT((int)DxcCursor_TemplateTemplateParameter == (int)CXCursor_TemplateTemplateParameter);
+C_ASSERT((int)DxcCursor_FunctionTemplate == (int)CXCursor_FunctionTemplate);
+C_ASSERT((int)DxcCursor_ClassTemplate == (int)CXCursor_ClassTemplate);
+C_ASSERT((int)DxcCursor_ClassTemplatePartialSpecialization == (int)CXCursor_ClassTemplatePartialSpecialization);
+C_ASSERT((int)DxcCursor_NamespaceAlias == (int)CXCursor_NamespaceAlias);
+C_ASSERT((int)DxcCursor_UsingDirective == (int)CXCursor_UsingDirective);
+C_ASSERT((int)DxcCursor_UsingDeclaration == (int)CXCursor_UsingDeclaration);
+C_ASSERT((int)DxcCursor_TypeAliasDecl == (int)CXCursor_TypeAliasDecl);
+C_ASSERT((int)DxcCursor_ObjCSynthesizeDecl == (int)CXCursor_ObjCSynthesizeDecl);
+C_ASSERT((int)DxcCursor_ObjCDynamicDecl == (int)CXCursor_ObjCDynamicDecl);
+C_ASSERT((int)DxcCursor_CXXAccessSpecifier == (int)CXCursor_CXXAccessSpecifier);
+C_ASSERT((int)DxcCursor_FirstDecl == (int)CXCursor_FirstDecl);
+C_ASSERT((int)DxcCursor_LastDecl == (int)CXCursor_LastDecl);
+C_ASSERT((int)DxcCursor_FirstRef == (int)CXCursor_FirstRef);
+C_ASSERT((int)DxcCursor_ObjCSuperClassRef == (int)CXCursor_ObjCSuperClassRef);
+C_ASSERT((int)DxcCursor_ObjCProtocolRef == (int)CXCursor_ObjCProtocolRef);
+C_ASSERT((int)DxcCursor_ObjCClassRef == (int)CXCursor_ObjCClassRef);
+C_ASSERT((int)DxcCursor_TypeRef == (int)CXCursor_TypeRef);
+C_ASSERT((int)DxcCursor_CXXBaseSpecifier == (int)CXCursor_CXXBaseSpecifier);
+C_ASSERT((int)DxcCursor_TemplateRef == (int)CXCursor_TemplateRef);
+C_ASSERT((int)DxcCursor_NamespaceRef == (int)CXCursor_NamespaceRef);
+C_ASSERT((int)DxcCursor_MemberRef == (int)CXCursor_MemberRef);
+C_ASSERT((int)DxcCursor_LabelRef == (int)CXCursor_LabelRef);
+C_ASSERT((int)DxcCursor_OverloadedDeclRef == (int)CXCursor_OverloadedDeclRef);
+C_ASSERT((int)DxcCursor_VariableRef == (int)CXCursor_VariableRef);
+C_ASSERT((int)DxcCursor_LastRef == (int)CXCursor_LastRef);
+C_ASSERT((int)DxcCursor_FirstInvalid == (int)CXCursor_FirstInvalid);
+C_ASSERT((int)DxcCursor_InvalidFile == (int)CXCursor_InvalidFile);
+C_ASSERT((int)DxcCursor_NoDeclFound == (int)CXCursor_NoDeclFound);
+C_ASSERT((int)DxcCursor_NotImplemented == (int)CXCursor_NotImplemented);
+C_ASSERT((int)DxcCursor_InvalidCode == (int)CXCursor_InvalidCode);
+C_ASSERT((int)DxcCursor_LastInvalid == (int)CXCursor_LastInvalid);
+C_ASSERT((int)DxcCursor_FirstExpr == (int)CXCursor_FirstExpr);
+C_ASSERT((int)DxcCursor_UnexposedExpr == (int)CXCursor_UnexposedExpr);
+C_ASSERT((int)DxcCursor_DeclRefExpr == (int)CXCursor_DeclRefExpr);
+C_ASSERT((int)DxcCursor_MemberRefExpr == (int)CXCursor_MemberRefExpr);
+C_ASSERT((int)DxcCursor_CallExpr == (int)CXCursor_CallExpr);
+C_ASSERT((int)DxcCursor_ObjCMessageExpr == (int)CXCursor_ObjCMessageExpr);
+C_ASSERT((int)DxcCursor_BlockExpr == (int)CXCursor_BlockExpr);
+C_ASSERT((int)DxcCursor_IntegerLiteral == (int)CXCursor_IntegerLiteral);
+C_ASSERT((int)DxcCursor_FloatingLiteral == (int)CXCursor_FloatingLiteral);
+C_ASSERT((int)DxcCursor_ImaginaryLiteral == (int)CXCursor_ImaginaryLiteral);
+C_ASSERT((int)DxcCursor_StringLiteral == (int)CXCursor_StringLiteral);
+C_ASSERT((int)DxcCursor_CharacterLiteral == (int)CXCursor_CharacterLiteral);
+C_ASSERT((int)DxcCursor_ParenExpr == (int)CXCursor_ParenExpr);
+C_ASSERT((int)DxcCursor_UnaryOperator == (int)CXCursor_UnaryOperator);
+C_ASSERT((int)DxcCursor_ArraySubscriptExpr == (int)CXCursor_ArraySubscriptExpr);
+C_ASSERT((int)DxcCursor_BinaryOperator == (int)CXCursor_BinaryOperator);
+C_ASSERT((int)DxcCursor_CompoundAssignOperator == (int)CXCursor_CompoundAssignOperator);
+C_ASSERT((int)DxcCursor_ConditionalOperator == (int)CXCursor_ConditionalOperator);
+C_ASSERT((int)DxcCursor_CStyleCastExpr == (int)CXCursor_CStyleCastExpr);
+C_ASSERT((int)DxcCursor_CompoundLiteralExpr == (int)CXCursor_CompoundLiteralExpr);
+C_ASSERT((int)DxcCursor_InitListExpr == (int)CXCursor_InitListExpr);
+C_ASSERT((int)DxcCursor_AddrLabelExpr == (int)CXCursor_AddrLabelExpr);
+C_ASSERT((int)DxcCursor_StmtExpr == (int)CXCursor_StmtExpr);
+C_ASSERT((int)DxcCursor_GenericSelectionExpr == (int)CXCursor_GenericSelectionExpr);
+C_ASSERT((int)DxcCursor_GNUNullExpr == (int)CXCursor_GNUNullExpr);
+C_ASSERT((int)DxcCursor_CXXStaticCastExpr == (int)CXCursor_CXXStaticCastExpr);
+C_ASSERT((int)DxcCursor_CXXDynamicCastExpr == (int)CXCursor_CXXDynamicCastExpr);
+C_ASSERT((int)DxcCursor_CXXReinterpretCastExpr == (int)CXCursor_CXXReinterpretCastExpr);
+C_ASSERT((int)DxcCursor_CXXConstCastExpr == (int)CXCursor_CXXConstCastExpr);
+C_ASSERT((int)DxcCursor_CXXFunctionalCastExpr == (int)CXCursor_CXXFunctionalCastExpr);
+C_ASSERT((int)DxcCursor_CXXTypeidExpr == (int)CXCursor_CXXTypeidExpr);
+C_ASSERT((int)DxcCursor_CXXBoolLiteralExpr == (int)CXCursor_CXXBoolLiteralExpr);
+C_ASSERT((int)DxcCursor_CXXNullPtrLiteralExpr == (int)CXCursor_CXXNullPtrLiteralExpr);
+C_ASSERT((int)DxcCursor_CXXThisExpr == (int)CXCursor_CXXThisExpr);
+C_ASSERT((int)DxcCursor_CXXThrowExpr == (int)CXCursor_CXXThrowExpr);
+C_ASSERT((int)DxcCursor_CXXNewExpr == (int)CXCursor_CXXNewExpr);
+C_ASSERT((int)DxcCursor_CXXDeleteExpr == (int)CXCursor_CXXDeleteExpr);
+C_ASSERT((int)DxcCursor_UnaryExpr == (int)CXCursor_UnaryExpr);
+C_ASSERT((int)DxcCursor_ObjCStringLiteral == (int)CXCursor_ObjCStringLiteral);
+C_ASSERT((int)DxcCursor_ObjCEncodeExpr == (int)CXCursor_ObjCEncodeExpr);
+C_ASSERT((int)DxcCursor_ObjCSelectorExpr == (int)CXCursor_ObjCSelectorExpr);
+C_ASSERT((int)DxcCursor_ObjCProtocolExpr == (int)CXCursor_ObjCProtocolExpr);
+C_ASSERT((int)DxcCursor_ObjCBridgedCastExpr == (int)CXCursor_ObjCBridgedCastExpr);
+C_ASSERT((int)DxcCursor_PackExpansionExpr == (int)CXCursor_PackExpansionExpr);
+C_ASSERT((int)DxcCursor_SizeOfPackExpr == (int)CXCursor_SizeOfPackExpr);
+C_ASSERT((int)DxcCursor_LambdaExpr == (int)CXCursor_LambdaExpr);
+C_ASSERT((int)DxcCursor_ObjCBoolLiteralExpr == (int)CXCursor_ObjCBoolLiteralExpr);
+C_ASSERT((int)DxcCursor_ObjCSelfExpr == (int)CXCursor_ObjCSelfExpr);
+C_ASSERT((int)DxcCursor_LastExpr == (int)CXCursor_LastExpr);
+C_ASSERT((int)DxcCursor_FirstStmt == (int)CXCursor_FirstStmt);
+C_ASSERT((int)DxcCursor_UnexposedStmt == (int)CXCursor_UnexposedStmt);
+C_ASSERT((int)DxcCursor_LabelStmt == (int)CXCursor_LabelStmt);
+C_ASSERT((int)DxcCursor_CompoundStmt == (int)CXCursor_CompoundStmt);
+C_ASSERT((int)DxcCursor_CaseStmt == (int)CXCursor_CaseStmt);
+C_ASSERT((int)DxcCursor_DefaultStmt == (int)CXCursor_DefaultStmt);
+C_ASSERT((int)DxcCursor_IfStmt == (int)CXCursor_IfStmt);
+C_ASSERT((int)DxcCursor_SwitchStmt == (int)CXCursor_SwitchStmt);
+C_ASSERT((int)DxcCursor_WhileStmt == (int)CXCursor_WhileStmt);
+C_ASSERT((int)DxcCursor_DoStmt == (int)CXCursor_DoStmt);
+C_ASSERT((int)DxcCursor_ForStmt == (int)CXCursor_ForStmt);
+C_ASSERT((int)DxcCursor_GotoStmt == (int)CXCursor_GotoStmt);
+C_ASSERT((int)DxcCursor_IndirectGotoStmt == (int)CXCursor_IndirectGotoStmt);
+C_ASSERT((int)DxcCursor_ContinueStmt == (int)CXCursor_ContinueStmt);
+C_ASSERT((int)DxcCursor_BreakStmt == (int)CXCursor_BreakStmt);
+C_ASSERT((int)DxcCursor_ReturnStmt == (int)CXCursor_ReturnStmt);
+C_ASSERT((int)DxcCursor_GCCAsmStmt == (int)CXCursor_GCCAsmStmt);
+C_ASSERT((int)DxcCursor_AsmStmt == (int)CXCursor_AsmStmt);
+C_ASSERT((int)DxcCursor_ObjCAtTryStmt == (int)CXCursor_ObjCAtTryStmt);
+C_ASSERT((int)DxcCursor_ObjCAtCatchStmt == (int)CXCursor_ObjCAtCatchStmt);
+C_ASSERT((int)DxcCursor_ObjCAtFinallyStmt == (int)CXCursor_ObjCAtFinallyStmt);
+C_ASSERT((int)DxcCursor_ObjCAtThrowStmt == (int)CXCursor_ObjCAtThrowStmt);
+C_ASSERT((int)DxcCursor_ObjCAtSynchronizedStmt == (int)CXCursor_ObjCAtSynchronizedStmt);
+C_ASSERT((int)DxcCursor_ObjCAutoreleasePoolStmt == (int)CXCursor_ObjCAutoreleasePoolStmt);
+C_ASSERT((int)DxcCursor_ObjCForCollectionStmt == (int)CXCursor_ObjCForCollectionStmt);
+C_ASSERT((int)DxcCursor_CXXCatchStmt == (int)CXCursor_CXXCatchStmt);
+C_ASSERT((int)DxcCursor_CXXTryStmt == (int)CXCursor_CXXTryStmt);
+C_ASSERT((int)DxcCursor_CXXForRangeStmt == (int)CXCursor_CXXForRangeStmt);
+C_ASSERT((int)DxcCursor_SEHTryStmt == (int)CXCursor_SEHTryStmt);
+C_ASSERT((int)DxcCursor_SEHExceptStmt == (int)CXCursor_SEHExceptStmt);
+C_ASSERT((int)DxcCursor_SEHFinallyStmt == (int)CXCursor_SEHFinallyStmt);
+C_ASSERT((int)DxcCursor_MSAsmStmt == (int)CXCursor_MSAsmStmt);
+C_ASSERT((int)DxcCursor_NullStmt == (int)CXCursor_NullStmt);
+C_ASSERT((int)DxcCursor_DeclStmt == (int)CXCursor_DeclStmt);
+C_ASSERT((int)DxcCursor_OMPParallelDirective == (int)CXCursor_OMPParallelDirective);
+C_ASSERT((int)DxcCursor_LastStmt == (int)CXCursor_LastStmt);
+C_ASSERT((int)DxcCursor_TranslationUnit == (int)CXCursor_TranslationUnit);
+C_ASSERT((int)DxcCursor_FirstAttr == (int)CXCursor_FirstAttr);
+C_ASSERT((int)DxcCursor_UnexposedAttr == (int)CXCursor_UnexposedAttr);
+C_ASSERT((int)DxcCursor_IBActionAttr == (int)CXCursor_IBActionAttr);
+C_ASSERT((int)DxcCursor_IBOutletAttr == (int)CXCursor_IBOutletAttr);
+C_ASSERT((int)DxcCursor_IBOutletCollectionAttr == (int)CXCursor_IBOutletCollectionAttr);
+C_ASSERT((int)DxcCursor_CXXFinalAttr == (int)CXCursor_CXXFinalAttr);
+C_ASSERT((int)DxcCursor_CXXOverrideAttr == (int)CXCursor_CXXOverrideAttr);
+C_ASSERT((int)DxcCursor_AnnotateAttr == (int)CXCursor_AnnotateAttr);
+C_ASSERT((int)DxcCursor_AsmLabelAttr == (int)CXCursor_AsmLabelAttr);
+C_ASSERT((int)DxcCursor_PackedAttr == (int)CXCursor_PackedAttr);
+C_ASSERT((int)DxcCursor_LastAttr == (int)CXCursor_LastAttr);
+C_ASSERT((int)DxcCursor_PreprocessingDirective == (int)CXCursor_PreprocessingDirective);
+C_ASSERT((int)DxcCursor_MacroDefinition == (int)CXCursor_MacroDefinition);
+C_ASSERT((int)DxcCursor_MacroExpansion == (int)CXCursor_MacroExpansion);
+C_ASSERT((int)DxcCursor_MacroInstantiation == (int)CXCursor_MacroInstantiation);
+C_ASSERT((int)DxcCursor_InclusionDirective == (int)CXCursor_InclusionDirective);
+C_ASSERT((int)DxcCursor_FirstPreprocessing == (int)CXCursor_FirstPreprocessing);
+C_ASSERT((int)DxcCursor_LastPreprocessing == (int)CXCursor_LastPreprocessing);
+C_ASSERT((int)DxcCursor_ModuleImportDecl == (int)CXCursor_ModuleImportDecl);
+C_ASSERT((int)DxcCursor_FirstExtraDecl == (int)CXCursor_FirstExtraDecl);
+C_ASSERT((int)DxcCursor_LastExtraDecl == (int)CXCursor_LastExtraDecl);
+
+C_ASSERT((int)DxcTranslationUnitFlags_UseCallerThread == (int)CXTranslationUnit_UseCallerThread);

+ 12 - 12
tools/clang/tools/libclang/dxcisenseimpl.h

@@ -37,7 +37,7 @@ private:
   CXCursor m_cursor;
 public:
   DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL()
-  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject)
+  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject) override
   {
     return DoBasicQueryInterface<IDxcCursor>(this, iid, ppvObject);
   }
@@ -86,7 +86,7 @@ private:
   CXDiagnostic m_diagnostic;
 public:
   DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL()
-  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject)
+  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject) override
   {
     return DoBasicQueryInterface<IDxcDiagnostic>(this, iid, ppvObject);
   }
@@ -117,7 +117,7 @@ private:
   CXFile m_file;
 public:
   DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL()
-  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject)
+  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject) override
   {
     return DoBasicQueryInterface<IDxcFile>(this, iid, ppvObject);
   }
@@ -142,7 +142,7 @@ private:
   unsigned m_locationLength;
 public:
   DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL()
-  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject)
+  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject) override
   {
     return DoBasicQueryInterface<IDxcInclusion>(this, iid, ppvObject);
   }
@@ -166,7 +166,7 @@ private:
     hlsl::DxcLangExtensionsHelper m_langHelper;
 public:
     DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL()
-    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject)
+    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject) override
     {
       return DoBasicQueryInterface<IDxcIndex>(this, iid, ppvObject);
     }
@@ -190,14 +190,14 @@ public:
 
 class DxcIntelliSense : public IDxcIntelliSense, public IDxcLangExtensions {
 private:
-  DXC_MICROCOM_TM_REF_FIELDS();
+  DXC_MICROCOM_TM_REF_FIELDS()
   hlsl::DxcLangExtensionsHelper m_langHelper;
 
 public:
   DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL();
   DXC_LANGEXTENSIONS_HELPER_IMPL(m_langHelper);
 
-  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject) {
+  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject) override {
     return DoBasicQueryInterface<IDxcIntelliSense, IDxcLangExtensions>(
         this, iid, ppvObject);
   }
@@ -226,7 +226,7 @@ private:
   CXSourceLocation m_location;
 public:
   DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL()
-  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject)
+  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject) override
   {
     return DoBasicQueryInterface<IDxcSourceLocation>(this, iid, ppvObject);
   }
@@ -253,7 +253,7 @@ private:
   CXSourceRange m_range;
 public:
   DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL()
-  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject)
+  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject) override
   {
     return DoBasicQueryInterface<IDxcSourceRange>(this, iid, ppvObject);
   }
@@ -278,7 +278,7 @@ private:
   CXTranslationUnit m_tu;
 public:
   DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL()
-  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject)
+  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject) override
   {
     return DoBasicQueryInterface<IDxcToken>(this, iid, ppvObject);
   }
@@ -301,7 +301,7 @@ private:
     CXTranslationUnit m_tu;
 public:
     DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL()
-    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject)
+    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject) override
     {
       return DoBasicQueryInterface<IDxcTranslationUnit>(this, iid, ppvObject);
     }
@@ -347,7 +347,7 @@ private:
   CXType m_type;
 public:
   DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL()
-  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject)
+  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject) override
   {
     return DoBasicQueryInterface<IDxcType>(this, iid, ppvObject);
   }

+ 20 - 8
tools/clang/unittests/HLSL/AllocatorTest.cpp

@@ -9,7 +9,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "dxc/Support/WinIncludes.h"
+#ifdef _WIN32
 #include "WexTestClass.h"
+#endif
 #include "HlslTestUtils.h"
 
 #include "dxc/HLSL/DxilSpanAllocator.h"
@@ -318,7 +320,8 @@ struct Scenario {
     }
     //   one = two = random
     if (maxIdx > 2) {
-      unsigned one = std::min(1 + (randGen() % (maxIdx - 2)), maxIdx);
+      unsigned randIdx = 1 + (randGen() % (maxIdx - 2));
+      unsigned one = std::min(randIdx, maxIdx);
       pairs.insert(Test(one, one));
     }
     //   one = two = last - 1
@@ -343,18 +346,22 @@ struct Scenario {
     }
     //   one = first, two = random
     if (maxIdx > 3) {
-      unsigned two = std::min(1 + (randGen() % (maxIdx - 2)), maxIdx);
+      unsigned randIdx = 1 + (randGen() % (maxIdx - 2));
+      unsigned two = std::min(randIdx, maxIdx);
       pairs.insert(Test(0, two));
     }
     //   one = random, two = random
     if (maxIdx > 4) {
-      unsigned one = std::min(1 + (randGen() % (maxIdx - 3)), maxIdx);
-      unsigned two = std::min(one + 1 + (randGen() % (maxIdx - (one + 1))), maxIdx);
+      unsigned randIdx = 1 + (randGen() % (maxIdx - 3));
+      unsigned one = std::min(randIdx, maxIdx);
+      randIdx = one + 1 + (randGen() % (maxIdx - (one + 1)));
+      unsigned two = std::min(randIdx, maxIdx);
       pairs.insert(Test(one, two));
     }
     //   one = random, two = last
     if (maxIdx > 3) {
-      unsigned one = std::min(1 + (randGen() % (maxIdx - 2)), maxIdx);
+      unsigned randIdx = 1 + (randGen() % (maxIdx - 2));
+      unsigned one = std::min(randIdx, maxIdx);
       pairs.insert(Test(one, maxIdx));
     }
     //   one = second, two = last-1
@@ -522,7 +529,12 @@ struct Scenario {
 };
 
 // The test fixture.
+#ifdef _WIN32
 class AllocatorTest {
+#else
+class AllocatorTest : public ::testing::Test {
+protected:
+#endif
   std::vector<Scenario> m_Scenarios;
 public:
   BEGIN_TEST_CLASS(AllocatorTest)
@@ -532,9 +544,9 @@ public:
 
   TEST_CLASS_SETUP(AllocatorTestSetup);
 
-  TEST_METHOD(Intersections);
-  TEST_METHOD(GapFilling);
-  TEST_METHOD(Allocate);
+  TEST_METHOD(Intersections)
+  TEST_METHOD(GapFilling)
+  TEST_METHOD(Allocate)
 
   void InitScenarios() {
     struct P {

+ 18 - 6
tools/clang/unittests/HLSL/CMakeLists.txt

@@ -6,6 +6,7 @@ find_package(DiaSDK REQUIRED) # Used for constants and declarations.
 find_package(D3D12 REQUIRED) # Used for ExecutionTest.cpp.
 ENDif(WIN32)
 
+if(WIN32)
 set( LLVM_LINK_COMPONENTS
   support
   mssupport
@@ -19,7 +20,6 @@ set( LLVM_LINK_COMPONENTS
   irreader
   )
 
-if(WIN32)
 set(HLSL_IGNORE_SOURCES
   TestMain.cpp
   HLSLTestOptions.cpp
@@ -28,6 +28,7 @@ add_clang_library(clang-hlsl-tests SHARED
   AllocatorTest.cpp
   CompilationResult.h
   CompilerTest.cpp
+  DxcTestUtils.cpp
   DxilContainerTest.cpp
   DxilModuleTest.cpp
   DXIsenseTest.cpp
@@ -52,12 +53,16 @@ add_clang_library(clang-hlsl-tests SHARED
   clang-hlsl-tests.rc
   )
 else (WIN32)
+set( LLVM_LINK_COMPONENTS
+  support
+  mssupport
+  dxcsupport
+  )
+
 set(HLSL_IGNORE_SOURCES
-  AllocatorTest.cpp
   CompilerTest.cpp
   DxilContainerTest.cpp
   DxilModuleTest.cpp
-  DXIsenseTest.cpp
   ExecutionTest.cpp
   ExtensionTest.cpp
   FileCheckerTest.cpp
@@ -65,19 +70,22 @@ set(HLSL_IGNORE_SOURCES
   FunctionTest.cpp
   LinkerTest.cpp
   MSFileSysTest.cpp
-  Objects.cpp
   OptimizerTest.cpp
   OptionsTest.cpp
   RewriterTest.cpp
   ShaderOpTest.cpp
   SystemValueTest.cpp
   ValidationTest.cpp
-  VerifierTest.cpp
   )
 
 add_clang_unittest(clang-hlsl-tests
-  TestMain.cpp
+  AllocatorTest.cpp
+  DxcTestUtils.cpp
+  DXIsenseTest.cpp
   HLSLTestOptions.cpp
+  Objects.cpp
+  TestMain.cpp
+  VerifierTest.cpp
   )
 
 endif(WIN32)
@@ -123,3 +131,7 @@ file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" DOS_STYLE_SOURCE_DIR)
 file(TO_NATIVE_PATH "${TAEF_BIN_DIR}" DOS_TAEF_BIN_DIR)
 configure_file(clang-hlsl-tests.vcxproj.user.txt clang-hlsl-tests.vcxproj.user)
 endif(WIN32)
+
+add_test(NAME test-hlsl-codegen
+  COMMAND clang-hlsl-tests --HlslDataDir
+          ${PROJECT_SOURCE_DIR}/tools/clang/test/HLSL)

+ 3 - 168
tools/clang/unittests/HLSL/CompilerTest.cpp

@@ -48,172 +48,6 @@
 using namespace std;
 using namespace hlsl_test;
 
-void AssembleToContainer(dxc::DxcDllSupport &dllSupport, IDxcBlob *pModule, IDxcBlob **pContainer) {
-  CComPtr<IDxcAssembler> pAssembler;
-  CComPtr<IDxcOperationResult> pResult;
-  VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcAssembler, &pAssembler));
-  VERIFY_SUCCEEDED(pAssembler->AssembleToContainer(pModule, &pResult));
-  CheckOperationSucceeded(pResult, pContainer);
-}
-
-std::wstring BlobToUtf16(_In_ IDxcBlob *pBlob) {
-  CComPtr<IDxcBlobEncoding> pBlobEncoding;
-  const UINT CP_UTF16 = 1200;
-  IFT(pBlob->QueryInterface(&pBlobEncoding));
-  BOOL known;
-  UINT32 codePage;
-  IFT(pBlobEncoding->GetEncoding(&known, &codePage));
-  std::wstring result;
-  if (codePage == CP_UTF16) {
-    result.resize(pBlob->GetBufferSize() + 1);
-    memcpy((void *)result.data(), pBlob->GetBufferPointer(),
-           pBlob->GetBufferSize());
-    return result;
-  } else if (codePage == CP_UTF8) {
-    Unicode::UTF8ToUTF16String((char *)pBlob->GetBufferPointer(),
-                               pBlob->GetBufferSize(), &result);
-    return result;
-  } else {
-    throw std::exception("Unsupported codepage.");
-  }
-}
-
-void GetDxilPart(dxc::DxcDllSupport &dllSupport, IDxcBlob *pProgram, IDxcBlob **pDxilPart) {
-  const UINT32 DxilPartKind = 'LIXD'; // DXIL
-  UINT32 DxilIndex;
-  CComPtr<IDxcContainerReflection> pContainerReflection;
-  VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcContainerReflection, &pContainerReflection));
-  VERIFY_SUCCEEDED(pContainerReflection->Load(pProgram));
-  VERIFY_SUCCEEDED(pContainerReflection->FindFirstPartKind(DxilPartKind, &DxilIndex));
-  VERIFY_SUCCEEDED(pContainerReflection->GetPartContent(DxilIndex, pDxilPart));
-}
-
-void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const char *pVal, _Outptr_ IDxcBlobEncoding **ppBlob) {
-  CComPtr<IDxcLibrary> library;
-  IFT(dllSupport.CreateInstance(CLSID_DxcLibrary, &library));
-  IFT(library->CreateBlobWithEncodingOnHeapCopy(pVal, strlen(pVal), CP_UTF8, ppBlob));
-}
-
-void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, _Outptr_ IDxcBlobEncoding **ppBlob) {
-  CComPtr<IDxcLibrary> library;
-  IFT(dllSupport.CreateInstance(CLSID_DxcLibrary, &library));
-  IFT(library->CreateBlobWithEncodingOnHeapCopy(val.data(), val.size(), CP_UTF8, ppBlob));
-}
-
-void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, _Outptr_ IDxcBlob **ppBlob) {
-  Utf8ToBlob(dllSupport, val, (IDxcBlobEncoding**)ppBlob);
-}
-
-void Utf16ToBlob(dxc::DxcDllSupport &dllSupport, const std::wstring &val, _Outptr_ IDxcBlobEncoding **ppBlob) {
-  const UINT32 CP_UTF16 = 1200;
-  CComPtr<IDxcLibrary> library;
-  IFT(dllSupport.CreateInstance(CLSID_DxcLibrary, &library));
-  IFT(library->CreateBlobWithEncodingOnHeapCopy(val.data(), val.size() * sizeof(wchar_t), CP_UTF16, ppBlob));
-}
-
-void Utf16ToBlob(dxc::DxcDllSupport &dllSupport, const std::wstring &val, _Outptr_ IDxcBlob **ppBlob) {
-  Utf16ToBlob(dllSupport, val, (IDxcBlobEncoding**)ppBlob);
-}
-
-void VerifyCompileOK(dxc::DxcDllSupport &dllSupport, LPCSTR pText,
-                     LPWSTR pTargetProfile, LPCWSTR pArgs,
-                     _Outptr_ IDxcBlob **ppResult) {
-  std::vector<std::wstring> argsW;
-  std::vector<LPCWSTR> args;
-  if (pArgs) {
-    wistringstream argsS(pArgs);
-    copy(istream_iterator<wstring, wchar_t>(argsS),
-         istream_iterator<wstring, wchar_t>(), back_inserter(argsW));
-    transform(argsW.begin(), argsW.end(), back_inserter(args),
-              [](const wstring &w) { return w.data(); });
-  }
-  VerifyCompileOK(dllSupport, pText, pTargetProfile, args, ppResult);
-}
-
-void VerifyCompileOK(dxc::DxcDllSupport &dllSupport, LPCSTR pText,
-  LPWSTR pTargetProfile, std::vector<LPCWSTR> &args,
-  _Outptr_ IDxcBlob **ppResult) {
-  CComPtr<IDxcCompiler> pCompiler;
-  CComPtr<IDxcBlobEncoding> pSource;
-  CComPtr<IDxcOperationResult> pResult;
-  HRESULT hrCompile;
-  *ppResult = nullptr;
-  VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
-  Utf8ToBlob(dllSupport, pText, &pSource);
-  VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"source.hlsl", L"main",
-    pTargetProfile, args.data(), args.size(),
-    nullptr, 0, nullptr, &pResult));
-  VERIFY_SUCCEEDED(pResult->GetStatus(&hrCompile));
-  VERIFY_SUCCEEDED(hrCompile);
-  VERIFY_SUCCEEDED(pResult->GetResult(ppResult));
-}
-
-
-// VersionSupportInfo Implementation
-VersionSupportInfo::VersionSupportInfo() :
-  m_CompilerIsDebugBuild(false),
-  m_InternalValidator(false),
-  m_DxilMajor(0),
-  m_DxilMinor(0),
-  m_ValMajor(0),
-  m_ValMinor(0)
-{}
-
-void VersionSupportInfo::Initialize(dxc::DxcDllSupport &dllSupport) {
-  VERIFY_IS_TRUE(dllSupport.IsEnabled());
-
-  // Default to Dxil 1.0 and internal Val 1.0
-  m_DxilMajor = m_ValMajor = 1;
-  m_DxilMinor = m_ValMinor = 0;
-  m_InternalValidator = true;
-  CComPtr<IDxcVersionInfo> pVersionInfo;
-  UINT32 VersionFlags = 0;
-
-  // If the following fails, we have Dxil 1.0 compiler
-  if (SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcCompiler, &pVersionInfo))) {
-    VERIFY_SUCCEEDED(pVersionInfo->GetVersion(&m_DxilMajor, &m_DxilMinor));
-    VERIFY_SUCCEEDED(pVersionInfo->GetFlags(&VersionFlags));
-    m_CompilerIsDebugBuild = (VersionFlags & DxcVersionInfoFlags_Debug) ? true : false;
-    pVersionInfo.Release();
-  }
-
-  if (SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcValidator, &pVersionInfo))) {
-    VERIFY_SUCCEEDED(pVersionInfo->GetVersion(&m_ValMajor, &m_ValMinor));
-    VERIFY_SUCCEEDED(pVersionInfo->GetFlags(&VersionFlags));
-    if (m_ValMinor > 0) {
-      // flag only exists on newer validator, assume internal otherwise.
-      m_InternalValidator = (VersionFlags & DxcVersionInfoFlags_Internal) ? true : false;
-    } else {
-      // With old compiler, validator is the only way to get this
-      m_CompilerIsDebugBuild = (VersionFlags & DxcVersionInfoFlags_Debug) ? true : false;
-    }
-  } else {
-    // If create instance of IDxcVersionInfo on validator failed, we have an old validator from dxil.dll
-    m_InternalValidator = false;
-  }
-}
-bool VersionSupportInfo::SkipIRSensitiveTest() {
-  // Only debug builds preserve BB names.
-  if (!m_CompilerIsDebugBuild) {
-    WEX::Logging::Log::Comment(L"Test skipped due to name preservation requirement.");
-    return true;
-  }
-  return false;
-}
-bool VersionSupportInfo::SkipDxilVersion(unsigned major, unsigned minor) {
-  if (m_DxilMajor < major || (m_DxilMajor == major && m_DxilMinor < minor) ||
-      m_ValMajor < major || (m_ValMajor == major && m_ValMinor < minor)) {
-    WEX::Logging::Log::Comment(WEX::Common::String().Format(
-        L"Test skipped because it requires Dxil %u.%u and Validator %u.%u.",
-        major, minor, major, minor));
-    return true;
-  }
-  return false;
-}
-bool VersionSupportInfo::SkipOutOfMemoryTest() {
-  return false;
-}
-
 // Aligned to SymTagEnum.
 const char *SymTagEnumText[] =
 {
@@ -843,7 +677,7 @@ public:
   TEST_METHOD(CodeGenUnusedFunc)
   TEST_METHOD(CodeGenUnusedCB)
   TEST_METHOD(CodeGenUpdateCounter)
-  TEST_METHOD(CodeGenUpperCaseRegister1);
+  TEST_METHOD(CodeGenUpperCaseRegister1)
   TEST_METHOD(CodeGenVcmp)
   TEST_METHOD(CodeGenVecBitCast)
   TEST_METHOD(CodeGenVec_Comp_Arg)
@@ -2547,7 +2381,8 @@ TEST_F(CompilerTest, CompileWhenODumpThenOptimizerMatch) {
                                               nullptr));
 
     string text = DisassembleProgram(m_dllSupport, pOptimizedModule);
-    LogCommentFmt(L"Final program:\r\n%S", text.c_str());
+    WEX::Logging::Log::Comment(L"Final program:");
+    WEX::Logging::Log::Comment(CA2W(text.c_str()));
 
     // At the very least, the module should be valid.
     pResult.Release();

+ 59 - 54
tools/clang/unittests/HLSL/DXIsenseTest.cpp

@@ -13,12 +13,19 @@
 #include "HLSLTestData.h"
 #include <stdint.h>
 
+#ifdef _WIN32
 #include "WexTestClass.h"
+#endif
 #include "HlslTestUtils.h"
 #include "dxc/Support/microcom.h"
 
-class DXIntellisenseTest
-{
+
+#ifdef _WIN32
+class DXIntellisenseTest {
+#else
+typedef BSTR CComBSTR;
+class DXIntellisenseTest : public ::testing::Test {
+#endif
 public:
   BEGIN_TEST_CLASS(DXIntellisenseTest)
     TEST_CLASS_PROPERTY(L"Parallel", L"true")
@@ -26,8 +33,8 @@ public:
   END_TEST_CLASS()
 
 protected:
-  TEST_CLASS_SETUP(DXIntellisenseTestClassSetup);
-  TEST_CLASS_CLEANUP(DXIntellisenseTestClassCleanup);
+  TEST_CLASS_SETUP(DXIntellisenseTestClassSetup)
+  TEST_CLASS_CLEANUP(DXIntellisenseTestClassCleanup)
 
   void GetLocationAt(IDxcTranslationUnit* TU, unsigned line, unsigned col, IDxcSourceLocation** pResult)
   {
@@ -77,46 +84,44 @@ protected:
     EXPECT_STREQW(expectedDecl, name);// << "declaration text at " << line << ":" << col;
   }
 
-  TEST_METHOD(CursorWhenCBufferRefThenFound);
-  TEST_METHOD(CursorWhenFieldRefThenSimpleNames);
-  TEST_METHOD(CursorWhenFindAtBodyCallThenMatch);
-  TEST_METHOD(CursorWhenFindAtGlobalThenMatch);
-  TEST_METHOD(CursorWhenFindBeforeBodyCallThenMatch);
-  TEST_METHOD(CursorWhenFindBeforeGlobalThenMatch);
-  TEST_METHOD(CursorWhenFunctionThenParamsAvailable);
-  TEST_METHOD(CursorWhenFunctionThenReturnTypeAvailable);
-  TEST_METHOD(CursorWhenFunctionThenSignatureAvailable);
-  TEST_METHOD(CursorWhenGlobalVariableThenSimpleNames);
-  TEST_METHOD(CursorWhenOverloadedIncompleteThenInvisible);
-  TEST_METHOD(CursorWhenOverloadedResolvedThenDirectSymbol);
-  TEST_METHOD(CursorWhenReferenceThenDefinitionAvailable);
-  TEST_METHOD(CursorWhenTypeOfVariableDeclThenNamesHaveType);
-  TEST_METHOD(CursorWhenVariableRefThenSimpleNames);
-  TEST_METHOD(CursorWhenVariableUsedThenDeclarationAvailable);
-
-  TEST_METHOD(FileWhenSameThenEqual);
-  TEST_METHOD(FileWhenNotSameThenNotEqual);
-
-  TEST_METHOD(InclusionWhenMissingThenError);
-  TEST_METHOD(InclusionWhenValidThenAvailable);
-
-  TEST_METHOD(TUWhenGetFileMissingThenFail);
-  TEST_METHOD(TUWhenGetFilePresentThenOK);
-  TEST_METHOD(TUWhenEmptyStructThenErrorIfISense);
-  TEST_METHOD(TUWhenRegionInactiveMissingThenCountIsZero);
-  TEST_METHOD(TUWhenRegionInactiveThenEndIsBeforeElseHash);
-  TEST_METHOD(TUWhenRegionInactiveThenEndIsBeforeEndifHash);
-  TEST_METHOD(TUWhenRegionInactiveThenStartIsAtIfdefEol);
-  TEST_METHOD(TUWhenUnsaveFileThenOK);
-
-  TEST_METHOD(QualifiedNameClass);
-  TEST_METHOD(QualifiedNameVariable);
-
-  TEST_METHOD(TypeWhenICEThenEval);
+  TEST_METHOD(CursorWhenCBufferRefThenFound)
+  TEST_METHOD(CursorWhenFieldRefThenSimpleNames)
+  TEST_METHOD(CursorWhenFindAtBodyCallThenMatch)
+  TEST_METHOD(CursorWhenFindAtGlobalThenMatch)
+  TEST_METHOD(CursorWhenFindBeforeBodyCallThenMatch)
+  TEST_METHOD(CursorWhenFindBeforeGlobalThenMatch)
+  TEST_METHOD(CursorWhenFunctionThenParamsAvailable)
+  TEST_METHOD(CursorWhenFunctionThenReturnTypeAvailable)
+  TEST_METHOD(CursorWhenFunctionThenSignatureAvailable)
+  TEST_METHOD(CursorWhenGlobalVariableThenSimpleNames)
+  TEST_METHOD(CursorWhenOverloadedIncompleteThenInvisible)
+  TEST_METHOD(CursorWhenOverloadedResolvedThenDirectSymbol)
+  TEST_METHOD(CursorWhenReferenceThenDefinitionAvailable)
+  TEST_METHOD(CursorWhenTypeOfVariableDeclThenNamesHaveType)
+  TEST_METHOD(CursorWhenVariableRefThenSimpleNames)
+  TEST_METHOD(CursorWhenVariableUsedThenDeclarationAvailable)
+
+  TEST_METHOD(FileWhenSameThenEqual)
+  TEST_METHOD(FileWhenNotSameThenNotEqual)
+
+  TEST_METHOD(InclusionWhenMissingThenError)
+  TEST_METHOD(InclusionWhenValidThenAvailable)
+
+  TEST_METHOD(TUWhenGetFileMissingThenFail)
+  TEST_METHOD(TUWhenGetFilePresentThenOK)
+  TEST_METHOD(TUWhenEmptyStructThenErrorIfISense)
+  TEST_METHOD(TUWhenRegionInactiveMissingThenCountIsZero)
+  TEST_METHOD(TUWhenRegionInactiveThenEndIsBeforeElseHash)
+  TEST_METHOD(TUWhenRegionInactiveThenEndIsBeforeEndifHash)
+  TEST_METHOD(TUWhenRegionInactiveThenStartIsAtIfdefEol)
+  TEST_METHOD(TUWhenUnsaveFileThenOK)
+
+  TEST_METHOD(QualifiedNameClass)
+  TEST_METHOD(QualifiedNameVariable)
+
+  TEST_METHOD(TypeWhenICEThenEval)
 };
 
-std::shared_ptr<HlslIntellisenseSupport> CompilationResult::DefaultHlslSupport;
-
 bool DXIntellisenseTest::DXIntellisenseTestClassSetup() {
   std::shared_ptr<HlslIntellisenseSupport> result = std::make_shared<HlslIntellisenseSupport>();
   if (FAILED(result->Initialize()))
@@ -581,7 +586,7 @@ TEST_F(DXIntellisenseTest, CursorWhenVariableUsedThenDeclarationAvailable) {
 
   CComBSTR name;
   ASSERT_HRESULT_SUCCEEDED(referenced->GetFormattedName(DxcCursorFormatting_Default, &name));
-  EXPECT_STREQW(L"i", name);
+  EXPECT_STREQW(L"i", (LPWSTR)name);
 }
 
 // TODO: get a referenced local variable as 'int localVar';
@@ -592,7 +597,7 @@ TEST_F(DXIntellisenseTest, CursorWhenVariableUsedThenDeclarationAvailable) {
 // TODO: code completion for a built-in function
 // TODO: code completion for a built-in method
 
-void DXIntellisenseTest::CursorWhenFunctionThenSignatureAvailable()
+TEST_F(DXIntellisenseTest, CursorWhenFunctionThenSignatureAvailable)
 {
   char program[] =
     "int myfunc(int a, float b) { return a + b; }\r\n"
@@ -606,7 +611,7 @@ void DXIntellisenseTest::CursorWhenFunctionThenSignatureAvailable()
   // TODO - how to get signature?
 }
 
-void DXIntellisenseTest::CursorWhenFunctionThenParamsAvailable()
+TEST_F(DXIntellisenseTest, CursorWhenFunctionThenParamsAvailable)
 {
   char program[] =
     "int myfunc(int a, float b) { return a + b; }\r\n"
@@ -625,7 +630,7 @@ void DXIntellisenseTest::CursorWhenFunctionThenParamsAvailable()
   // TODO - how to get signature?
 }
 
-void DXIntellisenseTest::CursorWhenFunctionThenReturnTypeAvailable()
+TEST_F(DXIntellisenseTest, CursorWhenFunctionThenReturnTypeAvailable)
 {
   char program[] =
     "int myfunc(int a, float b) { return a + b; }\r\n"
@@ -639,7 +644,7 @@ void DXIntellisenseTest::CursorWhenFunctionThenReturnTypeAvailable()
   // TODO - how to get signature?
 }
 
-void DXIntellisenseTest::CursorWhenReferenceThenDefinitionAvailable()
+TEST_F(DXIntellisenseTest, CursorWhenReferenceThenDefinitionAvailable)
 {
   char program[] =
     "int myfunc(int a, float b) { return a + b; }\r\n"
@@ -668,7 +673,7 @@ void DXIntellisenseTest::CursorWhenReferenceThenDefinitionAvailable()
   VERIFY_ARE_EQUAL(4, offset); // Offset is zero-based
 }
 
-void DXIntellisenseTest::CursorWhenFindAtBodyCallThenMatch()
+TEST_F(DXIntellisenseTest,CursorWhenFindAtBodyCallThenMatch)
 {
   char program[] =
     "int f();\r\n"
@@ -680,7 +685,7 @@ void DXIntellisenseTest::CursorWhenFindAtBodyCallThenMatch()
   ExpectCursorAt(result.TU, 3, 3, DxcCursor_DeclRefExpr, &cursor);
 }
 
-void DXIntellisenseTest::CursorWhenFindAtGlobalThenMatch()
+TEST_F(DXIntellisenseTest, CursorWhenFindAtGlobalThenMatch)
 {
   char program[] = "int a;";
   CompilationResult result(CompilationResult::CreateForProgram(program, _countof(program)));
@@ -689,7 +694,7 @@ void DXIntellisenseTest::CursorWhenFindAtGlobalThenMatch()
   ExpectCursorAt(result.TU, 1, 4, DxcCursor_VarDecl, &cursor);
 }
 
-void DXIntellisenseTest::CursorWhenFindBeforeBodyCallThenMatch()
+TEST_F(DXIntellisenseTest, CursorWhenFindBeforeBodyCallThenMatch)
 {
   char program[] =
     "int f();\r\n"
@@ -710,7 +715,7 @@ void DXIntellisenseTest::CursorWhenFindBeforeBodyCallThenMatch()
   VERIFY_ARE_EQUAL(DxcCursor_DeclRefExpr, cursorKind);
 }
 
-void DXIntellisenseTest::CursorWhenFindBeforeGlobalThenMatch()
+TEST_F(DXIntellisenseTest, CursorWhenFindBeforeGlobalThenMatch)
 {
   char program[] = "    int a;";
   CompilationResult result(CompilationResult::CreateForProgram(program, _countof(program)));
@@ -731,7 +736,7 @@ void DXIntellisenseTest::CursorWhenFindBeforeGlobalThenMatch()
   VERIFY_ARE_EQUAL(DxcCursor_VarDecl, cursorKind);
 }
 
-void DXIntellisenseTest::FileWhenSameThenEqual()
+TEST_F(DXIntellisenseTest, FileWhenSameThenEqual)
 {
   char program[] = "int a;\r\nint b;";
   CompilationResult result(CompilationResult::CreateForProgram(program, _countof(program)));
@@ -748,7 +753,7 @@ void DXIntellisenseTest::FileWhenSameThenEqual()
   VERIFY_ARE_EQUAL(TRUE, isEqual);
 }
 
-void DXIntellisenseTest::FileWhenNotSameThenNotEqual()
+TEST_F(DXIntellisenseTest, FileWhenNotSameThenNotEqual)
 {
   char program[] = "int a;\r\nint b;";
   CompilationResult result0(CompilationResult::CreateForProgram(program, _countof(program)));
@@ -766,7 +771,7 @@ void DXIntellisenseTest::FileWhenNotSameThenNotEqual()
   VERIFY_ARE_EQUAL(FALSE, isEqual);
 }
 
-void DXIntellisenseTest::TypeWhenICEThenEval()
+TEST_F(DXIntellisenseTest, TypeWhenICEThenEval)
 {
   // When an ICE is present in a declaration, it appears in the name.
   char program[] =

+ 372 - 0
tools/clang/unittests/HLSL/DxcTestUtils.cpp

@@ -0,0 +1,372 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// DxcTestUtils.cpp                                                          //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Utility function implementations for testing dxc APIs                     //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "CompilationResult.h"
+#include "DxcTestUtils.h"
+#include "HlslTestUtils.h"
+#include "dxc/Support/HLSLOptions.h"
+#include "dxc/Support/Global.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/FileSystem.h"
+
+using namespace std;
+using namespace hlsl_test;
+
+MODULE_SETUP(TestModuleSetup);
+MODULE_CLEANUP(TestModuleCleanup);
+
+bool TestModuleSetup() {
+  // Use this module-level function to set up LLVM dependencies.
+  if (llvm::sys::fs::SetupPerThreadFileSystem())
+    return false;
+  if (FAILED(DxcInitThreadMalloc()))
+    return false;
+  DxcSetThreadMallocOrDefault(nullptr);
+
+  if (hlsl::options::initHlslOptTable()) {
+    return false;
+  }
+  return true;
+}
+
+bool TestModuleCleanup() {
+  // Use this module-level function to set up LLVM dependencies.
+  // In particular, clean up managed static allocations used by
+  // parsing options with the LLVM library.
+  ::hlsl::options::cleanupHlslOptTable();
+  ::llvm::llvm_shutdown();
+  DxcClearThreadMalloc();
+  DxcCleanupThreadMalloc();
+  llvm::sys::fs::CleanupPerThreadFileSystem();
+  return true;
+}
+
+std::shared_ptr<HlslIntellisenseSupport> CompilationResult::DefaultHlslSupport;
+
+void CheckOperationSucceeded(IDxcOperationResult *pResult, IDxcBlob **ppBlob) {
+  HRESULT status;
+  VERIFY_SUCCEEDED(pResult->GetStatus(&status));
+  VERIFY_SUCCEEDED(status);
+  VERIFY_SUCCEEDED(pResult->GetResult(ppBlob));
+}
+
+static bool CheckMsgs(llvm::StringRef text, llvm::ArrayRef<LPCSTR> pMsgs,
+                      bool bRegex) {
+  const char *pStart = !text.empty() ? text.begin() : nullptr;
+  const char *pEnd = !text.empty() ? text.end() : nullptr;
+  for (auto pMsg : pMsgs) {
+    if (bRegex) {
+      llvm::Regex RE(pMsg);
+      std::string reErrors;
+      VERIFY_IS_TRUE(RE.isValid(reErrors));
+      if (!RE.match(text)) {
+        WEX::Logging::Log::Comment(WEX::Common::String().Format(
+          L"Unable to find regex '%S' in text:\r\n%.*S", pMsg, (pEnd - pStart),
+          pStart));
+        VERIFY_IS_TRUE(false);
+      }
+    } else {
+      const char *pMatch = std::search(pStart, pEnd, pMsg, pMsg + strlen(pMsg));
+      if (pEnd == pMatch) {
+        WEX::Logging::Log::Comment(WEX::Common::String().Format(
+            L"Unable to find '%S' in text:\r\n%.*S", pMsg, (pEnd - pStart),
+            pStart));
+      }
+      VERIFY_IS_FALSE(pEnd == pMatch);
+    }
+  }
+  return true;
+}
+
+bool CheckMsgs(const LPCSTR pText, size_t TextCount, const LPCSTR *pErrorMsgs,
+               size_t errorMsgCount, bool bRegex) {
+  return CheckMsgs(llvm::StringRef(pText, TextCount),
+                   llvm::ArrayRef<LPCSTR>(pErrorMsgs, errorMsgCount), bRegex);
+}
+
+static bool CheckNotMsgs(llvm::StringRef text, llvm::ArrayRef<LPCSTR> pMsgs,
+                         bool bRegex) {
+  const char *pStart = !text.empty() ? text.begin() : nullptr;
+  const char *pEnd = !text.empty() ? text.end() : nullptr;
+  for (auto pMsg : pMsgs) {
+    if (bRegex) {
+      llvm::Regex RE(pMsg);
+      std::string reErrors;
+      VERIFY_IS_TRUE(RE.isValid(reErrors));
+      if (RE.match(text)) {
+        WEX::Logging::Log::Comment(WEX::Common::String().Format(
+          L"Unexpectedly found regex '%S' in text:\r\n%.*S", pMsg, (pEnd - pStart),
+          pStart));
+        VERIFY_IS_TRUE(false);
+      }
+    }
+    else {
+      const char *pMatch = std::search(pStart, pEnd, pMsg, pMsg + strlen(pMsg));
+      if (pEnd != pMatch) {
+        WEX::Logging::Log::Comment(WEX::Common::String().Format(
+          L"Unexpectedly found '%S' in text:\r\n%.*S", pMsg, (pEnd - pStart),
+          pStart));
+      }
+      VERIFY_IS_TRUE(pEnd == pMatch);
+    }
+  }
+  return true;
+}
+
+bool CheckNotMsgs(const LPCSTR pText, size_t TextCount, const LPCSTR *pErrorMsgs,
+                  size_t errorMsgCount, bool bRegex) {
+  return CheckNotMsgs(llvm::StringRef(pText, TextCount),
+    llvm::ArrayRef<LPCSTR>(pErrorMsgs, errorMsgCount), bRegex);
+}
+
+bool CheckOperationResultMsgs(IDxcOperationResult *pResult,
+                              llvm::ArrayRef<LPCSTR> pErrorMsgs,
+                              bool maySucceedAnyway, bool bRegex) {
+  HRESULT status;
+  CComPtr<IDxcBlobEncoding> text;
+  if (!pResult)
+    return true;
+  VERIFY_SUCCEEDED(pResult->GetStatus(&status));
+  VERIFY_SUCCEEDED(pResult->GetErrorBuffer(&text));
+  const char *pStart = text ? (const char *)text->GetBufferPointer() : nullptr;
+  const char *pEnd = text ? pStart + text->GetBufferSize() : nullptr;
+  if (pErrorMsgs.empty() || (pErrorMsgs.size() == 1 && !pErrorMsgs[0])) {
+    if (FAILED(status) && pStart) {
+      WEX::Logging::Log::Comment(WEX::Common::String().Format(
+          L"Expected success but found errors\r\n%.*S", (pEnd - pStart),
+          pStart));
+    }
+    VERIFY_SUCCEEDED(status);
+  } else {
+    if (SUCCEEDED(status) && maySucceedAnyway) {
+      return false;
+    }
+    CheckMsgs(llvm::StringRef((const char *)text->GetBufferPointer(),
+                              text->GetBufferSize()),
+              pErrorMsgs, bRegex);
+  }
+  return true;
+}
+
+bool CheckOperationResultMsgs(IDxcOperationResult *pResult,
+                              const LPCSTR *pErrorMsgs, size_t errorMsgCount,
+                              bool maySucceedAnyway, bool bRegex) {
+  return CheckOperationResultMsgs(
+      pResult, llvm::ArrayRef<LPCSTR>(pErrorMsgs, errorMsgCount),
+      maySucceedAnyway, bRegex);
+}
+
+std::string DisassembleProgram(dxc::DxcDllSupport &dllSupport,
+                               IDxcBlob *pProgram) {
+  CComPtr<IDxcCompiler> pCompiler;
+  CComPtr<IDxcBlobEncoding> pDisassembly;
+
+  if (!dllSupport.IsEnabled()) {
+    VERIFY_SUCCEEDED(dllSupport.Initialize());
+  }
+
+  VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
+  VERIFY_SUCCEEDED(pCompiler->Disassemble(pProgram, &pDisassembly));
+  return BlobToUtf8(pDisassembly);
+}
+
+void AssembleToContainer(dxc::DxcDllSupport &dllSupport, IDxcBlob *pModule,
+                         IDxcBlob **pContainer) {
+  CComPtr<IDxcAssembler> pAssembler;
+  CComPtr<IDxcOperationResult> pResult;
+  VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcAssembler, &pAssembler));
+  VERIFY_SUCCEEDED(pAssembler->AssembleToContainer(pModule, &pResult));
+  CheckOperationSucceeded(pResult, pContainer);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Helper functions to deal with passes.
+
+void SplitPassList(LPWSTR pPassesBuffer, std::vector<LPCWSTR> &passes) {
+  while (*pPassesBuffer) {
+    // Skip comment lines.
+    if (*pPassesBuffer == L'#') {
+      while (*pPassesBuffer && *pPassesBuffer != '\n' &&
+             *pPassesBuffer != '\r') {
+        ++pPassesBuffer;
+      }
+      while (*pPassesBuffer == '\n' || *pPassesBuffer == '\r') {
+        ++pPassesBuffer;
+      }
+      continue;
+    }
+    // Every other line is an option. Find the end of the line/buffer and
+    // terminate it.
+    passes.push_back(pPassesBuffer);
+    while (*pPassesBuffer && *pPassesBuffer != '\n' && *pPassesBuffer != '\r') {
+      ++pPassesBuffer;
+    }
+    while (*pPassesBuffer == '\n' || *pPassesBuffer == '\r') {
+      *pPassesBuffer = L'\0';
+      ++pPassesBuffer;
+    }
+  }
+}
+
+std::wstring BlobToUtf16(_In_ IDxcBlob *pBlob) {
+  CComPtr<IDxcBlobEncoding> pBlobEncoding;
+  const UINT CP_UTF16 = 1200;
+  IFT(pBlob->QueryInterface(&pBlobEncoding));
+  BOOL known;
+  UINT32 codePage;
+  IFT(pBlobEncoding->GetEncoding(&known, &codePage));
+  std::wstring result;
+  if (codePage == CP_UTF16) {
+    result.resize(pBlob->GetBufferSize() + 1);
+    memcpy((void *)result.data(), pBlob->GetBufferPointer(),
+           pBlob->GetBufferSize());
+    return result;
+  } else if (codePage == CP_UTF8) {
+    Unicode::UTF8ToUTF16String((char *)pBlob->GetBufferPointer(),
+                               pBlob->GetBufferSize(), &result);
+    return result;
+  } else {
+    throw std::runtime_error("Unsupported codepage.");
+  }
+}
+
+void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const char *pVal,
+                _Outptr_ IDxcBlobEncoding **ppBlob) {
+  CComPtr<IDxcLibrary> library;
+  IFT(dllSupport.CreateInstance(CLSID_DxcLibrary, &library));
+  IFT(library->CreateBlobWithEncodingOnHeapCopy(pVal, strlen(pVal), CP_UTF8,
+                                                ppBlob));
+}
+
+void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val,
+                _Outptr_ IDxcBlobEncoding **ppBlob) {
+  CComPtr<IDxcLibrary> library;
+  IFT(dllSupport.CreateInstance(CLSID_DxcLibrary, &library));
+  IFT(library->CreateBlobWithEncodingOnHeapCopy(val.data(), val.size(), CP_UTF8,
+                                                ppBlob));
+}
+
+void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val,
+                _Outptr_ IDxcBlob **ppBlob) {
+  Utf8ToBlob(dllSupport, val, (IDxcBlobEncoding **)ppBlob);
+}
+
+void Utf16ToBlob(dxc::DxcDllSupport &dllSupport, const std::wstring &val,
+                 _Outptr_ IDxcBlobEncoding **ppBlob) {
+  const UINT32 CP_UTF16 = 1200;
+  CComPtr<IDxcLibrary> library;
+  IFT(dllSupport.CreateInstance(CLSID_DxcLibrary, &library));
+  IFT(library->CreateBlobWithEncodingOnHeapCopy(
+      val.data(), val.size() * sizeof(wchar_t), CP_UTF16, ppBlob));
+}
+
+void Utf16ToBlob(dxc::DxcDllSupport &dllSupport, const std::wstring &val,
+                 _Outptr_ IDxcBlob **ppBlob) {
+  Utf16ToBlob(dllSupport, val, (IDxcBlobEncoding **)ppBlob);
+}
+
+void VerifyCompileOK(dxc::DxcDllSupport &dllSupport, LPCSTR pText,
+                     LPWSTR pTargetProfile, LPCWSTR pArgs,
+                     _Outptr_ IDxcBlob **ppResult) {
+  std::vector<std::wstring> argsW;
+  std::vector<LPCWSTR> args;
+  if (pArgs) {
+    wistringstream argsS(pArgs);
+    copy(istream_iterator<wstring, wchar_t>(argsS),
+         istream_iterator<wstring, wchar_t>(), back_inserter(argsW));
+    transform(argsW.begin(), argsW.end(), back_inserter(args),
+              [](const wstring &w) { return w.data(); });
+  }
+  VerifyCompileOK(dllSupport, pText, pTargetProfile, args, ppResult);
+}
+
+void VerifyCompileOK(dxc::DxcDllSupport &dllSupport, LPCSTR pText,
+                     LPWSTR pTargetProfile, std::vector<LPCWSTR> &args,
+                     _Outptr_ IDxcBlob **ppResult) {
+  CComPtr<IDxcCompiler> pCompiler;
+  CComPtr<IDxcBlobEncoding> pSource;
+  CComPtr<IDxcOperationResult> pResult;
+  HRESULT hrCompile;
+  *ppResult = nullptr;
+  VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
+  Utf8ToBlob(dllSupport, pText, &pSource);
+  VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"source.hlsl", L"main",
+                                      pTargetProfile, args.data(), args.size(),
+                                      nullptr, 0, nullptr, &pResult));
+  VERIFY_SUCCEEDED(pResult->GetStatus(&hrCompile));
+  VERIFY_SUCCEEDED(hrCompile);
+  VERIFY_SUCCEEDED(pResult->GetResult(ppResult));
+}
+
+// VersionSupportInfo Implementation
+VersionSupportInfo::VersionSupportInfo()
+    : m_CompilerIsDebugBuild(false), m_InternalValidator(false), m_DxilMajor(0),
+      m_DxilMinor(0), m_ValMajor(0), m_ValMinor(0) {}
+
+void VersionSupportInfo::Initialize(dxc::DxcDllSupport &dllSupport) {
+  VERIFY_IS_TRUE(dllSupport.IsEnabled());
+
+  // Default to Dxil 1.0 and internal Val 1.0
+  m_DxilMajor = m_ValMajor = 1;
+  m_DxilMinor = m_ValMinor = 0;
+  m_InternalValidator = true;
+  CComPtr<IDxcVersionInfo> pVersionInfo;
+  UINT32 VersionFlags = 0;
+
+  // If the following fails, we have Dxil 1.0 compiler
+  if (SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcCompiler, &pVersionInfo))) {
+    VERIFY_SUCCEEDED(pVersionInfo->GetVersion(&m_DxilMajor, &m_DxilMinor));
+    VERIFY_SUCCEEDED(pVersionInfo->GetFlags(&VersionFlags));
+    m_CompilerIsDebugBuild =
+        (VersionFlags & DxcVersionInfoFlags_Debug) ? true : false;
+    pVersionInfo.Release();
+  }
+
+  if (SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcValidator, &pVersionInfo))) {
+    VERIFY_SUCCEEDED(pVersionInfo->GetVersion(&m_ValMajor, &m_ValMinor));
+    VERIFY_SUCCEEDED(pVersionInfo->GetFlags(&VersionFlags));
+    if (m_ValMinor > 0) {
+      // flag only exists on newer validator, assume internal otherwise.
+      m_InternalValidator =
+          (VersionFlags & DxcVersionInfoFlags_Internal) ? true : false;
+    } else {
+      // With old compiler, validator is the only way to get this
+      m_CompilerIsDebugBuild =
+          (VersionFlags & DxcVersionInfoFlags_Debug) ? true : false;
+    }
+  } else {
+    // If create instance of IDxcVersionInfo on validator failed, we have an old
+    // validator from dxil.dll
+    m_InternalValidator = false;
+  }
+}
+bool VersionSupportInfo::SkipIRSensitiveTest() {
+  // Only debug builds preserve BB names.
+  if (!m_CompilerIsDebugBuild) {
+    WEX::Logging::Log::Comment(
+        L"Test skipped due to name preservation requirement.");
+    return true;
+  }
+  return false;
+}
+bool VersionSupportInfo::SkipDxilVersion(unsigned major, unsigned minor) {
+  if (m_DxilMajor < major || (m_DxilMajor == major && m_DxilMinor < minor) ||
+      m_ValMajor < major || (m_ValMajor == major && m_ValMinor < minor)) {
+    WEX::Logging::Log::Comment(WEX::Common::String().Format(
+        L"Test skipped because it requires Dxil %u.%u and Validator %u.%u.",
+        major, minor, major, minor));
+    return true;
+  }
+  return false;
+}
+bool VersionSupportInfo::SkipOutOfMemoryTest() { return false; }

+ 4 - 0
tools/clang/unittests/HLSL/DxcTestUtils.h

@@ -15,6 +15,7 @@
 #include <vector>
 #include "dxc/dxcapi.h"
 #include "dxc/Support/dxcapi.use.h"
+#include "llvm/ADT/ArrayRef.h"
 
 namespace hlsl {
 namespace options {
@@ -104,6 +105,9 @@ inline std::string BlobToUtf8(_In_ IDxcBlob *pBlob) {
 void AssembleToContainer(dxc::DxcDllSupport &dllSupport, IDxcBlob *pModule, IDxcBlob **pContainer);
 std::wstring BlobToUtf16(_In_ IDxcBlob *pBlob);
 void CheckOperationSucceeded(IDxcOperationResult *pResult, IDxcBlob **ppBlob);
+bool CheckOperationResultMsgs(IDxcOperationResult *pResult,
+                              llvm::ArrayRef<LPCSTR> pErrorMsgs,
+                              bool maySucceedAnyway, bool bRegex);
 bool CheckOperationResultMsgs(IDxcOperationResult *pResult,
                               const LPCSTR *pErrorMsgs, size_t errorMsgCount,
                               bool maySucceedAnyway, bool bRegex);

+ 10 - 10
tools/clang/unittests/HLSL/DxilModuleTest.cpp

@@ -46,18 +46,18 @@ public:
   dxc::DxcDllSupport m_dllSupport;
 
   // Basic loading tests.
-  TEST_METHOD(LoadDxilModule_1_0);
-  TEST_METHOD(LoadDxilModule_1_1);
-  TEST_METHOD(LoadDxilModule_1_2);
+  TEST_METHOD(LoadDxilModule_1_0)
+  TEST_METHOD(LoadDxilModule_1_1)
+  TEST_METHOD(LoadDxilModule_1_2)
 
   // Precise query tests.
-  TEST_METHOD(Precise1);
-  TEST_METHOD(Precise2);
-  TEST_METHOD(Precise3);
-  TEST_METHOD(Precise4);
-  TEST_METHOD(Precise5);
-  TEST_METHOD(Precise6);
-  TEST_METHOD(Precise7);
+  TEST_METHOD(Precise1)
+  TEST_METHOD(Precise2)
+  TEST_METHOD(Precise3)
+  TEST_METHOD(Precise4)
+  TEST_METHOD(Precise5)
+  TEST_METHOD(Precise6)
+  TEST_METHOD(Precise7)
 };
 
 bool DxilModuleTest::InitSupport() {

+ 16 - 16
tools/clang/unittests/HLSL/ExtensionTest.cpp

@@ -422,22 +422,22 @@ public:
 
   dxc::DxcDllSupport m_dllSupport;
 
-  TEST_METHOD(DefineWhenRegisteredThenPreserved);
-  TEST_METHOD(DefineValidationError);
-  TEST_METHOD(DefineValidationWarning);
-  TEST_METHOD(DefineNoValidatorOk);
-  TEST_METHOD(DefineFromMacro);
-  TEST_METHOD(IntrinsicWhenAvailableThenUsed);
-  TEST_METHOD(CustomIntrinsicName);
-  TEST_METHOD(NoLowering);
-  TEST_METHOD(PackedLowering);
-  TEST_METHOD(ReplicateLoweringWhenOnlyVectorIsResult);
-  TEST_METHOD(UnsignedOpcodeIsUnchanged);
-  TEST_METHOD(ResourceExtensionIntrinsic);
-  TEST_METHOD(NameLoweredWhenNoReplicationNeeded);
-  TEST_METHOD(DxilLoweringVector1);
-  TEST_METHOD(DxilLoweringVector2);
-  TEST_METHOD(DxilLoweringScalar);
+  TEST_METHOD(DefineWhenRegisteredThenPreserved)
+  TEST_METHOD(DefineValidationError)
+  TEST_METHOD(DefineValidationWarning)
+  TEST_METHOD(DefineNoValidatorOk)
+  TEST_METHOD(DefineFromMacro)
+  TEST_METHOD(IntrinsicWhenAvailableThenUsed)
+  TEST_METHOD(CustomIntrinsicName)
+  TEST_METHOD(NoLowering)
+  TEST_METHOD(PackedLowering)
+  TEST_METHOD(ReplicateLoweringWhenOnlyVectorIsResult)
+  TEST_METHOD(UnsignedOpcodeIsUnchanged)
+  TEST_METHOD(ResourceExtensionIntrinsic)
+  TEST_METHOD(NameLoweredWhenNoReplicationNeeded)
+  TEST_METHOD(DxilLoweringVector1)
+  TEST_METHOD(DxilLoweringVector2)
+  TEST_METHOD(DxilLoweringScalar)
 };
 
 TEST_F(ExtensionTest, DefineWhenRegisteredThenPreserved) {

+ 3 - 3
tools/clang/unittests/HLSL/FunctionTest.cpp

@@ -31,9 +31,9 @@ public:
     TEST_CLASS_PROPERTY(L"Parallel", L"true")
     TEST_METHOD_PROPERTY(L"Priority", L"0")
   END_TEST_CLASS()
-  TEST_METHOD(AllowedStorageClass);
-  TEST_METHOD(AllowedInParamUsesClass);
-  TEST_METHOD(ParseRootSignature);
+  TEST_METHOD(AllowedStorageClass)
+  TEST_METHOD(AllowedInParamUsesClass)
+  TEST_METHOD(ParseRootSignature)
 
   dxc::DxcDllSupport m_support;
   std::vector<char> rootSigText;

+ 2 - 1
tools/clang/unittests/HLSL/HLSLTestOptions.cpp

@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "HLSLTestOptions.h"
+#include "WEXAdapter.h"
 #include "dxc/Support/WinAdapter.h"
 
 namespace clang {
@@ -29,7 +30,7 @@ ARG_LIST(ARG_DEFINE)
 namespace WEX {
 namespace TestExecution {
 namespace RuntimeParameters {
-HRESULT TryGetValue(const wchar_t *param, std::wstring &retStr) {
+HRESULT TryGetValue(const wchar_t *param, WEX::Common::String &retStr) {
 #define RETURN_ARG(argname)                                                    \
   if (wcscmp(param, L## #argname) == 0) {                                      \
     if (!clang::hlsl::testOptions::argname.empty()) {                          \

+ 49 - 18
tools/clang/unittests/HLSL/HlslTestUtils.h

@@ -11,10 +11,15 @@
 #include <string>
 #include <sstream>
 #include <fstream>
+#ifdef _WIN32
+#include <dxgiformat.h>
+#include "WexTestClass.h"
+#else
+#include "WEXAdapter.h"
+#endif
 #include "dxc/Support/Unicode.h"
 #include "dxc/HLSL/DxilConstants.h" // DenormMode
 #include "llvm/Support/Atomic.h"
-#include <dxgiformat.h>
 
 // If TAEF verify macros are available, use them to alias other legacy
 // comparison macros that don't have a direct translation.
@@ -28,10 +33,12 @@
 // preprocessor settings.
 
 #ifdef VERIFY_ARE_EQUAL
+#ifndef EXPECT_STREQ
 #define EXPECT_STREQ(a, b) VERIFY_ARE_EQUAL(0, strcmp(a, b))
+#endif
 #define EXPECT_STREQW(a, b) VERIFY_ARE_EQUAL(0, wcscmp(a, b))
 #define VERIFY_ARE_EQUAL_CMP(a, b, ...) VERIFY_IS_TRUE(a == b, __VA_ARGS__)
-#define VERIFY_ARE_EQUAL_STR(a, b, ...) { \
+#define VERIFY_ARE_EQUAL_STR(a, b) { \
   const char *pTmpA = (a);\
   const char *pTmpB = (b);\
   if (0 != strcmp(pTmpA, pTmpB)) {\
@@ -41,27 +48,42 @@
     wchar_t diffMsg[32]; swprintf_s(diffMsg, _countof(diffMsg), L"diff at %u", (unsigned)(pA-pTmpA)); \
     WEX::Logging::Log::Comment(diffMsg); \
   } \
-  VERIFY_ARE_EQUAL(0, strcmp(pTmpA, pTmpB), __VA_ARGS__); \
+  VERIFY_ARE_EQUAL(0, strcmp(pTmpA, pTmpB)); \
 }
-#define VERIFY_ARE_EQUAL_WSTR(a, b, ...) { \
+#define VERIFY_ARE_EQUAL_WSTR(a, b) { \
   if (0 != wcscmp(a, b)) { WEX::Logging::Log::Comment(b);} \
-  VERIFY_ARE_EQUAL(0, wcscmp(a, b), __VA_ARGS__); \
+  VERIFY_ARE_EQUAL(0, wcscmp(a, b)); \
 }
+#ifndef ASSERT_EQ
 #define ASSERT_EQ(expected, actual) VERIFY_ARE_EQUAL(expected, actual)
+#endif
+#ifndef ASSERT_NE
 #define ASSERT_NE(expected, actual) VERIFY_ARE_NOT_EQUAL(expected, actual)
+#endif
+#ifndef TEST_F
 #define TEST_F(typeName, functionName) void typeName::functionName()
+#endif
 #define ASSERT_HRESULT_SUCCEEDED VERIFY_SUCCEEDED
+#ifndef EXPECT_EQ
 #define EXPECT_EQ(expected, actual) VERIFY_ARE_EQUAL(expected, actual)
 #endif
+#endif
 
 namespace hlsl_test {
 
 inline std::wstring
 vFormatToWString(_In_z_ _Printf_format_string_ const wchar_t *fmt, va_list argptr) {
   std::wstring result;
+#ifdef _WIN32
   int len = _vscwprintf(fmt, argptr);
   result.resize(len + 1);
   vswprintf_s((wchar_t *)result.data(), len + 1, fmt, argptr);
+#else
+  wchar_t fmtOut[1000];
+  int len = vswprintf(fmtOut, 1000, fmt, argptr);
+  assert(len >= 0 && "Too long formatted string in vFormatToWstring");
+  result = fmtOut;
+#endif
   return result;
 }
 
@@ -97,14 +119,18 @@ inline std::wstring GetPathToHlslDataFile(const wchar_t* relative) {
 
   wchar_t envPath[MAX_PATH];
   wchar_t expanded[MAX_PATH];
-  swprintf_s(envPath, _countof(envPath), L"%s\\%s", reinterpret_cast<wchar_t*>(HlslDataDirValue.GetBuffer()), relative);
+  swprintf_s(envPath, _countof(envPath), L"%ls\\%ls", reinterpret_cast<const wchar_t*>(HlslDataDirValue.GetBuffer()), relative);
   VERIFY_WIN32_BOOL_SUCCEEDED(ExpandEnvironmentStringsW(envPath, expanded, _countof(expanded)));
   return std::wstring(expanded);
 }
 
 inline bool PathLooksAbsolute(LPCWSTR name) {
   // Very simplified, only for the cases we care about in the test suite.
+#ifdef _WIN32
   return name && *name && ((*name == L'\\') || (name[1] == L':'));
+#else
+  return name && *name && (*name == L'/');
+#endif
 }
 
 inline std::string GetFirstLine(LPCWSTR name) {
@@ -114,7 +140,11 @@ inline std::string GetFirstLine(LPCWSTR name) {
   const std::wstring path = PathLooksAbsolute(name)
                                 ? std::wstring(name)
                                 : hlsl_test::GetPathToHlslDataFile(name);
+#ifdef _WIN32
   std::ifstream infile(path);
+#else
+  std::ifstream infile((CW2A(path.c_str())));
+#endif
   if (infile.bad()) {
     std::wstring errMsg(L"Unable to read file ");
     errMsg += path;
@@ -174,7 +204,7 @@ inline bool GetTestParamUseWARP(bool defaultVal) {
           L"Adapter", AdapterValue))) {
     return defaultVal;
   }
-  if (defaultVal && AdapterValue.IsEmpty() ||
+  if ((defaultVal && AdapterValue.IsEmpty()) ||
       AdapterValue.CompareNoCase(L"WARP") == 0) {
     return true;
   }
@@ -184,11 +214,11 @@ inline bool GetTestParamUseWARP(bool defaultVal) {
 }
 
 inline bool isdenorm(float f) {
-  return FP_SUBNORMAL == fpclassify(f);
+  return FP_SUBNORMAL == std::fpclassify(f);
 }
 
 inline bool isdenorm(double d) {
-  return FP_SUBNORMAL == fpclassify(d);
+  return FP_SUBNORMAL == std::fpclassify(d);
 }
 
 inline float ifdenorm_flushf(float a) {
@@ -200,7 +230,7 @@ inline bool ifdenorm_flushf_eq(float a, float b) {
 }
 
 inline bool ifdenorm_flushf_eq_or_nans(float a, float b) {
-  if (isnan(a) && isnan(b)) return true;
+  if (std::isnan(a) && std::isnan(b)) return true;
   return ifdenorm_flushf(a) == ifdenorm_flushf(b);
 }
 
@@ -331,13 +361,13 @@ inline bool CompareFloatULP(const float &fsrc, const float &fref,
   if (fsrc == fref) {
     return true;
   }
-  if (isnan(fsrc)) {
-    return isnan(fref);
+  if (std::isnan(fsrc)) {
+    return std::isnan(fref);
   }
   if (mode == hlsl::DXIL::Float32DenormMode::Any) {
     // If denorm expected, output can be sign preserved zero. Otherwise output
     // should pass the regular ulp testing.
-    if (isdenorm(fref) && fsrc == 0 && signbit(fsrc) == signbit(fref))
+    if (isdenorm(fref) && fsrc == 0 && std::signbit(fsrc) == std::signbit(fref))
       return true;
   }
   // For FTZ or Preserve mode, we should get the expected number within
@@ -353,13 +383,13 @@ CompareFloatEpsilon(const float &fsrc, const float &fref, float epsilon,
   if (fsrc == fref) {
     return true;
   }
-  if (isnan(fsrc)) {
-    return isnan(fref);
+  if (std::isnan(fsrc)) {
+    return std::isnan(fref);
   }
   if (mode == hlsl::DXIL::Float32DenormMode::Any) {
     // If denorm expected, output can be sign preserved zero. Otherwise output
     // should pass the regular epsilon testing.
-    if (isdenorm(fref) && fsrc == 0 && signbit(fsrc) == signbit(fref))
+    if (isdenorm(fref) && fsrc == 0 && std::signbit(fsrc) == std::signbit(fref))
       return true;
   }
   // For FTZ or Preserve mode, we should get the expected number within
@@ -393,7 +423,7 @@ inline bool CompareHalfEpsilon(const uint16_t &fsrc, const uint16_t &fref, float
     return isnanFloat16(fref);
   float src_f32 = ConvertFloat16ToFloat32(fsrc);
   float ref_f32 = ConvertFloat16ToFloat32(fref);
-  return abs(src_f32-ref_f32) < epsilon;
+  return std::abs(src_f32-ref_f32) < epsilon;
 }
 
 inline bool
@@ -402,6 +432,7 @@ CompareHalfRelativeEpsilon(const uint16_t &fsrc, const uint16_t &fref,
   return CompareHalfULP(fsrc, fref, 10 - nRelativeExp);
 }
 
+#ifdef _WIN32
 // returns the number of bytes per pixel for a given dxgi format
 // add more cases if different format needed to copy back resources
 inline UINT GetByteSizeForFormat(DXGI_FORMAT value) {
@@ -477,7 +508,7 @@ inline UINT GetByteSizeForFormat(DXGI_FORMAT value) {
         return 0;
     }
 }
-
+#endif
 
 #define SIMPLE_IUNKNOWN_IMPL1(_IFACE_) \
   private: volatile llvm::sys::cas_flag m_dwRef; \

+ 6 - 6
tools/clang/unittests/HLSL/MSFileSysTest.cpp

@@ -37,14 +37,14 @@ public:
     TEST_METHOD_PROPERTY(L"Priority", L"0")
   END_TEST_CLASS()
 
-  TEST_METHOD(CreationWhenInvokedThenNonNull);
+  TEST_METHOD(CreationWhenInvokedThenNonNull)
 
-  TEST_METHOD(FindFirstWhenInvokedThenHasFile);
-  TEST_METHOD(FindFirstWhenInvokedThenFailsIfNoMatch);
-  TEST_METHOD(FindNextWhenLastThenNoMatch);
-  TEST_METHOD(FindNextWhenExistsThenMatch);
+  TEST_METHOD(FindFirstWhenInvokedThenHasFile)
+  TEST_METHOD(FindFirstWhenInvokedThenFailsIfNoMatch)
+  TEST_METHOD(FindNextWhenLastThenNoMatch)
+  TEST_METHOD(FindNextWhenExistsThenMatch)
 
-  TEST_METHOD(OpenWhenNewThenZeroSize);
+  TEST_METHOD(OpenWhenNewThenZeroSize)
 };
 
 static

+ 27 - 15
tools/clang/unittests/HLSL/Objects.cpp

@@ -12,7 +12,9 @@
 #include "HLSLTestData.h"
 #include <stdint.h>
 
+#ifdef _WIN32
 #include "WexTestClass.h"
+#endif
 #include "HlslTestUtils.h"
 
 #include <exception>
@@ -477,12 +479,15 @@ const ShaderObjectIntrinsicDataItem& GetIntrinsicData(const ShaderObjectDataItem
     }
   }
 
-  throw std::exception("cannot find shader object kind");
+  throw std::runtime_error("cannot find shader object kind");
 }
 
 // The test fixture.
-class ObjectTest
-{
+#ifdef _WIN32
+class ObjectTest {
+#else
+class ObjectTest : public ::testing::Test {
+#endif
 private:
   HlslIntellisenseSupport m_isenseSupport;
 public:
@@ -493,16 +498,16 @@ public:
 
   TEST_CLASS_SETUP(ObjectTestSetup);
 
-  TEST_METHOD(DeclareLocalObject);
-  TEST_METHOD(OptionalTemplateArgs);
-  TEST_METHOD(MissingTemplateArgs);
-  TEST_METHOD(TooManyTemplateArgs);
-  TEST_METHOD(PassAsParameter);
-  TEST_METHOD(AssignVariables);
-  TEST_METHOD(AssignReturnResult);
-  TEST_METHOD(PassToInoutArgs);
-  TEST_METHOD(TemplateArgConstraints);
-  TEST_METHOD(FunctionInvoke);
+  TEST_METHOD(DeclareLocalObject)
+  TEST_METHOD(OptionalTemplateArgs)
+  TEST_METHOD(MissingTemplateArgs)
+  TEST_METHOD(TooManyTemplateArgs)
+  TEST_METHOD(PassAsParameter)
+  TEST_METHOD(AssignVariables)
+  TEST_METHOD(AssignReturnResult)
+  TEST_METHOD(PassToInoutArgs)
+  TEST_METHOD(TemplateArgConstraints)
+  TEST_METHOD(FunctionInvoke)
 
   void FormatTypeNameAndPreamble(const ShaderObjectDataItem& sod,
                                  char (&typeName)[64],
@@ -619,6 +624,9 @@ public:
     case SOK_StreamOutputTriangle:
       parmType = "inout " + parmType;
       break;
+    default:
+      // Other kinds need no alteration
+      break;
     }
 
     sprintf_s(result, _countof(result),
@@ -684,8 +692,6 @@ public:
 
 bool ObjectTest::ObjectTestSetup()
 {
-  // Runs once for all tests in this class.
-  // Load the dxcompiler DLL and hold a reference to it to avoid unload/reloads.
   m_isenseSupport.Initialize();
   return m_isenseSupport.IsEnabled();
 }
@@ -787,6 +793,9 @@ TEST_F(ObjectTest, PassToInoutArgs) {
         // Stream-output objects can only be inout. Skip other cases.
         if (std::string(iop.Keyword) != "inout")
           continue;
+      default:
+        // other cases can be what they want
+        break;
       }
 
       char typeName[64];
@@ -843,6 +852,9 @@ CreateSampleDataForTemplateArg(
   auto templateData = GetTemplateData(sod);
   assert(templateData.TemplateKind != SOTK_NoParams && "shouldn't call CreateSampleDataForTemplateArg");
   switch (templateData.TemplateKind) {
+  case SOTK_NoParams:
+    assert(!"shouldn't call CreateSampleDataForTemplateArg");
+    break;
   case SOTK_SingleSVParam:
   case SOTK_SingleSVCParam:
     sprintf_s(typeName, _countof(typeName), "%s<float4>", sod.TypeName);

+ 0 - 27
tools/clang/unittests/HLSL/OptimizerTest.cpp

@@ -45,33 +45,6 @@
 using namespace std;
 using namespace hlsl_test;
 
-///////////////////////////////////////////////////////////////////////////////
-// Helper functions to deal with passes.
-
-void SplitPassList(LPWSTR pPassesBuffer, std::vector<LPCWSTR> &passes) {
-  while (*pPassesBuffer) {
-    // Skip comment lines.
-    if (*pPassesBuffer == L'#') {
-      while (*pPassesBuffer && *pPassesBuffer != '\n' && *pPassesBuffer != '\r') {
-        ++pPassesBuffer;
-      }
-      while (*pPassesBuffer == '\n' || *pPassesBuffer == '\r') {
-        ++pPassesBuffer;
-      }
-      continue;
-    }
-    // Every other line is an option. Find the end of the line/buffer and terminate it.
-    passes.push_back(pPassesBuffer);
-    while (*pPassesBuffer && *pPassesBuffer != '\n' && *pPassesBuffer != '\r') {
-      ++pPassesBuffer;
-    }
-    while (*pPassesBuffer == '\n' || *pPassesBuffer == '\r') {
-      *pPassesBuffer = L'\0';
-      ++pPassesBuffer;
-    }
-  }
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // Optimizer test cases.
 

+ 5 - 1
tools/clang/unittests/HLSL/RewriterTest.cpp

@@ -16,6 +16,10 @@
 #define UNICODE
 #endif
 
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
 #include <memory>
 #include <vector>
 #include <string>
@@ -608,4 +612,4 @@ float test(float a, float b) {\n\
 #define X 1\n\
 #define Y(A, B)  ( ( A ) + ( B ) )\n\
 ") == 0);
-}
+}

+ 3 - 0
tools/clang/unittests/HLSL/TestMain.cpp

@@ -13,6 +13,7 @@
 #include "llvm/Support/Signals.h"
 
 #include "HLSLTestOptions.h"
+#include "WEXAdapter.h"
 
 #if defined(_WIN32)
 #include <windows.h>
@@ -139,6 +140,8 @@ int main(int argc, char **argv) {
 #endif
 #endif
 
+  moduleSetup();
   int rv = RUN_ALL_TESTS();
+  moduleTeardown();
   return rv;
 }

+ 84 - 211
tools/clang/unittests/HLSL/ValidationTest.cpp

@@ -29,133 +29,6 @@
 using namespace std;
 using namespace hlsl;
 
-void CheckOperationSucceeded(IDxcOperationResult *pResult, IDxcBlob **ppBlob) {
-  HRESULT status;
-  VERIFY_SUCCEEDED(pResult->GetStatus(&status));
-  VERIFY_SUCCEEDED(status);
-  VERIFY_SUCCEEDED(pResult->GetResult(ppBlob));
-}
-
-static bool CheckMsgs(llvm::StringRef text, llvm::ArrayRef<LPCSTR> pMsgs,
-                      bool bRegex) {
-  const char *pStart = !text.empty() ? text.begin() : nullptr;
-  const char *pEnd = !text.empty() ? text.end() : nullptr;
-  for (auto pMsg : pMsgs) {
-    if (bRegex) {
-      llvm::Regex RE(pMsg);
-      std::string reErrors;
-      VERIFY_IS_TRUE(RE.isValid(reErrors));
-      if (!RE.match(text)) {
-        WEX::Logging::Log::Comment(WEX::Common::String().Format(
-          L"Unable to find regex '%S' in text:\r\n%.*S", pMsg, (pEnd - pStart),
-          pStart));
-        VERIFY_IS_TRUE(false);
-      }
-    } else {
-      const char *pMatch = std::search(pStart, pEnd, pMsg, pMsg + strlen(pMsg));
-      if (pEnd == pMatch) {
-        WEX::Logging::Log::Comment(WEX::Common::String().Format(
-            L"Unable to find '%S' in text:\r\n%.*S", pMsg, (pEnd - pStart),
-            pStart));
-      }
-      VERIFY_IS_FALSE(pEnd == pMatch);
-    }
-  }
-  return true;
-}
-
-bool CheckMsgs(const LPCSTR pText, size_t TextCount, const LPCSTR *pErrorMsgs,
-               size_t errorMsgCount, bool bRegex) {
-  return CheckMsgs(llvm::StringRef(pText, TextCount),
-                   llvm::ArrayRef<LPCSTR>(pErrorMsgs, errorMsgCount), bRegex);
-}
-
-static bool CheckNotMsgs(llvm::StringRef text, llvm::ArrayRef<LPCSTR> pMsgs,
-                         bool bRegex) {
-  const char *pStart = !text.empty() ? text.begin() : nullptr;
-  const char *pEnd = !text.empty() ? text.end() : nullptr;
-  for (auto pMsg : pMsgs) {
-    if (bRegex) {
-      llvm::Regex RE(pMsg);
-      std::string reErrors;
-      VERIFY_IS_TRUE(RE.isValid(reErrors));
-      if (RE.match(text)) {
-        WEX::Logging::Log::Comment(WEX::Common::String().Format(
-          L"Unexpectedly found regex '%S' in text:\r\n%.*S", pMsg, (pEnd - pStart),
-          pStart));
-        VERIFY_IS_TRUE(false);
-      }
-    }
-    else {
-      const char *pMatch = std::search(pStart, pEnd, pMsg, pMsg + strlen(pMsg));
-      if (pEnd != pMatch) {
-        WEX::Logging::Log::Comment(WEX::Common::String().Format(
-          L"Unexpectedly found '%S' in text:\r\n%.*S", pMsg, (pEnd - pStart),
-          pStart));
-      }
-      VERIFY_IS_TRUE(pEnd == pMatch);
-    }
-  }
-  return true;
-}
-
-bool CheckNotMsgs(const LPCSTR pText, size_t TextCount, const LPCSTR *pErrorMsgs,
-                  size_t errorMsgCount, bool bRegex) {
-  return CheckNotMsgs(llvm::StringRef(pText, TextCount),
-    llvm::ArrayRef<LPCSTR>(pErrorMsgs, errorMsgCount), bRegex);
-}
-
-static
-bool CheckOperationResultMsgs(IDxcOperationResult *pResult,
-                              llvm::ArrayRef<LPCSTR> pErrorMsgs,
-                              bool maySucceedAnyway, bool bRegex) {
-  HRESULT status;
-  CComPtr<IDxcBlobEncoding> text;
-  VERIFY_SUCCEEDED(pResult->GetStatus(&status));
-  VERIFY_SUCCEEDED(pResult->GetErrorBuffer(&text));
-  const char *pStart = text ? (const char *)text->GetBufferPointer() : nullptr;
-  const char *pEnd = text ? pStart + text->GetBufferSize() : nullptr;
-  if (pErrorMsgs.empty() || (pErrorMsgs.size() == 1 && !pErrorMsgs[0])) {
-    if (FAILED(status) && pStart) {
-      WEX::Logging::Log::Comment(WEX::Common::String().Format(
-          L"Expected success but found errors\r\n%.*S", (pEnd - pStart),
-          pStart));
-    }
-    VERIFY_SUCCEEDED(status);
-  }
-  else {
-    if (SUCCEEDED(status) && maySucceedAnyway) {
-      return false;
-    }
-    CheckMsgs(llvm::StringRef((const char *)text->GetBufferPointer(),
-                              text->GetBufferSize()),
-              pErrorMsgs, bRegex);
-  }
-  return true;
-}
-
-bool CheckOperationResultMsgs(IDxcOperationResult *pResult,
-                              const LPCSTR *pErrorMsgs, size_t errorMsgCount,
-                              bool maySucceedAnyway, bool bRegex) {
-  return CheckOperationResultMsgs(
-      pResult, llvm::ArrayRef<LPCSTR>(pErrorMsgs, errorMsgCount),
-      maySucceedAnyway, bRegex);
-}
-
-std::string DisassembleProgram(dxc::DxcDllSupport &dllSupport,
-                               IDxcBlob *pProgram) {
-  CComPtr<IDxcCompiler> pCompiler;
-  CComPtr<IDxcBlobEncoding> pDisassembly;
-
-  if (!dllSupport.IsEnabled()) {
-    VERIFY_SUCCEEDED(dllSupport.Initialize());
-  }
-
-  VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
-  VERIFY_SUCCEEDED(pCompiler->Disassemble(pProgram, &pDisassembly));
-  return BlobToUtf8(pDisassembly);
-}
-
 class ValidationTest
 {
 public:
@@ -166,25 +39,25 @@ public:
 
   TEST_CLASS_SETUP(InitSupport);
 
-  TEST_METHOD(WhenCorrectThenOK);
-  TEST_METHOD(WhenMisalignedThenFail);
-  TEST_METHOD(WhenEmptyFileThenFail);
-  TEST_METHOD(WhenIncorrectMagicThenFail);
-  TEST_METHOD(WhenIncorrectTargetTripleThenFail);
-  TEST_METHOD(WhenIncorrectModelThenFail);
-  TEST_METHOD(WhenIncorrectPSThenFail);
+  TEST_METHOD(WhenCorrectThenOK)
+  TEST_METHOD(WhenMisalignedThenFail)
+  TEST_METHOD(WhenEmptyFileThenFail)
+  TEST_METHOD(WhenIncorrectMagicThenFail)
+  TEST_METHOD(WhenIncorrectTargetTripleThenFail)
+  TEST_METHOD(WhenIncorrectModelThenFail)
+  TEST_METHOD(WhenIncorrectPSThenFail)
 
-  TEST_METHOD(WhenWaveAffectsGradientThenFail);
+  TEST_METHOD(WhenWaveAffectsGradientThenFail)
 
-  TEST_METHOD(WhenMultipleModulesThenFail);
-  TEST_METHOD(WhenUnexpectedEOFThenFail);
-  TEST_METHOD(WhenUnknownBlocksThenFail);
-  TEST_METHOD(WhenZeroInputPatchCountWithInputThenFail);
+  TEST_METHOD(WhenMultipleModulesThenFail)
+  TEST_METHOD(WhenUnexpectedEOFThenFail)
+  TEST_METHOD(WhenUnknownBlocksThenFail)
+  TEST_METHOD(WhenZeroInputPatchCountWithInputThenFail)
 
   TEST_METHOD(Float32DenormModeAttribute)
-  TEST_METHOD(LoadOutputControlPointNotInPatchConstantFunction);
-  TEST_METHOD(StorePatchControlNotInPatchConstantFunction);
-  TEST_METHOD(OutputControlPointIDInPatchConstantFunction);
+  TEST_METHOD(LoadOutputControlPointNotInPatchConstantFunction)
+  TEST_METHOD(StorePatchControlNotInPatchConstantFunction)
+  TEST_METHOD(OutputControlPointIDInPatchConstantFunction)
   TEST_METHOD(GsVertexIDOutOfBound)
   TEST_METHOD(StreamIDOutOfBound)
   TEST_METHOD(SignatureDataWidth)
@@ -293,75 +166,75 @@ public:
   TEST_METHOD(SemPackOverlap2)
   TEST_METHOD(SemMultiDepth)
 
-  TEST_METHOD(WhenInstrDisallowedThenFail);
-  TEST_METHOD(WhenDepthNotFloatThenFail);
-  TEST_METHOD(BarrierFail);
-  TEST_METHOD(CBufferLegacyOutOfBoundFail);
-  TEST_METHOD(CsThreadSizeFail);
-  TEST_METHOD(DeadLoopFail);
-  TEST_METHOD(EvalFail);
-  TEST_METHOD(GetDimCalcLODFail);
-  TEST_METHOD(HsAttributeFail);
-  TEST_METHOD(InnerCoverageFail);
-  TEST_METHOD(InterpChangeFail);
-  TEST_METHOD(InterpOnIntFail);
-  TEST_METHOD(InvalidSigCompTyFail);
-  TEST_METHOD(MultiStream2Fail);
-  TEST_METHOD(PhiTGSMFail);
-  TEST_METHOD(QuadOpInCS);
-  TEST_METHOD(ReducibleFail);
-  TEST_METHOD(SampleBiasFail);
-  TEST_METHOD(SamplerKindFail);
-  TEST_METHOD(SemaOverlapFail);
-  TEST_METHOD(SigOutOfRangeFail);
-  TEST_METHOD(SigOverlapFail);
-  TEST_METHOD(SimpleHs1Fail);
-  TEST_METHOD(SimpleHs3Fail);
-  TEST_METHOD(SimpleHs4Fail);
-  TEST_METHOD(SimpleDs1Fail);
-  TEST_METHOD(SimpleGs1Fail);
-  TEST_METHOD(UavBarrierFail);
-  TEST_METHOD(UndefValueFail);
-  TEST_METHOD(UpdateCounterFail);
-  TEST_METHOD(LocalResCopy);
-  TEST_METHOD(ResCounter);
-
-  TEST_METHOD(WhenSmUnknownThenFail);
-  TEST_METHOD(WhenSmLegacyThenFail);
-
-  TEST_METHOD(WhenMetaFlagsUsageDeclThenOK);
-  TEST_METHOD(WhenMetaFlagsUsageThenFail);
-
-  TEST_METHOD(WhenRootSigMismatchThenFail);
-  TEST_METHOD(WhenRootSigCompatThenSucceed);
-  TEST_METHOD(WhenRootSigMatchShaderSucceed_RootConstVis);
-  TEST_METHOD(WhenRootSigMatchShaderFail_RootConstVis);
-  TEST_METHOD(WhenRootSigMatchShaderSucceed_RootCBV);
-  TEST_METHOD(WhenRootSigMatchShaderFail_RootCBV_Range);
-  TEST_METHOD(WhenRootSigMatchShaderFail_RootCBV_Space);
-  TEST_METHOD(WhenRootSigMatchShaderSucceed_RootSRV);
-  TEST_METHOD(WhenRootSigMatchShaderFail_RootSRV_ResType);
-  TEST_METHOD(WhenRootSigMatchShaderSucceed_RootUAV);
-  TEST_METHOD(WhenRootSigMatchShaderSucceed_DescTable);
-  TEST_METHOD(WhenRootSigMatchShaderSucceed_DescTable_GoodRange);
-  TEST_METHOD(WhenRootSigMatchShaderSucceed_DescTable_Unbounded);
-  TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Range1);
-  TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Range2);
-  TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Range3);
-  TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Space);
-  TEST_METHOD(WhenRootSigMatchShaderSucceed_Unbounded);
-  TEST_METHOD(WhenRootSigMatchShaderFail_Unbounded1);
-  TEST_METHOD(WhenRootSigMatchShaderFail_Unbounded2);
-  TEST_METHOD(WhenRootSigMatchShaderFail_Unbounded3);
-  TEST_METHOD(WhenProgramOutSigMissingThenFail);
-  TEST_METHOD(WhenProgramOutSigUnexpectedThenFail);
-  TEST_METHOD(WhenProgramSigMismatchThenFail);
-  TEST_METHOD(WhenProgramInSigMissingThenFail);
-  TEST_METHOD(WhenProgramSigMismatchThenFail2);
-  TEST_METHOD(WhenProgramPCSigMissingThenFail);
-  TEST_METHOD(WhenPSVMismatchThenFail);
-  TEST_METHOD(WhenRDATMismatchThenFail);
-  TEST_METHOD(WhenFeatureInfoMismatchThenFail);
+  TEST_METHOD(WhenInstrDisallowedThenFail)
+  TEST_METHOD(WhenDepthNotFloatThenFail)
+  TEST_METHOD(BarrierFail)
+  TEST_METHOD(CBufferLegacyOutOfBoundFail)
+  TEST_METHOD(CsThreadSizeFail)
+  TEST_METHOD(DeadLoopFail)
+  TEST_METHOD(EvalFail)
+  TEST_METHOD(GetDimCalcLODFail)
+  TEST_METHOD(HsAttributeFail)
+  TEST_METHOD(InnerCoverageFail)
+  TEST_METHOD(InterpChangeFail)
+  TEST_METHOD(InterpOnIntFail)
+  TEST_METHOD(InvalidSigCompTyFail)
+  TEST_METHOD(MultiStream2Fail)
+  TEST_METHOD(PhiTGSMFail)
+  TEST_METHOD(QuadOpInCS)
+  TEST_METHOD(ReducibleFail)
+  TEST_METHOD(SampleBiasFail)
+  TEST_METHOD(SamplerKindFail)
+  TEST_METHOD(SemaOverlapFail)
+  TEST_METHOD(SigOutOfRangeFail)
+  TEST_METHOD(SigOverlapFail)
+  TEST_METHOD(SimpleHs1Fail)
+  TEST_METHOD(SimpleHs3Fail)
+  TEST_METHOD(SimpleHs4Fail)
+  TEST_METHOD(SimpleDs1Fail)
+  TEST_METHOD(SimpleGs1Fail)
+  TEST_METHOD(UavBarrierFail)
+  TEST_METHOD(UndefValueFail)
+  TEST_METHOD(UpdateCounterFail)
+  TEST_METHOD(LocalResCopy)
+  TEST_METHOD(ResCounter)
+
+  TEST_METHOD(WhenSmUnknownThenFail)
+  TEST_METHOD(WhenSmLegacyThenFail)
+
+  TEST_METHOD(WhenMetaFlagsUsageDeclThenOK)
+  TEST_METHOD(WhenMetaFlagsUsageThenFail)
+
+  TEST_METHOD(WhenRootSigMismatchThenFail)
+  TEST_METHOD(WhenRootSigCompatThenSucceed)
+  TEST_METHOD(WhenRootSigMatchShaderSucceed_RootConstVis)
+  TEST_METHOD(WhenRootSigMatchShaderFail_RootConstVis)
+  TEST_METHOD(WhenRootSigMatchShaderSucceed_RootCBV)
+  TEST_METHOD(WhenRootSigMatchShaderFail_RootCBV_Range)
+  TEST_METHOD(WhenRootSigMatchShaderFail_RootCBV_Space)
+  TEST_METHOD(WhenRootSigMatchShaderSucceed_RootSRV)
+  TEST_METHOD(WhenRootSigMatchShaderFail_RootSRV_ResType)
+  TEST_METHOD(WhenRootSigMatchShaderSucceed_RootUAV)
+  TEST_METHOD(WhenRootSigMatchShaderSucceed_DescTable)
+  TEST_METHOD(WhenRootSigMatchShaderSucceed_DescTable_GoodRange)
+  TEST_METHOD(WhenRootSigMatchShaderSucceed_DescTable_Unbounded)
+  TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Range1)
+  TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Range2)
+  TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Range3)
+  TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Space)
+  TEST_METHOD(WhenRootSigMatchShaderSucceed_Unbounded)
+  TEST_METHOD(WhenRootSigMatchShaderFail_Unbounded1)
+  TEST_METHOD(WhenRootSigMatchShaderFail_Unbounded2)
+  TEST_METHOD(WhenRootSigMatchShaderFail_Unbounded3)
+  TEST_METHOD(WhenProgramOutSigMissingThenFail)
+  TEST_METHOD(WhenProgramOutSigUnexpectedThenFail)
+  TEST_METHOD(WhenProgramSigMismatchThenFail)
+  TEST_METHOD(WhenProgramInSigMissingThenFail)
+  TEST_METHOD(WhenProgramSigMismatchThenFail2)
+  TEST_METHOD(WhenProgramPCSigMissingThenFail)
+  TEST_METHOD(WhenPSVMismatchThenFail)
+  TEST_METHOD(WhenRDATMismatchThenFail)
+  TEST_METHOD(WhenFeatureInfoMismatchThenFail)
   TEST_METHOD(RayShaderWithSignaturesFail)
 
   TEST_METHOD(ViewIDInCSFail)

+ 51 - 71
tools/clang/unittests/HLSL/VerifierTest.cpp

@@ -13,71 +13,71 @@
 #include <string>
 #include "CompilationResult.h"
 #include "HLSLTestData.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "dxc/Support/HLSLOptions.h"
-#include "llvm/Support/FileSystem.h"
 
 #include <fstream>
 
+#ifdef _WIN32
 #include "WexTestClass.h"
+#endif
 #include "HlslTestUtils.h"
 
 using namespace std;
 
-MODULE_SETUP(TestModuleSetup);
-MODULE_CLEANUP(TestModuleCleanup);
-
 // The test fixture.
-class VerifierTest
-{
+#ifdef _WIN32
+class VerifierTest {
+#else
+class VerifierTest : public ::testing::Test {
+#endif
+
 public:
   BEGIN_TEST_CLASS(VerifierTest)
     TEST_CLASS_PROPERTY(L"Parallel", L"true")
     TEST_METHOD_PROPERTY(L"Priority", L"0")
   END_TEST_CLASS()
 
-  TEST_METHOD(RunAttributes);
-  TEST_METHOD(RunConstExpr);
-  TEST_METHOD(RunConstAssign);
-  TEST_METHOD(RunConstDefault);
-  TEST_METHOD(RunCppErrors);
-  TEST_METHOD(RunCXX11Attributes);
-  TEST_METHOD(RunEnums);
-  TEST_METHOD(RunFunctions);
-  TEST_METHOD(RunIndexingOperator);
-  TEST_METHOD(RunIntrinsicExamples);
-  TEST_METHOD(RunMatrixAssignments);
-  TEST_METHOD(RunMatrixSyntax);
-  TEST_METHOD(RunMatrixSyntaxExactPrecision);
-  TEST_METHOD(RunMoreOperators);
-  TEST_METHOD(RunObjectOperators);
-  TEST_METHOD(RunPackReg);
-  TEST_METHOD(RunRayTracings);
-  TEST_METHOD(RunScalarAssignments);
-  TEST_METHOD(RunScalarAssignmentsExactPrecision);
-  TEST_METHOD(RunScalarOperatorsAssign);
-  TEST_METHOD(RunScalarOperatorsAssignExactPrecision);
-  TEST_METHOD(RunScalarOperators);
-  TEST_METHOD(RunScalarOperatorsExactPrecision);
-  TEST_METHOD(RunString);
-  TEST_METHOD(RunStructAssignments);
-  TEST_METHOD(RunIncompleteArray);
-  TEST_METHOD(RunTemplateChecks);
-  TEST_METHOD(RunVarmodsSyntax);
-  TEST_METHOD(RunVectorAssignments);
-  TEST_METHOD(RunVectorSyntaxMix);
-  TEST_METHOD(RunVectorSyntax);
-  TEST_METHOD(RunVectorSyntaxExactPrecision);
-  TEST_METHOD(RunTypemodsSyntax);
-  TEST_METHOD(RunSemantics);
-  TEST_METHOD(RunImplicitCasts);
-  TEST_METHOD(RunDerivedToBaseCasts);
-  TEST_METHOD(RunLiterals);
-  TEST_METHOD(RunEffectsSyntax);
-  TEST_METHOD(RunVectorConditional);
-  TEST_METHOD(RunUint4Add3);
-  TEST_METHOD(RunBadInclude);
-  TEST_METHOD(RunWave);
+  TEST_METHOD(RunAttributes)
+  TEST_METHOD(RunConstExpr)
+  TEST_METHOD(RunConstAssign)
+  TEST_METHOD(RunConstDefault)
+  TEST_METHOD(RunCppErrors)
+  TEST_METHOD(RunCXX11Attributes)
+  TEST_METHOD(RunEnums)
+  TEST_METHOD(RunFunctions)
+  TEST_METHOD(RunIndexingOperator)
+  TEST_METHOD(RunIntrinsicExamples)
+  TEST_METHOD(RunMatrixAssignments)
+  TEST_METHOD(RunMatrixSyntax)
+  TEST_METHOD(RunMatrixSyntaxExactPrecision)
+  TEST_METHOD(RunMoreOperators)
+  TEST_METHOD(RunObjectOperators)
+  TEST_METHOD(RunPackReg)
+  TEST_METHOD(RunRayTracings)
+  TEST_METHOD(RunScalarAssignments)
+  TEST_METHOD(RunScalarAssignmentsExactPrecision)
+  TEST_METHOD(RunScalarOperatorsAssign)
+  TEST_METHOD(RunScalarOperatorsAssignExactPrecision)
+  TEST_METHOD(RunScalarOperators)
+  TEST_METHOD(RunScalarOperatorsExactPrecision)
+  TEST_METHOD(RunString)
+  TEST_METHOD(RunStructAssignments)
+  TEST_METHOD(RunIncompleteArray)
+  TEST_METHOD(RunTemplateChecks)
+  TEST_METHOD(RunVarmodsSyntax)
+  TEST_METHOD(RunVectorAssignments)
+  TEST_METHOD(RunVectorSyntaxMix)
+  TEST_METHOD(RunVectorSyntax)
+  TEST_METHOD(RunVectorSyntaxExactPrecision)
+  TEST_METHOD(RunTypemodsSyntax)
+  TEST_METHOD(RunSemantics)
+  TEST_METHOD(RunImplicitCasts)
+  TEST_METHOD(RunDerivedToBaseCasts)
+  TEST_METHOD(RunLiterals)
+  TEST_METHOD(RunEffectsSyntax)
+  TEST_METHOD(RunVectorConditional)
+  TEST_METHOD(RunUint4Add3)
+  TEST_METHOD(RunBadInclude)
+  TEST_METHOD(RunWave)
 
   void CheckVerifies(const wchar_t* path) {
     WEX::TestExecution::SetVerifyOutput verifySettings(WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
@@ -101,7 +101,7 @@ public:
     //
 
     {
-      ifstream infile(path);
+      ifstream infile(CW2A(path).m_psz);
       ASSERT_EQ(false, infile.bad());
 
       infile.getline(firstLine, _countof(firstLine));
@@ -132,26 +132,6 @@ public:
   }
 };
 
-bool TestModuleSetup() {
-  if (llvm::sys::fs::SetupPerThreadFileSystem())
-    return false;
-  // Use this module-level function to set up LLVM dependencies.
-  if (hlsl::options::initHlslOptTable()) {
-    return false;
-  }
-  return true;
-}
-
-bool TestModuleCleanup() {
-  // Use this module-level function to set up LLVM dependencies.
-  // In particular, clean up managed static allocations used by
-  // parsing options with the LLVM library.
-  ::hlsl::options::cleanupHlslOptTable();
-  llvm::sys::fs::CleanupPerThreadFileSystem();
-  ::llvm::llvm_shutdown();
-  return true;
-}
-
 TEST_F(VerifierTest, RunAttributes) {
   CheckVerifiesHLSL(L"attributes.hlsl");
 }

+ 155 - 0
tools/clang/unittests/HLSL/WEXAdapter.h

@@ -0,0 +1,155 @@
+#ifndef LLVM_CLANG_UNITTESTS_WEX_ADAPTER_H
+#define LLVM_CLANG_UNITTESTS_WEX_ADAPTER_H
+
+#ifndef _WIN32
+
+#include <unistd.h>
+#include <wchar.h>
+
+#include "dxc/Support/WinAdapter.h"
+#include "dxc/Support/WinFunctions.h"
+#include "gtest/gtest.h"
+
+#define MAX_PATH 260
+
+// Concatinate two macro fragments
+#define CONCAT2(a, b) a##b
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT(a, b) CONCAT1(a, b)
+
+// Determine how many arguments are passed to NARG() up to 3
+#define ARG_CT(_1, _2, _3, N, ...) N
+#define NARG(...) ARG_CT(__VA_ARGS__, 3, 2, 1, 0)
+
+// Call the appropriate arity macro based on number of arguments
+#define MACRO_N_(PREFIX, N, ...) CONCAT(PREFIX, N)(__VA_ARGS__)
+#define MACRO_N(PREFIX, ...) MACRO_N_(PREFIX, NARG(__VA_ARGS__), __VA_ARGS__)
+
+// single and double argument versions
+#define VERIFY_SUCCEEDED_1(expr) EXPECT_TRUE(SUCCEEDED(expr))
+#define VERIFY_SUCCEEDED_2(expr, msg) EXPECT_TRUE(SUCCEEDED(expr)) << msg
+#define VERIFY_SUCCEEDED(...) MACRO_N(VERIFY_SUCCEEDED_, __VA_ARGS__)
+
+#define VERIFY_ARE_EQUAL_2(A, B) EXPECT_EQ(A, B)
+#define VERIFY_ARE_EQUAL_3(A, B, msg) EXPECT_EQ(A, B) << msg
+#define VERIFY_ARE_EQUAL(...) MACRO_N(VERIFY_ARE_EQUAL_, __VA_ARGS__)
+
+// Macros to convert TAEF macros to gtest equivalents
+#define VERIFY_IS_TRUE EXPECT_TRUE
+#define VERIFY_FAILED(expr) EXPECT_FALSE(SUCCEEDED(expr))
+#define VERIFY_IS_FALSE EXPECT_FALSE
+#define VERIFY_IS_NULL(exp) EXPECT_EQ(nullptr, (exp))
+#define VERIFY_IS_NOT_NULL(exp) EXPECT_NE(nullptr, (exp))
+#define VERIFY_FAIL ADD_FAILURE
+#define VERIFY_ARE_NOT_EQUAL EXPECT_NE
+#define VERIFY_WIN32_BOOL_SUCCEEDED EXPECT_TRUE
+
+#define TEST_CLASS_SETUP(method)                                               \
+  bool method();                                                               \
+  virtual void SetUp() { EXPECT_TRUE(method()); }
+#define TEST_CLASS_CLEANUP(method)                                             \
+  bool method();                                                               \
+  virtual void TearDown() { EXPECT_TRUE(method()); }
+#define BEGIN_TEST_CLASS(test)
+#define TEST_CLASS_PROPERTY(str1, str2)
+#define TEST_METHOD_PROPERTY(str1, str2)
+#define END_TEST_CLASS()
+#define TEST_METHOD(method)
+#define BEGIN_TEST_METHOD(method)
+#define END_TEST_METHOD()
+
+// gtest lacks any module setup/cleanup. These functions are called by the
+// main() function before and after tests are run. This approximates the
+// behavior.
+bool moduleSetup();
+bool moduleTeardown();
+#define MODULE_SETUP(method)                                                   \
+  bool method();                                                               \
+  bool moduleSetup() { return method(); }
+#define MODULE_CLEANUP(method)                                                 \
+  bool method();                                                               \
+  bool moduleTeardown() { return method(); }
+
+// No need to expand env vars on Unix platforms, so convert the slashes instead.
+inline DWORD ExpandEnvironmentStringsW(_In_ LPCWSTR lpSrc,
+                                       _Out_opt_ LPWSTR lpDst,
+                                       _In_ DWORD nSize) {
+  unsigned i;
+  bool wasSlash = false;
+  for (i = 0; i < nSize && *lpSrc; i++, lpSrc++) {
+    if (*lpSrc == L'\\' || *lpSrc == L'/') {
+      if (!wasSlash)
+        *lpDst++ = L'/';
+      wasSlash = true;
+    } else {
+      *lpDst++ = *lpSrc;
+      wasSlash = false;
+    }
+  }
+  *lpDst = L'\0';
+  return i;
+}
+
+typedef struct _LIST_ENTRY {
+  struct _LIST_ENTRY *Flink;
+  struct _LIST_ENTRY *Blink;
+} LIST_ENTRY, *PLIST_ENTRY, PRLIST_ENTRY;
+
+// Minimal implementation of the WEX namespace functions and classes
+// To either stub out or approximate behavior
+namespace WEX {
+namespace Common {
+class String : public std::wstring {
+public:
+  size_t GetLength() { return length(); }
+  bool IsEmpty() { return empty(); }
+  int CompareNoCase(std::wstring str) const {
+    return -1;
+    assert(!"unimplemented");
+  }
+  operator const wchar_t *() { return c_str(); }
+  const wchar_t *GetBuffer() { return *this; }
+  wchar_t *Format(const wchar_t *fmt, ...) {
+    static wchar_t msg[512];
+    va_list args;
+    va_start(args, fmt);
+    vswprintf(msg, 512, fmt, args);
+    va_end(args);
+    return msg;
+  }
+};
+} // namespace Common
+namespace TestExecution {
+enum class VerifyOutputSettings { LogOnlyFailures };
+class SetVerifyOutput {
+public:
+  SetVerifyOutput(VerifyOutputSettings) {}
+};
+class DisableVerifyExceptions {
+public:
+  DisableVerifyExceptions() {}
+};
+namespace RuntimeParameters {
+HRESULT TryGetValue(const wchar_t *param, Common::String &retStr);
+} // namespace RuntimeParameters
+} // namespace TestExecution
+namespace Logging {
+namespace Log {
+inline void StartGroup(const wchar_t *name) { wprintf(L"BEGIN TEST(S): <%ls>\n", name); };
+inline void EndGroup(const wchar_t *name) { wprintf(L"END TEST(S): <%ls>\n", name); };
+inline void Comment(const wchar_t *msg) {
+  fputws(msg, stdout);
+  fputwc(L'\n', stdout);
+}
+inline void Error(const wchar_t *msg) {
+  fputws(msg, stderr);
+  fputwc(L'\n', stderr);
+  ADD_FAILURE();
+}
+} // namespace Log
+} // namespace Logging
+} // namespace WEX
+
+#endif // _WIN32
+
+#endif // LLVM_CLANG_UNITTESTS_WEX_ADAPTER_H

+ 7 - 0
tools/clang/unittests/SPIRV/CodeGenSPIRVTest.cpp

@@ -1332,6 +1332,13 @@ TEST_F(FileTest, VulkanCLOptionInvertYGS) {
   runFileTest("vk.cloption.invert-y.gs.hlsl");
 }
 
+TEST_F(FileTest, VulkanCLOptionInvertWDS) {
+  runFileTest("vk.cloption.invert-w.ds.hlsl");
+}
+TEST_F(FileTest, VulkanCLOptionInvertWPS) {
+  runFileTest("vk.cloption.invert-w.ps.hlsl");
+}
+
 // Vulkan specific
 TEST_F(FileTest, VulkanLocation) { runFileTest("vk.location.hlsl"); }
 TEST_F(FileTest, VulkanLocationInputExplicitOutputImplicit) {

+ 47 - 37
utils/hct/VerifierHelper.py

@@ -78,6 +78,7 @@ fxcExcludedTests = ['RunCppErrors']
 
 # rxRUN = re.compile(r'[ RUN      ] VerifierTest.(\w+)')	# gtest syntax
 rxRUN = re.compile(r'StartGroup: VerifierTest::(\w+)')		# TAEF syntax
+rxEndGroup = re.compile(r'EndGroup: VerifierTest::(\w+)\s+\[(\w+)\]')      # TAEF syntax
 rxForProgram = re.compile(r'^for program (.*?) with errors\:$')
 # rxExpected = re.compile(r"^error\: \'(\w+)\' diagnostics (expected but not seen|seen but not expected)\: $")  # gtest syntax
 rxExpected = re.compile(r"^\'(\w+)\' diagnostics (expected but not seen|seen but not expected)\: $")    # TAEF syntax
@@ -210,7 +211,7 @@ def ParseVerifierTestCpp():
                 tests[FoundTest] = m.group(1)
                 searching = False
         return line
-    with file(HlslVerifierTestCpp, 'rt') as f:
+    with open(HlslVerifierTestCpp, 'rt') as f:
         lines = f.readlines()
         start = 0
         while start < len(lines):
@@ -219,7 +220,7 @@ def ParseVerifierTestCpp():
                 FoundTest = m.group(1)
                 start += ProcessStatementOrBlock(lines, start, fn_process)
                 if FoundTest not in tests:
-                    print 'Could not parse file for test %s' % FoundTest
+                    print('Could not parse file for test %s' % FoundTest)
                 FoundTest = None
             else:
                 start += ProcessStatementOrBlock(lines, start, fn_null)
@@ -327,7 +328,7 @@ def ParseAst(astlines):
             name = m.group(1)
             text = text[m.end(1):].strip()
         else:
-            print 'rxAstNode match failed on:\n  %s' % text
+            print('rxAstNode match failed on:\n  %s' % text)
             return AstNode('ast-parse-failed', SourceLocation(), '', '', indent)
         text = rxAstHexAddress.sub('', text).strip()
         m = rxAstSourceLocation.search(text)
@@ -369,7 +370,7 @@ def ParseAst(astlines):
         # parse and add the node
         node = parsenode(line[col:], indent)
         if not node:
-            print 'error parsing line %d:\n%s' % (i+1, line)
+            print('error parsing line %d:\n%s' % (i+1, line))
             assert False
         push(node, col)
 
@@ -447,8 +448,8 @@ class File(object):
 
     def OutputResult(self):
         temp_filename = os.path.expandvars(r'${TEMP}\%s' % os.path.split(self.filename)[1])
-        with file(self.filename, 'rt') as fin:
-            with file(temp_filename+'.result', 'wt') as fout:
+        with open(self.filename, 'rt') as fin:
+            with open(temp_filename+'.result', 'wt') as fout:
                 line_num = 0
                 for line in fin.readlines():
                     if line[-1] == '\n':
@@ -456,7 +457,7 @@ class File(object):
                     line_num += 1
                     line, expected, diag_col = self.RemoveDiags(line, self.expected.get(line_num, []))
                     for ew, message in expected:
-                        print 'Error: Line %d: Could not find: expected-%s {{%s}}!!' % (line_num, ew, message)
+                        print('Error: Line %d: Could not find: expected-%s {{%s}}!!' % (line_num, ew, message))
                     line = self.AddDiags(line, self.unexpected.get(line_num, []), diag_col)
                     line = self.SortDiags(line)
                     fout.write(line + '\n')
@@ -466,7 +467,7 @@ class File(object):
         if result_filename is None:
             result_filename = temp_filename + '.fxc'
         inlines = []
-        with file(self.filename, 'rt') as fin:
+        with open(self.filename, 'rt') as fin:
             for line in fin.readlines():
                 if line[-1] == '\n':
                     line = line[:-1]
@@ -476,7 +477,7 @@ class File(object):
             m = rxVerifyArguments.search(line)
             if m:
                 verify_arguments = m.group(1)
-                print 'Found :FXC_VERIFY_ARGUMENTS: %s' % verify_arguments
+                print('Found :FXC_VERIFY_ARGUMENTS: %s' % verify_arguments)
                 break
 
         # result will hold the final result after adding fxc error messages
@@ -499,7 +500,7 @@ class File(object):
         # diags_by_line is a dictionary of a set of errors and warnings keyed off line_num
         diags_by_line = {}
         while True:
-            with file(temp_filename+'.fxc_temp', 'wt') as fout:
+            with open(temp_filename+'.fxc_temp', 'wt') as fout:
                 fout.write('\n'.join(commented))
                 if verify_arguments is None:
                     fout.write("\n[numthreads(1,1,1)] void _test_main() {  }\n")
@@ -509,7 +510,7 @@ class File(object):
                 args = verify_arguments
             os.system('%s /nologo "%s.fxc_temp" %s /DVERIFY_FXC=1 /Fo "%s.fxo" /Fe "%s.err" 1> "%s.log" 2>&1' % 
                       (FxcPath, temp_filename, args, temp_filename, temp_filename, temp_filename))
-            with file(temp_filename+'.err', 'rt') as f:
+            with open(temp_filename+'.err', 'rt') as f:
                 errors = [m for m in map(rxFxcErr.match, f.readlines()) if m]
             errors = sorted(errors, key=lambda m: int(m.group(2)))
             first_error = None
@@ -541,8 +542,8 @@ class File(object):
             line = self.SortDiags(self.AddDiags(line, diags, diag_col, prefix='fxc'))
             result[i] = line, diag_col, expected
 
-        with file(result_filename, 'wt') as f:
-            f.write('\n'.join(map(lambda (line, diag_col, expected): line, result)))
+        with open(result_filename, 'wt') as f:
+            f.write('\n'.join(map(lambda line, diag_col, expected: line, result)))
 
     def TryAst(self, result_filename=None):
         temp_filename = os.path.expandvars(r'${TEMP}\%s' % os.path.split(self.filename)[1])
@@ -557,12 +558,12 @@ class File(object):
                            (HlslBinDir, self.filename, temp_filename, temp_filename))
         # dxc dumps ast even if there exists any syntax error. If there is any error, dxc returns some nonzero errorcode.
         if not os.path.isfile(temp_filename+'.ast_dump'):
-            print 'ast-dump failed, see log:\n  %s.log' % (temp_filename)
+            print('ast-dump failed, see log:\n  %s.log' % (temp_filename))
             return
 ##        elif result:
-##            print 'ast-dump succeeded, but exited with error code %d, see log:\n  %s.log' % (result, temp_filename)
+##            print('ast-dump succeeded, but exited with error code %d, see log:\n  %s.log' % (result, temp_filename))
         astlines = []
-        with file(temp_filename+'.ast_dump', 'rt') as fin:
+        with open(temp_filename+'.ast_dump', 'rt') as fin:
             for line in fin.readlines():
                 if line[-1] == '\n':
                     line = line[:-1]
@@ -570,10 +571,10 @@ class File(object):
         try:
             ast_root = ParseAst(astlines)
         except:
-            print 'ParseAst failed on "%s"' % (temp_filename + '.ast_dump')
+            print('ParseAst failed on "%s"' % (temp_filename + '.ast_dump'))
             raise
         inlines = []
-        with file(self.filename, 'rt') as fin:
+        with open(self.filename, 'rt') as fin:
             for line in fin.readlines():
                 if line[-1] == '\n':
                     line = line[:-1]
@@ -598,12 +599,13 @@ class File(object):
                     i += 1
             i += 1
 
-        with file(result_filename, 'wt') as f:
+        with open(result_filename, 'wt') as f:
             f.write('\n'.join(outlines))
 
 def ProcessVerifierOutput(lines):
     files = {}
     cur_filename = None
+    cur_test = None
     state = 'WaitingForFile'
     ew = ''
     expected = None
@@ -612,12 +614,20 @@ def ProcessVerifierOutput(lines):
             continue
         if line[-1] == '\n':
             line = line[:-1]
+        m = rxRUN.match(line)
+        if m:
+            cur_test = m.group(1)
         m = rxForProgram.match(line)
         if m:
             cur_filename = m.group(1)
             files[cur_filename] = File(cur_filename)
             state = 'WaitingForCategory'
             continue
+        if state is 'WaitingForFile':
+            m = rxEndGroup.match(line)
+            if m and m.group(2) == 'Failed':
+                # This usually happens when compiler crashes
+                print('Fatal Error: test %s failed without verifier results.' % cur_test)
         if state is 'WaitingForCategory' or state is 'ReadingErrors':
             m = rxExpected.match(line)
             if m:
@@ -640,37 +650,37 @@ def ProcessVerifierOutput(lines):
 
 
 def maybe_compare(filename1, filename2):
-    with file(filename1, 'rt') as fbefore:
-        with file(filename2, 'rt') as fafter:
+    with open(filename1, 'rt') as fbefore:
+        with open(filename2, 'rt') as fafter:
             before = fbefore.read()
             after = fafter.read()
     if before.strip() != after.strip():
-        print 'Differences found.  Compare:\n  %s\nwith:\n  %s' % (filename1, filename2)
+        print('Differences found.  Compare:\n  %s\nwith:\n  %s' % (filename1, filename2))
         if DiffTool:
             os.system('%s %s %s' % (DiffTool, filename1, filename2))
         return True
     return False
 
 def PrintUsage():
-    print __doc__
-    print 'Available tests and corresponding files:'
+    print(__doc__)
+    print('Available tests and corresponding files:')
     tests = sorted(VerifierTests.keys())
     width = len(max(tests, key=len))
     for name in tests:
-        print ('    %%-%ds  %%s' % width) % (name, VerifierTests[name])
-    print 'Tests incompatible with fxc mode:'
+        print(('    %%-%ds  %%s' % width) % (name, VerifierTests[name]))
+    print('Tests incompatible with fxc mode:')
     for name in fxcExcludedTests:
-        print '    %s' % name
+        print('    %s' % name)
 
 def RunVerifierTest(test, HlslDataDir=HlslDataDir):
     import codecs
     temp_filename = os.path.expandvars(r'${TEMP}\VerifierHelper_temp.txt')
     cmd = ('te %s\\clang-hlsl-tests.dll /p:"HlslDataDir=%s" /name:VerifierTest::%s > %s' %
            (HlslBinDir, HlslDataDir, test, temp_filename))
-    print cmd
+    print(cmd)
     os.system(cmd)      # TAEF test
     # TAEF outputs unicode, so read as binary and convert:
-    with file(temp_filename, 'rb') as f:
+    with open(temp_filename, 'rb') as f:
         return codecs.decode(f.read(), 'UTF-16').replace(u'\x7f', u'').replace(u'\r\n', u'\n').splitlines()
 
 def main(*args):
@@ -678,7 +688,7 @@ def main(*args):
     try:
         VerifierTests = ParseVerifierTestCpp()
     except:
-        print 'Unable to parse tests from VerifierTest.cpp; using defaults'
+        print('Unable to parse tests from VerifierTest.cpp; using defaults')
     if len(args) < 1 or (args[0][0] in '-/' and args[0][1:].lower() in ('h', '?', 'help')):
         PrintUsage()
         return -1
@@ -694,13 +704,13 @@ def main(*args):
             tests = [args[1]]
         differences = False
         for test in tests:
-            print '---- %s ----' % test
+            print('---- %s ----' % test)
             filename = os.path.join(HlslDataDir, VerifierTests[test])
             result_filename = os.path.expandvars(r'${TEMP}\%s.fxc' % os.path.split(filename)[1])
             File(filename).TryFxc()
             differences = maybe_compare(filename, result_filename) or differences
         if not differences:
-            print 'No differences found!'
+            print('No differences found!')
     elif mode == 'clang':
         if args[1] != '*' and args[1] not in VerifierTests:
             PrintUsage()
@@ -713,7 +723,7 @@ def main(*args):
                     result_filename = os.path.expandvars(r'${TEMP}\%s.result' % os.path.split(f.filename)[1])
                     differences = maybe_compare(f.filename, result_filename) or differences
         if not differences:
-            print 'No differences found!'
+            print('No differences found!')
     elif mode == 'ast':
         allAstTests = sorted(VerifierTests.keys())
         if args[1] == '*':
@@ -725,13 +735,13 @@ def main(*args):
             tests = [args[1]]
         differences = False
         for test in tests:
-            print '---- %s ----' % test
+            print('---- %s ----' % test)
             filename = os.path.join(HlslDataDir, VerifierTests[test])
             result_filename = os.path.expandvars(r'${TEMP}\%s.ast' % os.path.split(filename)[1])
             File(filename).TryAst()
             differences = maybe_compare(filename, result_filename) or differences
         if not differences:
-            print 'No differences found!'
+            print('No differences found!')
     elif mode == 'all':
         allTests = sorted(VerifierTests.keys())
         if args[1] == '*':
@@ -764,14 +774,14 @@ def main(*args):
         for test in tests:
             name = VerifierTests[test]
             sourceFile = sourceFiles[name]
-            print ('Test %%-%ds - %%s' % width) % (test, name)
+            print(('Test %%-%ds - %%s' % width) % (test, name))
             result_filename = os.path.expandvars(r'${TEMP}\%s.fxc' % name)
             if name not in fxcExcludedFiles:
                 File(sourceFile).TryFxc(result_filename)
                 sourceFiles[name] = result_filename
             differences = maybe_compare(os.path.join(HlslDataDir, name), sourceFiles[name]) or differences
         if not differences:
-            print 'No differences found!'
+            print('No differences found!')
     else:
         PrintUsage()
         return -1

Some files were not shown because too many files changed in this diff