[clang-tidy] Using clang-tidy on Windows

Sorry sorry in advance if this is a newbie question, I’m trying to get clang-tidy (3.8.0 trunk) working on Windows pointing at the with the Visual Studio 2015 headers (VC and UCRT)

I’m trying a very simple programme
-------------cut-------

#include

void main(int argc,char **argv)
{
std::cerr << “Hello World” << std::endl;
}

-------------cut-------

clang-tidy will work perfectly until I start include system headers,stl etc…

I run on the command line (inside cygwin bash shell) with the following.

clang-tidy Stdio.cxx – -I"c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE" -I"c:/Program Files (x86)/Windows Kits/10/Include/10.0.10150.0/ucrt"

but I get a load of failures due to clang errors in the system headers.

Can I:

  1. parse a switch to clang-tidy to tell it not to complain about headers outside of my control?
  2. avoid this problem in the first place (I get the same if I try to compile with clang.exe or clang-cl.exe)?
  3. am I making an obvious mistake?

-----------------compiler output-----------------
8 warnings and 20 errors generated.
Error while processing D:\buildareas\HEAD\issdev\src\test\tidy\Stdio.cxx.
error: too many errors emitted, stopping now [clang-diagnostic-error]
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\vadefs.h:28:33: e
rror: expected ‘;’ after top level declarator [clang-diagnostic-error]
typedef unsigned __int64 uintptr_t;
^
;
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\vadefs.h:127:18:
error: expected identifier or ‘{’ [clang-diagnostic-error]
enum : bool { __the_value = false };
^
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\vadefs.h:133:18:
error: expected identifier or ‘{’ [clang-diagnostic-error]
enum : bool { __the_value = true };
^
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\vadefs.h:139:18:
error: expected identifier or ‘{’ [clang-diagnostic-error]
enum : bool { __the_value = true };
^
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\vcruntime.h:81:1:
error: C++ requires a type specifier for all declarations [clang-diagnostic-err
or]
_CRT_BEGIN_C_HEADER

… more errors cut

Many thanks inadvance

Paul

Sorry sorry in advance if this is a newbie question, I’m trying to get clang-tidy (3.8.0 trunk) working on Windows pointing at the with the Visual Studio 2015 headers (VC and UCRT)

I’m trying a very simple programme
-------------cut-------

#include

void main(int argc,char **argv)
{
std::cerr << “Hello World” << std::endl;
}

-------------cut-------

clang-tidy will work perfectly until I start include system headers,stl etc…

I run on the command line (inside cygwin bash shell) with the following.

clang-tidy Stdio.cxx – -I"c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE" -I"c:/Program Files (x86)/Windows Kits/10/Include/10.0.10150.0/ucrt"

but I get a load of failures due to clang errors in the system headers.

Can I:

  1. parse a switch to clang-tidy to tell it not to complain about headers outside of my control?
  2. avoid this problem in the first place (I get the same if I try to compile with clang.exe or clang-cl.exe)?
  3. am I making an obvious mistake?

-----------------compiler output-----------------
8 warnings and 20 errors generated.
Error while processing D:\buildareas\HEAD\issdev\src\test\tidy\Stdio.cxx.
error: too many errors emitted, stopping now [clang-diagnostic-error]
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\vadefs.h:28:33: e
rror: expected ‘;’ after top level declarator [clang-diagnostic-error]
typedef unsigned __int64 uintptr_t;
^
;
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\vadefs.h:127:18:
error: expected identifier or ‘{’ [clang-diagnostic-error]
enum : bool { __the_value = false };
^
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\vadefs.h:133:18:
error: expected identifier or ‘{’ [clang-diagnostic-error]
enum : bool { __the_value = true };
^
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\vadefs.h:139:18:
error: expected identifier or ‘{’ [clang-diagnostic-error]
enum : bool { __the_value = true };
^
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\vcruntime.h:81:1:
error: C++ requires a type specifier for all declarations [clang-diagnostic-err
or]
_CRT_BEGIN_C_HEADER

… more errors cut

Note that those are parsing errors, not clang-tidy errors.
You basically need to be able to run:
clang-check Stdio.cxx –
successfully first.

The easiest way to get there is to use CMake, and have it output a compilation database (see the description how to do this for LLVM, it’s very similar: http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html)

This looks like clang-tidy doesn’t know it’s targeting Windows and doesn’t know that C++11 is enabled.

Try throwing “-fms-extensions -fms-compatibility -fms-compatibility-version=19 -std=c++11” on the command line and see what happens?

Manuel
clang-check went nuts! so backed up a bit and used Reid suggestion

Reid
this did better once I added a -D_M_X64 (after getting a #error unsupported architecture)

clang-tidy Stdio.cxx – -I"c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE" -I"c:/Program Files (x86)/Windows Kits/10/Include/10.0.10150.0/ucrt"
-fms-extensions -fms-compatibility -fms-compatibility-version=19 -std=c++11 -D_MSC_VER=1900 -D_M_X64
64 warnings and 3 errors generated.

Error while processing D:\buildareas\HEAD\issdev\src\test\tidy\Stdio.cxx.
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\limits:1117:24: error: constexpr function never produces a constant expression [clang-diagnostic-
invalid-constexpr]
static _CONST_FUN _Ty infinity() _THROW0()
^
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\limits:1119:11: note: floating point arithmetic produces an infinity
return (_INF_LIMIT);
^
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\limits:52:21: note: expanded from macro ‘_INF_LIMIT’
#define _INF_LIMIT INFINITY

as this was complaining about constexpr I dropped the -std=c++11 and this gave me an assertion.

clang-tidy Stdio.cxx – -I"c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE" -I"c:/Program Files (x86)/Windows Kits/10/Include/10.0.10150.0/ucrt"
-fms-extensions -fms-compatibility -fms-compatibility-version=19 -D_MSC_VER=1900 -D_M_X64

Assertion failed: !isNull() && “Cannot retrieve a NULL type pointer”, file D:\src\llvm_snapshot_244436\llvm\tools\clang\include\clang/AST/Type.h, line 585

So I backed up again

clang-tidy Stdio.cxx – -I"c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/INCLUDE" -fms-extensions -fms-compatibility -fms-compatibility-version=18 -std=c++11 -D_MSC_VER=1800 -D_M_X64

This time dropping back to VS2013 and adding your c++11 back in…perfect that worked…

clang-tidy Stdio.cxx – -I"c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/INCLUDE" -fms-extensions -fms-compatibility -fms-compatibility-version=18 -std=c++11 -D_M_X64
18 warnings generated.
Suppressed 18 warnings (18 in non-user code).
Use -header-filter=.* to display errors from all non-system headers.

I wonder if I should log a bug to this effect that clang-tidy isn’t working with VS2015 headers?

Manuel
clang-check went nuts! so backed up a bit and used Reid suggestion

Reid
this did better once I added a -D_M_X64 (after getting a #error unsupported architecture)

clang-tidy Stdio.cxx – -I"c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE" -I"c:/Program Files (x86)/Windows Kits/10/Include/10.0.10150.0/ucrt"

-fms-extensions -fms-compatibility -fms-compatibility-version=19 -std=c++11 -D_MSC_VER=1900 -D_M_X64
64 warnings and 3 errors generated.

Error while processing D:\buildareas\HEAD\issdev\src\test\tidy\Stdio.cxx.

c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\limits:1117:24: error: constexpr function never produces a constant expression [clang-diagnostic-
invalid-constexpr]
static _CONST_FUN _Ty infinity() _THROW0()
^
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\limits:1119:11: note: floating point arithmetic produces an infinity
return (_INF_LIMIT);
^
c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE\limits:52:21: note: expanded from macro ‘_INF_LIMIT’
#define _INF_LIMIT INFINITY

as this was complaining about constexpr I dropped the -std=c++11 and this gave me an assertion.

clang-tidy Stdio.cxx – -I"c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE" -I"c:/Program Files (x86)/Windows Kits/10/Include/10.0.10150.0/ucrt"

-fms-extensions -fms-compatibility -fms-compatibility-version=19 -D_MSC_VER=1900 -D_M_X64

Assertion failed: !isNull() && “Cannot retrieve a NULL type pointer”, file D:\src\llvm_snapshot_244436\llvm\tools\clang\include\clang/AST/Type.h, line 585

So I backed up again

clang-tidy Stdio.cxx – -I"c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/INCLUDE" -fms-extensions -fms-compatibility -fms-compatibility-version=18 -std=c++11 -D_MSC_VER=1800 -D_M_X64

This time dropping back to VS2013 and adding your c++11 back in…perfect that worked…

clang-tidy Stdio.cxx – -I"c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/INCLUDE" -fms-extensions -fms-compatibility -fms-compatibility-version=18 -std=c++11 -D_M_X64
18 warnings generated.
Suppressed 18 warnings (18 in non-user code).
Use -header-filter=.* to display errors from all non-system headers.

I wonder if I should log a bug to this effect that clang-tidy isn’t working with VS2015 headers?

This still looks like compiler warnings. You need to be able to compile the code (with clang) before running clang-tidy on it.

I should also of confessed…that it only worked after I had fixed my example program

clang-tidy Stdio.cxx – -I"c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/INCLUDE" -fms-extensions -fms-compatibility -fms-compatibility-version=18 -std=c++11 -D_M_X64
D:\buildareas\HEAD\issdev\src\test\tidy\Stdio.cxx:3:1: error: ‘main’ must return ‘int’ [clang-diagnostic-error]
void main(int argc,char **argv)
^
int
D:\buildareas\HEAD\issdev\src\test\tidy\Stdio.cxx:6:4: error: void function ‘main’ should not return a value [clang-diagnostic-return-type]
return 0;
^

In article <CAOsfVv=QAgkYsADBo6zMxB8mn8MBKdr56Tqzh3Prnntj-6ukLw@mail.gmail.com>,
    Manuel Klimek via cfe-dev <cfe-dev@lists.llvm.org> writes:

The easiest way to get there is to use CMake, and have it output a
compilation database (see the description how to do this for LLVM, it's
very similar: http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html)

Unless they've changed it, this doesn't work on Windows.

In article <CAOsfVv=QAgkYsADBo6zMxB8mn8MBKdr56Tqzh3Prnntj-6ukLw@mail.gmail.com>,
Manuel Klimek via cfe-dev <cfe-dev@lists.llvm.org> writes:

The easiest way to get there is to use CMake, and have it output a
compilation database (see the description how to do this for LLVM, it’s
very similar: http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html)

Unless they’ve changed it, this doesn’t work on Windows.

Ah, right, sorry. My mistake. Do we have anything on Windows to generate compile_commands.json? (I think I remember something, but then again, my memory is really bad :slight_smile:

I don’t think we do and I think we should really mention it in the docs. Last time I tried this I wasted an hour and ended up starting a Linux VM :slight_smile:

Yes, now that we have ‘arguments’ in the compilation db, we should be able to at least add it to cmake…

Hi,

here are my 2 cents of experience with it:

  1. you can use the -G”Ninja” code generator. It works on Windows too and it can generate compilation databases.
  2. it you only use the standard headers, you can use "clang-tidy foo.cpp — -fms-compatibility-version=19” from the visual studio command line and it’ll find the standard headers without any problems.

Regards
Toibas