Various fixes for Win32 CTS coverage

Change-Id: I68032ef724fbbe5c6299c3724de6c908fcb520af
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/171101
Commit-Queue: Ben Clayton <bclayton@google.com>
Auto-Submit: Ben Clayton <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bfebca8..79b2f7a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -572,6 +572,10 @@
 # Run on all subdirectories
 ################################################################################
 if (EXISTS "${DAWN_PROTOBUF_DIR}/cmake")
+  if (("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") AND WIN32)
+    set(protobuf_HAVE_BUILTIN_ATOMICS 1)
+  endif()
+
   # Needs to come before SPIR-V Tools
   include("third_party/protobuf.cmake")
 endif()
@@ -619,4 +623,3 @@
     COMMENT "Generating tint coverage data"
     VERBATIM)
 endif()
-
diff --git a/src/dawn/node/cts.js b/src/dawn/node/cts.js
index 47111cb..fd3e1ab 100644
--- a/src/dawn/node/cts.js
+++ b/src/dawn/node/cts.js
@@ -1,7 +1,7 @@
 'use strict';
 
-const { create, globals } = require('./dawn.node');
+const { create, coverage, globals } = require('./dawn.node');
 
 Object.assign(globalThis, globals);
 
-module.exports = { create };
+module.exports = { create, coverage };
diff --git a/src/dawn/node/index.js b/src/dawn/node/index.js
index b70e421..40d7520 100644
--- a/src/dawn/node/index.js
+++ b/src/dawn/node/index.js
@@ -1,8 +1,9 @@
 'use strict';
 
-const { create, globals } = require('./dawn.node');
+const { create, coverage, globals } = require('./dawn.node');
 
 module.exports = {
   ...globals,
+  coverage,
   gpu: create(process.env.DAWN_FLAGS?.split(',') || []),
 };
diff --git a/src/tint/cmd/fuzz/ir/fuzz.h b/src/tint/cmd/fuzz/ir/fuzz.h
index 183ebe1..533cac4 100644
--- a/src/tint/cmd/fuzz/ir/fuzz.h
+++ b/src/tint/cmd/fuzz/ir/fuzz.h
@@ -81,7 +81,7 @@
 
 /// Registers the fuzzer function with the IR fuzzer executable.
 /// @param fuzzer the fuzzer
-void Register(const IRFuzzer& fuzzer);
+void Register([[maybe_unused]] const IRFuzzer& fuzzer);
 
 /// TINT_IR_MODULE_FUZZER registers the fuzzer function.
 #define TINT_IR_MODULE_FUZZER(FUNCTION) \
diff --git a/tools/generate-coverage b/tools/generate-coverage
index 6d437f4..f1ea741 100644
--- a/tools/generate-coverage
+++ b/tools/generate-coverage
@@ -50,8 +50,8 @@
 ninja
 popd
 
