MSVC compatibility¶
When Clang compiles C++ code for Windows, it attempts to be compatible with MSVC. There are multiple dimensions to compatibility.
First, Clang attempts to be ABI-compatible, meaning that Clang-compiled code should be able to link against MSVC-compiled code successfully. However, C++ ABIs are particularly large and complicated, and Clang’s support for MSVC’s C++ ABI is a work in progress. If you don’t require MSVC ABI compatibility or don’t want to use Microsoft’s C and C++ runtimes, the mingw32 toolchain might be a better fit for your project.
Second, Clang implements many MSVC language extensions, such as __declspec(dllexport) and a handful of pragmas. These are typically controlled by -fms-extensions.
Third, MSVC accepts some C++ code that Clang will typically diagnose as invalid. When these constructs are present in widely included system headers, Clang attempts to recover and continue compiling the user’s program. Most parsing and semantic compatibility tweaks are controlled by -fms-compatibility and -fdelayed-template-parsing, and they are a work in progress.
Finally, there is clang-cl, a driver program for clang that attempts to be compatible with MSVC’s cl.exe.
ABI features¶
The status of major ABI-impacting C++ features:
- Record layout: Complete. We’ve tested this with a fuzzer and have fixed all known bugs.
- Class inheritance: Mostly complete. This covers all of the standard OO features you would expect: virtual method inheritance, multiple inheritance, and virtual inheritance. Every so often we uncover a bug where our tables are incompatible, but this is pretty well in hand. This feature has also been fuzz tested.
- Name mangling: Ongoing. Every new C++ feature generally needs its own mangling. For example, member pointer template arguments have an interesting and distinct mangling. Fortunately, incorrect manglings usually do not result in runtime errors. Non-inline functions with incorrect manglings usually result in link errors, which are relatively easy to diagnose. Incorrect manglings for inline functions and templates result in multiple copies in the final image. The C++ standard requires that those addresses be equal, but few programs rely on this.
- Member pointers: Mostly complete. Standard C++ member pointers are fully implemented and should be ABI compatible. Both #pragma pointers_to_members and the /vm flags are supported. However, MSVC supports an extension to allow creating a pointer to a member of a virtual base class. Clang does not yet support this.
- Debug info: Minimal. Clang emits CodeView line tables into the object file, similar to what MSVC emits when given the /Z7 flag. Microsoft’s link.exe will read this information and use it to create a PDB, enabling stack traces in all modern Windows debuggers. Clang does not emit any type info or description of variable layout.
- RTTI: Complete. Generation of RTTI data structures has been finished, along with support for the /GR flag.
- Exceptions and SEH: Unstarted. Clang can parse both constructs, but does not know how to emit compatible handlers.
- Thread-safe initialization of local statics: Unstarted. We are ABI compatible with MSVC 2013, which does not support thread-safe local statics. MSVC “14” changed the ABI to make initialization of local statics thread safe, and we have not yet implemented this.
- Lambdas: Mostly complete. Clang is compatible with Microsoft’s implementation of lambdas except for providing overloads for conversion to function pointer for different calling conventions. However, Microsoft’s extension is non-conforming.
Template instantiation and name lookup¶
MSVC allows many invalid constructs in class templates that Clang has historically rejected. In order to parse widely distributed headers for libraries such as the Active Template Library (ATL) and Windows Runtime Library (WRL), some template rules have been relaxed or extended in Clang on Windows.
The first major semantic difference is that MSVC appears to defer all parsing an analysis of inline method bodies in class templates until instantiation time. By default on Windows, Clang attempts to follow suit. This behavior is controlled by the -fdelayed-template-parsing flag. While Clang delays parsing of method bodies, it still parses the bodies before template argument substitution, which is not what MSVC does. The following compatibility tweaks are necessary to parse the the template in those cases.
MSVC allows some name lookup into dependent base classes. Even on other platforms, this has been a frequently asked question for Clang users. A dependent base class is a base class that depends on the value of a template parameter. Clang cannot see any of the names inside dependent bases while it is parsing your template, so the user is sometimes required to use the typename keyword to assist the parser. On Windows, Clang attempts to follow the normal lookup rules, but if lookup fails, it will assume that the user intended to find the name in a dependent base. While parsing the following program, Clang will recover as if the user had written the commented-out code:
template <typename T>
struct Foo : T {
void f() {
/*typename*/ T::UnknownType x = /*this->*/unknownMember;
}
};
After recovery, Clang warns the user that this code is non-standard and issues a hint suggesting how to fix the problem.
As of this writing, Clang is able to compile a simple ATL hello world application. There are still issues parsing WRL headers for modern Windows 8 apps, but they should be addressed soon.