From a767578d44dd96bfcb395a8cc605b1905f5393dd Mon Sep 17 00:00:00 2001 From: Andrej Radovic Date: Sat, 5 Aug 2017 15:21:02 +0200 Subject: [PATCH] Added clang-tidy for C, too. A limited number of clang-tidy checks can be used with C, too. I pretty much copied and refactored the C++ clang-tidy linter, and added some documentation about C-compatible checks. --- README.md | 2 +- ale_linters/c/clangtidy.vim | 107 ++++++++++++++++++++++++++++++ doc/ale-c.txt | 129 ++++++++++++++++++++++++++++++++++++ doc/ale.txt | 1 + 4 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 ale_linters/c/clangtidy.vim diff --git a/README.md b/README.md index e90474e..cf1e992 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ name. That seems to be the fairest way to arrange this table. | Awk | [gawk](https://www.gnu.org/software/gawk/)| | Bash | [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set), [shellcheck](https://www.shellcheck.net/) | | Bourne Shell | [-n flag](http://linux.die.net/man/1/sh), [shellcheck](https://www.shellcheck.net/) | -| C | [cppcheck](http://cppcheck.sourceforge.net), [gcc](https://gcc.gnu.org/), [clang](http://clang.llvm.org/)| +| C | [cppcheck](http://cppcheck.sourceforge.net), [gcc](https://gcc.gnu.org/), [clang](http://clang.llvm.org/), [clangtidy](http://clang.llvm.org/extra/clang-tidy/)| | C++ (filetype cpp) | [clang](http://clang.llvm.org/), [clangcheck](http://clang.llvm.org/docs/ClangCheck.html), [clangtidy](http://clang.llvm.org/extra/clang-tidy/), [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint), [gcc](https://gcc.gnu.org/)| | C# | [mcs](http://www.mono-project.com/docs/about-mono/languages/csharp/) | | Chef | [foodcritic](http://www.foodcritic.io/) | diff --git a/ale_linters/c/clangtidy.vim b/ale_linters/c/clangtidy.vim new file mode 100644 index 0000000..e92c0c0 --- /dev/null +++ b/ale_linters/c/clangtidy.vim @@ -0,0 +1,107 @@ +" Author: vdeurzen , w0rp , +" gagbo , Andrej Radovic +" Description: clang-tidy linter for c files + +call ale#Set('c_clangtidy_executable', 'clang-tidy') +" Set this option to check the checks clang-tidy will apply. +" The number of checks that can be applied to C files is limited in contrast to +" C++ +" +" Here is an incomplete list of C-compatible checks for clang-tidy version 6: +" bugprone-suspicious-memset-usage +" cert-env33-c +" cert-err34-c +" cert-flp30-c +" google-runtime-int +" llvm-header-guard +" llvm-include-order +" misc-argument-comment +" misc-assert-side-effect +" misc-bool-pointer-implicit-conversion +" misc-definitions-in-headers +" misc-incorrect-roundings +" misc-macro-parentheses +" misc-macro-repeated-side-effects +" misc-misplaced-const +" misc-misplaced-widening-cast +" misc-multiple-statement-macro +" misc-non-copyable-objects +" misc-redundant-expression +" misc-sizeof-expression +" misc-static-assert +" misc-string-literal-with-embedded-nul +" misc-suspicious-enum-usage +" misc-suspicious-missing-comma +" misc-suspicious-semicolon +" misc-suspicious-string-compare +" misc-swapped-arguments +" modernize-redundant-void-arg +" modernize-use-bool-literals +" performance-type-promotion-in-math-fn +" readability-braces-around-statements +" readability-else-after-return +" readability-function-size +" readability-identifier-naming +" readability-implicit-bool-cast +" readability-inconsistent-declaration-parameter-name +" readability-misleading-indentation +" readability-misplaced-array-index +" readability-named-parameter +" readability-non-const-parameter +" readability-redundant-control-flow +" readability-redundant-declaration +" readability-redundant-function-ptr-dereference +" readability-simplify-boolean-expr + +call ale#Set('c_clangtidy_checks', ['*']) +" Set this option to manually set some options for clang-tidy. +" This will disable compile_commands.json detection. +call ale#Set('c_clangtidy_options', '') +call ale#Set('c_build_dir', '') + +function! ale_linters#c#clangtidy#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'c_clangtidy_executable') +endfunction + +function! s:GetBuildDirectory(buffer) abort + " Don't include build directory for header files, as compile_commands.json + " files don't consider headers to be translation units, and provide no + " commands for compiling header files. + if expand('#' . a:buffer) =~# '\v\.(h|hpp)$' + return '' + endif + + let l:build_dir = ale#Var(a:buffer, 'c_build_dir') + + " c_build_dir has the priority if defined + if !empty(l:build_dir) + return l:build_dir + endif + + return ale#c#FindCompileCommands(a:buffer) +endfunction + +function! ale_linters#c#clangtidy#GetCommand(buffer) abort + let l:checks = join(ale#Var(a:buffer, 'c_clangtidy_checks'), ',') + let l:build_dir = s:GetBuildDirectory(a:buffer) + + " Get the extra options if we couldn't find a build directory. + let l:options = empty(l:build_dir) + \ ? ale#Var(a:buffer, 'c_clangtidy_options') + \ : '' + + return ale#Escape(ale_linters#c#clangtidy#GetExecutable(a:buffer)) + \ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '') + \ . ' %s' + \ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '') + \ . (!empty(l:options) ? ' -- ' . l:options : '') +endfunction + +call ale#linter#Define('c', { +\ 'name': 'clangtidy', +\ 'output_stream': 'stdout', +\ 'executable_callback': 'ale_linters#c#clangtidy#GetExecutable', +\ 'command_callback': 'ale_linters#c#clangtidy#GetCommand', +\ 'callback': 'ale#handlers#gcc#HandleGCCFormat', +\ 'lint_file': 1, +\}) diff --git a/doc/ale-c.txt b/doc/ale-c.txt index 2572d88..eb52bc1 100644 --- a/doc/ale-c.txt +++ b/doc/ale-c.txt @@ -2,6 +2,37 @@ ALE C Integration *ale-c-options* +=============================================================================== +Global Options + +g:ale_c_build_dir_names *g:ale_c_build_dir_names* + *b:ale_c_build_dir_names* + + Type: |List| + Default: `['build', 'bin']` + + A list of directory names to be used when searching upwards from cpp + files to discover compilation databases with. For directory named `'foo'`, + ALE will search for `'foo/compile_commands.json'` in all directories on and above + the directory containing the cpp file to find path to compilation database. + This feature is useful for the clang tools wrapped around LibTooling (namely + here, clang-tidy) + + +g:ale_c_build_dir *g:ale_c_build_dir* + *b:ale_c_build_dir* + + Type: |String| + Default: `''` + + A path to the directory containing the `compile_commands.json` file to use + with c-family linters. Usually setting this option to a non-empty string + will override the |g:ale_c_build_dir_names| option to impose a compilation + database (it can be useful if multiple builds are in multiple build + subdirectories in the project tree). + This feature is also most useful for the clang tools linters, wrapped + aroung LibTooling (namely clang-tidy here) + =============================================================================== clang *ale-c-clang* @@ -21,6 +52,104 @@ g:ale_c_clang_options *g:ale_c_clang_options* This variable can be changed to modify flags given to clang. +=============================================================================== +clangtidy *ale-c-clangtidy* + +`clang-tidy` will be run only when files are saved to disk, so that +`compile_commands.json` files can be used. It is recommended to use this +linter in combination with `compile_commands.json` files. +Therefore, `clang-tidy` linter reads the options |g:ale_c_build_dir| and +|g:ale_c_build_dir_names|. Also, setting |g:ale_c_build_dir| actually +overrides |g:ale_c_build_dir_names|. + + +g:ale_c_clangtidy_checks *g:ale_c_clangtidy_checks* + *b:ale_c_clangtidy_checks* + Type: |List| + Default: `['*']` + + The checks to enable for clang-tidy with the `-checks` argument. + + All options will be joined with commas, and escaped appropriately for + the shell. The `-checks` flag can be removed entirely by setting this + option to an empty List. + + Not all of clangtidy checks are applicable for C. You should consult the + clang documentation for an up-to-date list of compatible checks. + + Here's an (incomplete) list of C-compatible checks, for clang-tidy version 6: + bugprone-suspicious-memset-usage + cert-env33-c + cert-err34-c + cert-flp30-c + google-runtime-int + llvm-header-guard + llvm-include-order + misc-argument-comment + misc-assert-side-effect + misc-bool-pointer-implicit-conversion + misc-definitions-in-headers + misc-incorrect-roundings + misc-macro-parentheses + misc-macro-repeated-side-effects + misc-misplaced-const + misc-misplaced-widening-cast + misc-multiple-statement-macro + misc-non-copyable-objects + misc-redundant-expression + misc-sizeof-expression + misc-static-assert + misc-string-literal-with-embedded-nul + misc-suspicious-enum-usage + misc-suspicious-missing-comma + misc-suspicious-semicolon + misc-suspicious-string-compare + misc-swapped-arguments + modernize-redundant-void-arg + modernize-use-bool-literals + performance-type-promotion-in-math-fn + readability-braces-around-statements + readability-else-after-return + readability-function-size + readability-identifier-naming + readability-implicit-bool-cast + readability-inconsistent-declaration-parameter-name + readability-misleading-indentation + readability-misplaced-array-index + readability-named-parameter + readability-non-const-parameter + readability-redundant-control-flow + readability-redundant-declaration + readability-redundant-function-ptr-dereference + readability-simplify-boolean-expr + + +g:ale_c_clangtidy_executable *g:ale_c_clangtidy_executable* + *b:ale_c_clangtidy_executable* + Type: |String| + Default: `'clang-tidy'` + + This variable can be changed to use a different executable for clangtidy. + + +g:ale_c_clangtidy_options *g:ale_c_clangtidy_options* + *b:ale_c_clangtidy_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to clang-tidy. + + - Setting this variable to a non-empty string, + - and working in a buffer where no compilation database is found using + |g:ale_c_build_dir_names| or |g:ale_c_build_dir|, + will cause the `--` argument to be passed to `clang-tidy`, which will mean + that detection of `compile_commands.json` files for compile command + databases will be disabled. + Only set this option if you want to control compiler flags + entirely manually, and no `compile_commands.json` file is in one + of the |g:ale_c_build_dir_names| directories of the project tree. + + =============================================================================== cppcheck *ale-c-cppcheck* diff --git a/doc/ale.txt b/doc/ale.txt index 8647637..944431d 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -16,6 +16,7 @@ CONTENTS *ale-contents* gcc.................................|ale-asm-gcc| c.....................................|ale-c-options| clang...............................|ale-c-clang| + clangtidy...........................|ale-c-clangtidy| cppcheck............................|ale-c-cppcheck| gcc.................................|ale-c-gcc| chef..................................|ale-chef-options|