LLVM Project News and Details from the Trenches

Tuesday, November 5, 2013

The clang-cl /fallback mode

There has been a lot of work lately towards bringing an LLVM toolchain to the Windows platform (see A path forward for an LLVM toolchain on Windows). One result of that work is a new driver mode for Clang: clang-cl. This mode makes Clang understand the same kind of command-line arguments as Visual Studio's compiler, cl.exe. For example, a typical command to compile a file into an executable with Clang might be "clang hello.cc -o hello", whereas with cl.exe, one would use "cl.exe hello.cc /Fehello". Now one can use the latter syntax with Clang by substituting "cl.exe" with "clang-cl". This makes it easy to use Clang for existing projects in Visual Studio.

For the most part, clang-cl accepts exactly the same arguments as cl.exe. However, it also accepts some Clang-specific options. One such option that was added recently is the /fallback flag. The purpose of this flag is to make it easy to use clang-cl even in projects where Clang cannot yet compile all of the code. This post gives an example of how /fallback can be used.

The way clang-cl works in /fallback mode is that it first tries to compile the code with Clang, and if that fails for some reason it falls back to compiling with cl.exe. Consider the following two files, where main.cpp can be compiled by Clang, but printer.cpp cannot:

printer.cpp:

#include <iostream>
void print_hello(const char *s) {
  std::cout << "Hello from " << s << "!" << std::endl;
}
main.cpp:

extern void print_hello(const char*);
int main(int argc, char **argv) {
  print_hello(argv[0]);
  return 0;
}

clang-cl cannot compile printer.cpp since it includes iostream which uses language features that are not completely supported yet (hopefully they will be soon). However, clang-cl can still compile the two files in fallback mode:

clang-cl /fallback /Fehello main.cpp printer.cpp

Clang will compile main.cpp successfully, print some error messages about the features it does not support for printer.cpp, and fall back to the cl.exe compiler for that file. The compiled files will be linked together into hello.exe.

Note that this is not fool proof: even if clang-cl thinks it has compiled a file successfully, there can be bugs in the generated code that cause failures at link- or run-time.

Currently, the fallback mode will cause clang-cl to fall back on any kind of error. Going forward, it will be changed to only fall back on certain kinds of internal errors, and as Clang's Windows support improves, the fallback mode will eventually become unnecessary and removed. It is still early days for clang-cl, but you can try it out for yourself by downloading the toolchain from the LLVM Snapshot Builds website.