From 46ac6474ea4f5592863dbcb295e53080b2e56086 Mon Sep 17 00:00:00 2001
From: Allan Jensen <allan.jensen@qt.io>
Date: Fri, 29 Mar 2019 17:27:19 +0100
Subject: [PATCH] Support clang_cl builds on Windows

Change-Id: I1f3e8fc378cfceda92ff17fcc7669c0f5d97c3f7
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
---
 mkspecs/features/gn_generator.prf      |  7 ++++++-
 mkspecs/features/platform.prf          |  2 +-
 src/buildtools/gn.pro                  | 10 +++++++---
 src/core/config/linux.pri              |  3 +--
 src/core/config/windows.pri            | 20 +++++++++++++++++---
 src/core/core_chromium.pri             |  5 +++++
 src/core/core_module.pro               |  4 ++--
 src/webengine/ui_delegates_manager.cpp |  2 +-
 8 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/mkspecs/features/gn_generator.prf b/mkspecs/features/gn_generator.prf
index 4efbd92f2..78b56d123 100644
--- a/mkspecs/features/gn_generator.prf
+++ b/mkspecs/features/gn_generator.prf
@@ -120,13 +120,18 @@ GN_CONTENTS += "config(\"$${TARGET}_config\") {"
 }
 
 # Stop the barrage of unused variables warnings.
