compilers: clang-cl: Also accept .s files (#8520)

* compilers: clang-cl: Also accept .s files

clang-cl has support for gas-compatible assembly files.

* Add clang-cl to '128 generated assembly' test
diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py
index 2b173eb..763d030 100644
--- a/mesonbuild/compilers/mixins/visualstudio.py
+++ b/mesonbuild/compilers/mixins/visualstudio.py
@@ -412,6 +412,9 @@
         super().__init__(target)
         self.id = 'clang-cl'
 
+        # Assembly
+        self.can_compile_suffixes.add('s')
+
     def has_arguments(self, args: T.List[str], env: 'Environment', code: str, mode: str) -> T.Tuple[bool, bool]:
         if mode != 'link':
             args = args + ['-Werror=unknown-argument']
diff --git a/test cases/common/128 generated assembly/empty.c b/test cases/common/128 generated assembly/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/128 generated assembly/empty.c
diff --git a/test cases/common/128 generated assembly/meson.build b/test cases/common/128 generated assembly/meson.build
index 89b680d..b256630 100644
--- a/test cases/common/128 generated assembly/meson.build
+++ b/test cases/common/128 generated assembly/meson.build
@@ -6,10 +6,25 @@
   error('MESON_SKIP_TEST: Cygwin is broken and nobody knows how to fix it. Patches welcome.')
 endif
 
-if ['msvc', 'clang-cl', 'intel-cl'].contains(cc.get_id())
+if ['msvc', 'intel-cl'].contains(cc.get_id())
   error('MESON_SKIP_TEST: assembly files cannot be compiled directly by the compiler')
 endif
 
+crt_workaround = []
+if cc.get_linker_id() == 'lld-link'
+  # It seems that when building without a .c file, lld-link.exe
+  # misses the fact that it needs to include the c runtime to
+  # make a working .dll. So here we add an empty .c file to easily
+  # pull in crt.
+  crt_workaround += 'empty.c'
+  if host_machine.cpu_family() == 'x86'
+    # x86 assembly needs manual annotation to be compatible with
+    # Safe Exception Handlers (?) This assembly doesn't have such
+    # annotation, so just disable the feature.
+    add_project_link_arguments('/SAFESEH:NO', language : 'c')
+  endif
+endif
+
 cpu = host_machine.cpu_family()
 supported_cpus = ['arm', 'x86', 'x86_64']
 
@@ -17,6 +32,11 @@
   error('MESON_SKIP_TEST: unsupported cpu family: ' + cpu)
 endif
 
+if cc.get_id() == 'clang-cl' and cc.version().version_compare('< 12.0.0') and cpu == 'arm'
+  # https://reviews.llvm.org/D89622
+  error('MESON_SKIP_TEST: arm debug symbols not supported in clang-cl < 12.0.0')
+endif
+
 if cc.symbols_have_underscore_prefix()
   add_project_arguments('-DMESON_TEST__UNDERSCORE_SYMBOL', language : 'c')
 endif
@@ -29,7 +49,8 @@
   arguments : ['@INPUT@', '@OUTPUT@'],
   output : '@BASENAME@')
 
-l = shared_library('square-gen', copygen.process(input))
+l = shared_library('square-gen', crt_workaround + [copygen.process(input)],
+  vs_module_defs: 'square.def')
 
 test('square-gen-test', executable('square-gen-test', 'main.c', link_with : l))
 
@@ -38,6 +59,7 @@
   output : output,
   command : [copy, '@INPUT@', '@OUTPUT@'])
 
-l = shared_library('square-ct', copyct)
+l = shared_library('square-ct', crt_workaround + [copyct],
+  vs_module_defs: 'square.def')
 
 test('square-ct-test', executable('square-ct-test', 'main.c', link_with : l))
diff --git a/test cases/common/128 generated assembly/square-x86.S.in b/test cases/common/128 generated assembly/square-x86.S.in
index ee77b81..1a48fc4 100644
--- a/test cases/common/128 generated assembly/square-x86.S.in
+++ b/test cases/common/128 generated assembly/square-x86.S.in
@@ -1,6 +1,6 @@
 #include "symbol-underscore.h"
 
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(__clang__)
 
 .386
 .MODEL FLAT, C
diff --git a/test cases/common/128 generated assembly/square-x86_64.S.in b/test cases/common/128 generated assembly/square-x86_64.S.in
index b2cf3eb..d504341 100644
--- a/test cases/common/128 generated assembly/square-x86_64.S.in
+++ b/test cases/common/128 generated assembly/square-x86_64.S.in
@@ -1,6 +1,6 @@
 #include "symbol-underscore.h"
 
-#ifdef _MSC_VER /* MSVC on Windows */
+#if defined(_MSC_VER) && !defined(__clang__) /* MSVC on Windows */
 
 PUBLIC SYMBOL_NAME(square_unsigned)
 _TEXT   SEGMENT
diff --git a/test cases/common/128 generated assembly/square.def b/test cases/common/128 generated assembly/square.def
new file mode 100644
index 0000000..79f3d65
--- /dev/null
+++ b/test cases/common/128 generated assembly/square.def
@@ -0,0 +1,2 @@
+EXPORTS
+	square_unsigned