浏览代码

Fixed failure on including empty files, and added test.

Addresses #861
Tristan Labelle 6 年之前
父节点
当前提交
52117431c8

+ 2 - 1
lib/DxcSupport/FileIOHelper.cpp

@@ -589,8 +589,9 @@ HRESULT DxcGetBlobAsUtf8(IDxcBlob *pBlob, IDxcBlobEncoding **pBlobEncoding) thro
     codePage = DxcCodePageFromBytes((const char *)pBlob->GetBufferPointer(), blobLen);
   }
 
-  if (codePage == CP_UTF8) {
+  if (codePage == CP_UTF8 || blobLen == 0) {
     // Reuse the underlying blob but create an object with the encoding known.
+    // Empty blobs are encoding-agnostic, so we can consider them UTF-8 and avoid useless conversion.
     InternalDxcBlobEncoding* internalEncoding;
     hr = InternalDxcBlobEncoding::CreateFromBlob(pBlob, DxcGetThreadMallocNoRef(), true, CP_UTF8, &internalEncoding);
     if (SUCCEEDED(hr)) {

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

@@ -163,8 +163,9 @@ public:
   struct LoadSourceCallResult {
     HRESULT hr;
     std::string source;
-    LoadSourceCallResult() : hr(E_FAIL) { }
-    LoadSourceCallResult(const char *pSource) : hr(S_OK), source(pSource) { }
+    UINT32 codePage;
+    LoadSourceCallResult() : hr(E_FAIL), codePage(0) { }
+    LoadSourceCallResult(const char *pSource, UINT32 codePage = CP_UTF8) : hr(S_OK), source(pSource), codePage(codePage) { }
   };
   std::vector<LoadSourceCallResult> CallResults;
   size_t callIndex;
@@ -182,7 +183,8 @@ public:
     if (FAILED(CallResults[callIndex].hr)) {
       return CallResults[callIndex++].hr;
     }
-    Utf8ToBlob(m_dllSupport, CallResults[callIndex].source, ppIncludeSource);
+    MultiByteStringToBlob(m_dllSupport, CallResults[callIndex].source,
+                          CallResults[callIndex].codePage, ppIncludeSource);
     return CallResults[callIndex++].hr;
   }
 };
@@ -222,6 +224,7 @@ public:
   TEST_METHOD(CompileWhenIncludeFlagsThenIncludeUsed)
   TEST_METHOD(CompileWhenIncludeMissingThenFail)
   TEST_METHOD(CompileWhenIncludeHasPathThenOK)
+  TEST_METHOD(CompileWhenIncludeEmptyThenOK)
 
   TEST_METHOD(CompileWhenODumpThenPassConfig)
   TEST_METHOD(CompileWhenODumpThenOptimizerMatch)
@@ -2299,6 +2302,27 @@ TEST_F(CompilerTest, CompileWhenIncludeHasPathThenOK) {
  }
 }
 
+TEST_F(CompilerTest, CompileWhenIncludeEmptyThenOK) {
+  CComPtr<IDxcCompiler> pCompiler;
+  CComPtr<IDxcOperationResult> pResult;
+  CComPtr<IDxcBlobEncoding> pSource;
+  CComPtr<TestIncludeHandler> pInclude;
+
+  VERIFY_SUCCEEDED(CreateCompiler(&pCompiler));
+  CreateBlobFromText("#include \"empty.h\"\r\n"
+                     "float4 main() : SV_Target { return 0; }",
+                     &pSource);
+
+  pInclude = new TestIncludeHandler(m_dllSupport);
+  pInclude->CallResults.emplace_back("", CP_ACP); // An empty file would get detected as ACP code page
+
+  VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"source.hlsl", L"main",
+                                      L"ps_6_0", nullptr, 0, nullptr, 0,
+                                      pInclude, &pResult));
+  VerifyOperationSucceeded(pResult);
+  VERIFY_ARE_EQUAL_WSTR(L"./empty.h;", pInclude->GetAllFileNames().c_str());
+}
+
 static const char EmptyCompute[] = "[numthreads(8,8,1)] void main() { }";
 
 TEST_F(CompilerTest, CompileWhenODumpThenPassConfig) {

+ 14 - 4
tools/clang/unittests/HLSL/DxcTestUtils.cpp

@@ -248,12 +248,22 @@ void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const char *pVal,
                                                 ppBlob));
 }
 
-void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val,
-                _Outptr_ IDxcBlobEncoding **ppBlob) {
+void MultiByteStringToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val,
+                           UINT32 codePage, _Outptr_ IDxcBlobEncoding **ppBlob) {
   CComPtr<IDxcLibrary> library;
   IFT(dllSupport.CreateInstance(CLSID_DxcLibrary, &library));
-  IFT(library->CreateBlobWithEncodingOnHeapCopy(val.data(), val.size(), CP_UTF8,
-                                                ppBlob));
+  IFT(library->CreateBlobWithEncodingOnHeapCopy(val.data(), val.size(),
+                                                codePage, ppBlob));
+}
+
+void MultiByteStringToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val,
+                           UINT32 codePage, _Outptr_ IDxcBlob **ppBlob) {
+  MultiByteStringToBlob(dllSupport, val, codePage, (IDxcBlobEncoding **)ppBlob);
+}
+
+void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val,
+                _Outptr_ IDxcBlobEncoding **ppBlob) {
+  MultiByteStringToBlob(dllSupport, val, CP_UTF8, ppBlob);
 }
 
 void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val,

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

@@ -118,6 +118,8 @@ bool CheckNotMsgs(const LPCSTR pText, size_t TextCount, const LPCSTR *pErrorMsgs
 void GetDxilPart(dxc::DxcDllSupport &dllSupport, IDxcBlob *pProgram, IDxcBlob **pDxilPart);
 std::string DisassembleProgram(dxc::DxcDllSupport &dllSupport, IDxcBlob *pProgram);
 void SplitPassList(LPWSTR pPassesBuffer, std::vector<LPCWSTR> &passes);
+void MultiByteStringToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, UINT32 codePoint, _Outptr_ IDxcBlob **ppBlob);
+void MultiByteStringToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, UINT32 codePoint, _Outptr_ IDxcBlobEncoding **ppBlob);
 void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, _Outptr_ IDxcBlob **ppBlob);
 void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const std::string &val, _Outptr_ IDxcBlobEncoding **ppBlob);
 void Utf8ToBlob(dxc::DxcDllSupport &dllSupport, const char *pVal, _Outptr_ IDxcBlobEncoding **ppBlob);