@@ -192,6 +192,7 @@ class CompilerTest : public ::testing::Test {
192192 TEST_METHOD (CompileWhenIncludeLocalThenLoadRelative)
193193 TEST_METHOD (CompileWhenIncludeSystemThenLoadNotRelative)
194194 TEST_METHOD (CompileWhenAllIncludeCombinations)
195+ TEST_METHOD (TestPdbUtilsPathNormalizations)
195196 TEST_METHOD (CompileWhenIncludeSystemMissingThenLoadAttempt)
196197 TEST_METHOD (CompileWhenIncludeFlagsThenIncludeUsed)
197198 TEST_METHOD (CompileThenCheckDisplayIncludeProcess)
@@ -2884,50 +2885,148 @@ TEST_F(CompilerTest, CompileWhenIncludeThenLoadUsed) {
28842885 pInclude->GetAllFileNames ().c_str ());
28852886}
28862887
2887- TEST_F (CompilerTest, CompileWhenAllIncludeCombinations) {
2888- static auto NormalizeForPlatform = [](const std::wstring &s) -> std::wstring {
2888+ static std::wstring NormalizeForPlatform (const std::wstring &s) {
28892889#ifdef _WIN32
2890- wchar_t From = L' /' ;
2891- wchar_t To = L' \\ ' ;
2890+ wchar_t From = L' /' ;
2891+ wchar_t To = L' \\ ' ;
28922892#else
2893- wchar_t From = L' \\ ' ;
2894- wchar_t To = L' /' ;
2893+ wchar_t From = L' \\ ' ;
2894+ wchar_t To = L' /' ;
28952895#endif
2896- std::wstring ret = s;
2897- for (wchar_t &c : ret) {
2898- if (c == From)
2899- c = To;
2896+ std::wstring ret = s;
2897+ for (wchar_t &c : ret) {
2898+ if (c == From)
2899+ c = To;
2900+ }
2901+ return ret;
2902+ };
2903+
2904+ class SimpleIncludeHanlder : public IDxcIncludeHandler {
2905+ DXC_MICROCOM_REF_FIELD (m_dwRef)
2906+ public:
2907+ DXC_MICROCOM_ADDREF_RELEASE_IMPL (m_dwRef)
2908+ dxc::DxcDllSupport &m_dllSupport;
2909+ HRESULT m_defaultErrorCode = E_FAIL;
2910+ SimpleIncludeHanlder (dxc::DxcDllSupport &dllSupport)
2911+ : m_dwRef(0 ), m_dllSupport(dllSupport) {}
2912+ HRESULT STDMETHODCALLTYPE QueryInterface (REFIID iid,
2913+ void **ppvObject) override {
2914+ return DoBasicQueryInterface<IDxcIncludeHandler>(this , iid, ppvObject);
2915+ }
2916+
2917+ std::wstring Path;
2918+ std::string Content;
2919+
2920+ HRESULT STDMETHODCALLTYPE LoadSource (
2921+ LPCWSTR pFilename, // Filename as written in #include statement
2922+ IDxcBlob **ppIncludeSource // Resultant source object for included file
2923+ ) override {
2924+ if (pFilename == Path) {
2925+ MultiByteStringToBlob (m_dllSupport, Content, CP_UTF8, ppIncludeSource);
2926+ return S_OK;
29002927 }
2901- return ret;
2928+ return E_FAIL;
2929+ }
2930+ };
2931+
2932+ TEST_F (CompilerTest, TestPdbUtilsPathNormalizations) {
2933+ #include " TestHeaders/TestPdbUtilsPathNormalizations.h"
2934+ struct TestCase {
2935+ std::string MainName;
2936+ std::string IncludeName;
29022937 };
29032938
2904- class SimpleIncludeHanlder : public IDxcIncludeHandler {
2905- DXC_MICROCOM_REF_FIELD (m_dwRef)
2906- public:
2907- DXC_MICROCOM_ADDREF_RELEASE_IMPL (m_dwRef)
2908- dxc::DxcDllSupport &m_dllSupport;
2909- HRESULT m_defaultErrorCode = E_FAIL;
2910- SimpleIncludeHanlder (dxc::DxcDllSupport &dllSupport)
2911- : m_dwRef(0 ), m_dllSupport(dllSupport) {}
2912- HRESULT STDMETHODCALLTYPE QueryInterface (REFIID iid,
2913- void **ppvObject) override {
2914- return DoBasicQueryInterface<IDxcIncludeHandler>(this , iid, ppvObject);
2915- }
2939+ TestCase tests[] = {
2940+ {R"( main.hlsl)" , R"( include.h)" },
2941+ {R"( .\5Cmain.hlsl)" , R"( .\5Cinclude.h)" },
2942+ {R"( /path/main.hlsl)" , R"( /path/include.h)" },
2943+ {R"( \5Cpath/main.hlsl)" , R"( \5Cpath\5Cinclude.h)" },
2944+ {R"( ..\5Cmain.hlsl)" , R"( ..\5Cinclude.h)" },
2945+ {R"( ..\5Cdir\5Cmain.hlsl)" , R"( ..\5Cdir\5Cinclude.h)" },
2946+ {R"( F:\5C\5Cdir\5Cmain.hlsl)" , R"( F:\5C\5Cdir\5Cinclude.h)" },
2947+ {R"( \5C\5Cdir\5Cmain.hlsl)" , R"( \5C\5Cdir\5Cinclude.h)" },
2948+ {R"( \5C\5C\5Cdir\5Cmain.hlsl)" , R"( \5C\5C\5Cdir\5Cinclude.h)" },
2949+ {R"( //dir\5Cmain.hlsl)" , R"( //dir/include.h)" },
2950+ {R"( ///dir/main.hlsl)" , R"( ///dir\5Cinclude.h)" },
2951+ };
29162952
2917- std::wstring Path;
2918- std::string Content ;
2953+ for (TestCase &test : tests) {
2954+ std::string oldPdb = kTestPdbUtilsPathNormalizationsIR ;
29192955
2920- HRESULT STDMETHODCALLTYPE LoadSource (
2921- LPCWSTR pFilename, // Filename as written in #include statement
2922- IDxcBlob **ppIncludeSource // Resultant source object for included file
2923- ) override {
2924- if (pFilename == NormalizeForPlatform (Path)) {
2925- MultiByteStringToBlob (m_dllSupport, Content, CP_UTF8, ppIncludeSource);
2926- return S_OK;
2927- }
2928- return E_FAIL;
2956+ size_t findPos = std::string::npos;
2957+ std::string mainPattern = " <MAIN_FILE>" ;
2958+ std::string includePattern = " <INCLUDE_FILE>" ;
2959+ while ((findPos = oldPdb.find (mainPattern)) != std::string::npos) {
2960+ oldPdb.replace (oldPdb.begin () + findPos,
2961+ oldPdb.begin () + findPos + mainPattern.size (),
2962+ test.MainName );
29292963 }
2930- };
2964+ while ((findPos = oldPdb.find (includePattern)) != std::string::npos) {
2965+ oldPdb.replace (oldPdb.begin () + findPos,
2966+ oldPdb.begin () + findPos + includePattern.size (),
2967+ test.IncludeName );
2968+ }
2969+
2970+ CComPtr<IDxcAssembler> pAssembler;
2971+ VERIFY_SUCCEEDED (
2972+ m_dllSupport.CreateInstance (CLSID_DxcAssembler, &pAssembler));
2973+ CComPtr<IDxcUtils> pUtils;
2974+ VERIFY_SUCCEEDED (m_dllSupport.CreateInstance (CLSID_DxcUtils, &pUtils));
2975+
2976+ CComPtr<IDxcBlobEncoding> pBlobEncoding;
2977+ VERIFY_SUCCEEDED (pUtils->CreateBlobFromPinned (oldPdb.data (), oldPdb.size (),
2978+ CP_UTF8, &pBlobEncoding));
2979+
2980+ CComPtr<IDxcOperationResult> pOpResult;
2981+ VERIFY_SUCCEEDED (
2982+ pAssembler->AssembleToContainer (pBlobEncoding, &pOpResult));
2983+ VerifyOperationSucceeded (pOpResult);
2984+ CComPtr<IDxcBlob> pDxil;
2985+ VERIFY_SUCCEEDED (pOpResult->GetResult (&pDxil));
2986+
2987+ CComPtr<IDxcPdbUtils> pPdbUtils;
2988+ VERIFY_SUCCEEDED (
2989+ m_dllSupport.CreateInstance (CLSID_DxcPdbUtils, &pPdbUtils));
2990+ VERIFY_SUCCEEDED (pPdbUtils->Load (pDxil));
2991+
2992+ CComBSTR pMainName;
2993+ CComBSTR pIncludeName;
2994+ CComBSTR pMainName2;
2995+ CComPtr<IDxcBlobEncoding> pIncludeContent;
2996+ CComPtr<IDxcBlobEncoding> pMainContent;
2997+ VERIFY_SUCCEEDED (pPdbUtils->GetSourceName (0 , &pMainName));
2998+ VERIFY_SUCCEEDED (pPdbUtils->GetSourceName (1 , &pIncludeName));
2999+ VERIFY_SUCCEEDED (pPdbUtils->GetMainFileName (&pMainName2));
3000+ VERIFY_SUCCEEDED (pPdbUtils->GetSource (0 , &pMainContent));
3001+ VERIFY_SUCCEEDED (pPdbUtils->GetSource (1 , &pIncludeContent));
3002+
3003+ VERIFY_ARE_EQUAL (0 , wcscmp (pMainName.m_str , pMainName2.m_str ));
3004+
3005+ CComPtr<IDxcBlobUtf8> pMainContentUtf8;
3006+ CComPtr<IDxcBlobUtf8> pIncludeContentUtf8;
3007+ VERIFY_SUCCEEDED (pMainContent.QueryInterface (&pMainContentUtf8));
3008+ VERIFY_SUCCEEDED (pIncludeContent.QueryInterface (&pIncludeContentUtf8));
3009+
3010+ CComPtr<SimpleIncludeHanlder> pRecompileInclude =
3011+ new SimpleIncludeHanlder (m_dllSupport);
3012+ pRecompileInclude->Content =
3013+ std::string (pIncludeContentUtf8->GetStringPointer (),
3014+ pIncludeContentUtf8->GetStringLength ());
3015+ pRecompileInclude->Path = pIncludeName;
3016+
3017+ CComPtr<IDxcOperationResult> pRecompileOpResult;
3018+ const WCHAR *args[] = {L" -Zi" };
3019+
3020+ CComPtr<IDxcCompiler> pCompiler;
3021+ VERIFY_SUCCEEDED (CreateCompiler (&pCompiler));
3022+ VERIFY_SUCCEEDED (pCompiler->Compile (
3023+ pMainContentUtf8, pMainName, L" main" , L" ps_6_0" , args, _countof (args),
3024+ nullptr , 0 , pRecompileInclude, &pRecompileOpResult));
3025+ VerifyOperationSucceeded (pRecompileOpResult);
3026+ }
3027+ }
3028+
3029+ TEST_F (CompilerTest, CompileWhenAllIncludeCombinations) {
29313030 struct File {
29323031 std::wstring name;
29333032 std::string content;
0 commit comments