-gcc|clang {
+gcc|clang|clang_cl {
     QMAKE_CXXFLAGS += "-Wno-unused-parameter"
     QMAKE_CXXFLAGS += "-Wno-unused-variable"
 } else:msvc {
     QMAKE_CXXFLAGS += /wd4100 /wd4101
 }
 
+# Chromium activates this, but we need it off to be able to compile QFlags
+clang_cl {
+    QMAKE_CXXFLAGS += "-fno-complete-member-pointers"
+}
+
 !isEmpty(QMAKE_CXXFLAGS) {
     GN_CONTENTS += "  cflags_cc = ["
     for(flag, QMAKE_CXXFLAGS): GN_CONTENTS += "    \"$$filter_flag_values($$flag)\","
diff --git a/mkspecs/features/platform.prf b/mkspecs/features/platform.prf
index 35eb6b89c..67be73f74 100644
--- a/mkspecs/features/platform.prf
+++ b/mkspecs/features/platform.prf
@@ -26,7 +26,7 @@ defineTest(isPlatformSupported) {
       skipBuild("Qt WebEngine on Windows must be built on a 64-bit machine.")
     }
     !msvc|intel_icl {
-      skipBuild("Qt WebEngine on Windows requires MSVC.")
+      skipBuild("Qt WebEngine on Windows requires MSVC or Clang (MSVC mode).")
       return(false)
     }
     !isMinWinSDKVersion(10, 16299): {
diff --git a/src/buildtools/gn.pro b/src/buildtools/gn.pro
index 30ada9357..b6bf9cfc4 100644
--- a/src/buildtools/gn.pro
+++ b/src/buildtools/gn.pro
@@ -18,9 +18,13 @@ build_pass|!debug_and_release {
             src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT")
             gn_bootstrap = $$system_path($$absolute_path(gn/build/gen.py, $$src_3rd_party_dir))
 
-            gn_configure = $$system_quote($$gn_bootstrap) --no-last-commit-position --out-path $$out_path \
-                           --cc \"$$which($$QMAKE_CC)\" --cxx \"$$which($$QMAKE_CXX)\" \
-                           --ld \"$$which($$QMAKE_LINK)\"
+            gn_gen_args = --no-last-commit-position --out-path $$out_path \
+                          --cc \"$$which($$QMAKE_CC)\" --cxx \"$$which($$QMAKE_CXX)\" \
+                          --ld \"$$which($$QMAKE_LINK)\"
+
+            msvc:!clang_cl: gn_gen_args += --use-lto
+
+            gn_configure = $$system_quote($$gn_bootstrap) $$gn_gen_args
             macos {
                 gn_configure += --isysroot \"$$QMAKE_MAC_SDK_PATH\"
             }
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
index 3eb436910..95b7a4bda 100644
--- a/src/core/config/linux.pri
+++ b/src/core/config/linux.pri
@@ -36,8 +36,7 @@ clang {
     gn_args += \
         is_clang=true \
         clang_use_chrome_plugins=false \
-        clang_base_path=\"$${clang_prefix}\" \
-        use_lld=false
+        clang_base_path=\"$${clang_prefix}\"
 
     linux-clang-libc++: gn_args += use_libcxx=true
 } else {
diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri
index 9eb15830d..b934ea475 100644
--- a/src/core/config/windows.pri
+++ b/src/core/config/windows.pri
@@ -1,7 +1,6 @@
 include(common.pri)
 
 gn_args += \
-    is_clang=false \
     use_sysroot=false \
     enable_session_service=false \
     ninja_use_custom_environment_files=false \
@@ -9,6 +8,22 @@ gn_args += \
     win_linker_timing=true \
     com_init_check_hook_disabled=true
 
+use_lld_linker: gn_args += use_lld=true
+else: gn_args += use_lld=false
+
+clang_cl {
+    clang_full_path = $$system_path($$which($${QMAKE_CXX}))
+    # Remove the "\bin\clang-cl.exe" part:
+    clang_dir = $$dirname(clang_full_path)
+    clang_prefix = $$join(clang_dir,,,"\..")
+    gn_args += \
+        is_clang=true \
+        clang_use_chrome_plugins=false \
+        clang_base_path=$$system_quote($$system_path($$clean_path($$clang_prefix)))
+} else {
+    gn_args += is_clang=false
+}
+
 isDeveloperBuild() {
     gn_args += \
         is_win_fastlink=true
@@ -69,7 +84,6 @@ msvc {
 
     GN_TARGET_CPU = $$gnArch($$QT_ARCH)
     gn_args += target_cpu=\"$$GN_TARGET_CPU\"
-
 } else {
-    error("Qt WebEngine for Windows can only be built with the Microsoft Visual Studio C++ compiler")
+    error("Qt WebEngine for Windows can only be built with a Microsoft Visual Studio C++ compatible compiler")
 }
diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri
index 89fb40864..3f4266c8c 100644
--- a/src/core/core_chromium.pri
+++ b/src/core/core_chromium.pri
@@ -37,6 +37,11 @@ qtConfig(egl): CONFIG += egl
 
 INCLUDEPATH += $$PWD $$PWD/api
 
+clang_cl {
+    QMAKE_CFLAGS -= $$QMAKE_CFLAGS_MSVC_COMPAT
+    QMAKE_CXXFLAGS -= $$QMAKE_CFLAGS_MSVC_COMPAT
+}
+
 SOURCES = \
         accessibility_activation_observer.cpp \
         accessibility_tree_formatter_qt.cpp \
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index 3b5d37f29..e2fa3494d 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -55,7 +55,7 @@ LIBS_PRIVATE += -L$$api_library_path
 CONFIG *= no_smart_library_merge
 osx {
     LIBS_PRIVATE += -Wl,-force_load,$${api_library_path}$${QMAKE_DIR_SEP}lib$${api_library_name}.a
-} else:msvc {
+} else: win32 {
     !isDeveloperBuild() {
         # Remove unused functions and data in debug non-developer builds, because the binaries will
         # be smaller in the shipped packages.
@@ -74,7 +74,7 @@ osx {
     LIBS_PRIVATE += -Wl,-whole-archive -l$$api_library_name -Wl,-no-whole-archive
 }
 
-win32-msvc* {
+win32 {
     POST_TARGETDEPS += $${api_library_path}$${QMAKE_DIR_SEP}$${api_library_name}.lib
 } else {
     POST_TARGETDEPS += $${api_library_path}$${QMAKE_DIR_SEP}lib$${api_library_name}.a
diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp
index a30fa7b98..2f371efd5 100644
--- a/src/webengine/ui_delegates_manager.cpp
+++ b/src/webengine/ui_delegates_manager.cpp
@@ -64,7 +64,7 @@
 namespace QtWebEngineCore {
 
 #define NO_SEPARATOR
-#if defined(Q_OS_WIN)
+#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
 #define FILE_NAME_CASE_STATEMENT(TYPE, COMPONENT) \
     case UIDelegatesManager::TYPE:\
         return QString::fromLatin1(#TYPE ##".qml");
-- 
GitLab