Clang-tidy on Windows with Visual Studio defining __clang__?

I have followed the instructions on How To Setup Clang Tooling For LLVM — Clang 16.0.0git documentation under Setup Clang Tooling Using CMake on Windows to generate a compile_commands.json file for running clang-tidy on the command line in Windows. However, when I run it on some of our code that happens to have a block of code controlled by ‘#if defined(clang)’ it is taking that branch of the preprocessed code, even though my compile_commands.json is using the Visual Studio compiler, and nowhere is clang defined on the command lines.

Am I right in thinking that clang-tidy is defining that clang internally? If so, is there any way to disable that behaviour? I tried adding ‘-- /U__clang__’ at the end of the command line but that did nothing.

This is expected behavior – clang-tidy uses clang under the hood to perform compilation, and there’s no way to disable that. You’ll have to modify the preprocessor condition check instead.

1 Like

It does seem like a reasonable use-case though, with Microsoft packaging more clang tooling with Visual Studio (I know clang-format has been there for a while).
You could file an issue asking for the feature.

Not sure this would be a good idea? Wouldn’t that mean that clang-tidy would have to be 1:1 compatible with MSVC.

2 Likes

I don’t think filing an issue will change anything. We can’t stop identifying as Clang without breaking other things.

1 Like

Even as an explicit option, so we can handle this use-case? Not saying we should stop identifying as Clang by default.

I don’t think it will lead to good outcomes to let the user remove the compiler identification macro; ultimately, Clang is Clang; pretending it’s not (even in compatibility modes) is going to lead to nasty surprises and it’s not a compilation mode we could support.

Yeah, ultimately here the assumption is in the preprocessor condition that assumes “if compiling with clang, that means non-Windows”. You should check for platform independent of compiler.

I understand your use-case, i also work on an MSVC codebase. I’ve also wanted to add more analysis to it.

However: I started by compiling it with Clang-cl. It took me years to get to a point where clang understood the codebase because of several reasons including compiler bugs that are now resolved.

Next to confirming that the clang-tooling can now understand our code, it also gave us a large set of compiler warnings we’ve prioritized over clang-tidy. They might cover less, though they barely have false positives. (And when they do, it often points at code that should be improved)

My understanding is that next to the compiler defines, there are also platform defines, see c++ - Which Cross Platform Preprocessor Defines? (__WIN32__ or __WIN32 or WIN32 )? - Stack Overflow
If you want to detect the platform, use those iso the compiler ones.

Final remark, the Microsoft standard library is being tested with clang, which has specific code in #ifdef clang, for suppressing warnings … So if you would be able to undefined this, you most likely run into issues compiling.