-./tools/run run-cts --export-coverage ./out/coverage/win_api_operation.dat --dawn-node ./out/coverage/dawn.node 'webgpu:api,operation,*'
-./tools/run run-cts --export-coverage ./out/coverage/win_api_validation.dat --dawn-node ./out/coverage/dawn.node 'webgpu:api,validation,*'
-./tools/run run-cts --export-coverage ./out/coverage/win_shader_execution.dat --dawn-node ./out/coverage/dawn.node 'webgpu:shader,execution,*'
-./tools/run run-cts --export-coverage ./out/coverage/win_shader_validation.dat --dawn-node ./out/coverage/dawn.node 'webgpu:shader,validation,*'
-./tools/run run-cts --export-coverage ./out/coverage/win.dat --dawn-node ./out/coverage/dawn.node 'webgpu:*'
+./tools/run run-cts --export-coverage ./out/coverage/win_api_operation.dat --bin ./out/coverage 'webgpu:api,operation,*'
+./tools/run run-cts --export-coverage ./out/coverage/win_api_validation.dat --bin ./out/coverage 'webgpu:api,validation,*'
+./tools/run run-cts --export-coverage ./out/coverage/win_shader_execution.dat --bin ./out/coverage 'webgpu:shader,execution,*'
+./tools/run run-cts --export-coverage ./out/coverage/win_shader_validation.dat --bin ./out/coverage 'webgpu:shader,validation,*'
+./tools/run run-cts --export-coverage ./out/coverage/win.dat --bin ./out/coverage 'webgpu:*'
diff --git a/tools/src/cmd/run-cts/node/cmd.go b/tools/src/cmd/run-cts/node/cmd.go
index b810bbb..6611a2f 100644
--- a/tools/src/cmd/run-cts/node/cmd.go
+++ b/tools/src/cmd/run-cts/node/cmd.go
@@ -271,7 +271,7 @@
 }
 
 func (c *cmd) maybeInitCoverage() error {
-	if c.flags.coverageFile == "" {
+	if !c.flags.genCoverage && c.flags.coverageFile == "" {
 		return nil
 	}
 
@@ -303,7 +303,7 @@
 		OutputFile: c.flags.coverageFile,
 		Env: &cov.Env{
 			Profdata: profdata,
-			Binary:   c.flags.bin,
+			Binary:   filepath.Join(c.flags.bin, "dawn.node"),
 			Cov:      llvmCov,
 			TurboCov: turboCov,
 		},
diff --git a/tools/src/cmd/turbo-cov/CMakeLists.txt b/tools/src/cmd/turbo-cov/CMakeLists.txt
index 381439b..d48f21b 100644
--- a/tools/src/cmd/turbo-cov/CMakeLists.txt
+++ b/tools/src/cmd/turbo-cov/CMakeLists.txt
@@ -29,6 +29,11 @@
 
 if (LLVM_SOURCE_DIR)
     set(LLVM_INCLUDE_TESTS OFF)
+    if (("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") AND WIN32)
+        set(HAVE_CXX_ATOMICS_WITHOUT_LIB TRUE)
+        set(HAVE_CXX_ATOMICS64_WITHOUT_LIB TRUE)
+        set(LLVM_HOST_TRIPLE "x86_64-pc-win32")
+    endif()
     set(LLVM_TARGETS_TO_BUILD "X86") # At least one target needs to be provided
     add_subdirectory("${LLVM_SOURCE_DIR}" "llvm" EXCLUDE_FROM_ALL)
 
diff --git a/tools/src/cmd/turbo-cov/main.cpp b/tools/src/cmd/turbo-cov/main.cpp
index eeb1e8a..efe115d 100644
--- a/tools/src/cmd/turbo-cov/main.cpp
+++ b/tools/src/cmd/turbo-cov/main.cpp
@@ -36,6 +36,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
 #include "llvm/ProfileData/InstrProfReader.h"
+#include "llvm/Support/VirtualFileSystem.h"
 
 #if defined(_MSC_VER)
 #include <fcntl.h>  // _O_BINARY
@@ -72,8 +73,8 @@
 
     auto exe = argv[1];
     auto profdata = argv[2];
-
-    auto res = llvm::coverage::CoverageMapping::load({exe}, profdata);
+    auto filesystem = llvm::vfs::getRealFileSystem();
+    auto res = llvm::coverage::CoverageMapping::load({exe}, profdata, *filesystem);
     if (auto E = res.takeError()) {
         fprintf(stderr, "failed to load executable '%s': %s\n", exe,
                 llvm::toString(std::move(E)).c_str());
diff --git a/tools/src/fileutils/fileutils_windows.go b/tools/src/fileutils/fileutils_windows.go
index a8663c1..7e897e9 100644
--- a/tools/src/fileutils/fileutils_windows.go
+++ b/tools/src/fileutils/fileutils_windows.go
@@ -28,9 +28,14 @@
 // Package fileutils contains utility functions for files
 package fileutils
 
+import "os"
+
 const ExeExt = ".exe"
 
 // IsExe returns true if the file at path is an executable
 func IsExe(path string) bool {
+	if _, err := os.Stat(path); err != nil {
+		return false
+	}
 	return true
 }