cc: fix using '-x c*-header' for header files with GCC. (#4334)

Gcc does not support `x c*-header` when using `-` as input filename,
which is what ALE does.

Rework the feature to only use `-x c*-header` flag when using Clang and
not GCC.

The feature is now also controlled with the variable
`g:ale_c_cc_use_header_lang_flag` and
`g:ale_cpp_cc_use_header_lang_flag`.
This commit is contained in:
Nicolas Pauss
2022-10-12 00:05:37 +02:00
committed by GitHub
parent f085227504
commit 951a668b14
7 changed files with 161 additions and 21 deletions

View File

@@ -3,6 +3,7 @@
call ale#Set('c_cc_executable', '<auto>')
call ale#Set('c_cc_options', '-std=c11 -Wall')
call ale#Set('c_cc_use_header_lang_flag', -1)
call ale#Set('c_cc_header_exts', ['h'])
function! ale_linters#c#cc#GetExecutable(buffer) abort
@@ -23,8 +24,6 @@ endfunction
function! ale_linters#c#cc#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
let l:ale_flags = ale#Var(a:buffer, 'c_cc_options')
let l:header_exts = ale#Var(a:buffer, 'c_cc_header_exts')
let l:lang_flag = ale#c#GetLanguageFlag(a:buffer, l:header_exts, 'c')
if l:cflags =~# '-std='
let l:ale_flags = substitute(
@@ -34,6 +33,18 @@ function! ale_linters#c#cc#GetCommand(buffer, output) abort
\ 'g')
endif
" Select the correct language flag depending on the executable, options
" and file extension
let l:executable = ale_linters#c#cc#GetExecutable(a:buffer)
let l:use_header_lang_flag = ale#Var(a:buffer, 'c_cc_use_header_lang_flag')
let l:header_exts = ale#Var(a:buffer, 'c_cc_header_exts')
let l:lang_flag = ale#c#GetLanguageFlag(
\ a:buffer,
\ l:executable,
\ l:use_header_lang_flag,
\ l:header_exts,
\ 'c')
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
"

View File

@@ -3,6 +3,7 @@
call ale#Set('cpp_cc_executable', '<auto>')
call ale#Set('cpp_cc_options', '-std=c++14 -Wall')
call ale#Set('cpp_cc_use_header_lang_flag', -1)
call ale#Set('cpp_cc_header_exts', ['h', 'hpp'])
function! ale_linters#cpp#cc#GetExecutable(buffer) abort
@@ -23,8 +24,6 @@ endfunction
function! ale_linters#cpp#cc#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
let l:ale_flags = ale#Var(a:buffer, 'cpp_cc_options')
let l:header_exts = ale#Var(a:buffer, 'cpp_cc_header_exts')
let l:lang_flag = ale#c#GetLanguageFlag(a:buffer, l:header_exts, 'c++')
if l:cflags =~# '-std='
let l:ale_flags = substitute(
@@ -34,6 +33,18 @@ function! ale_linters#cpp#cc#GetCommand(buffer, output) abort
\ 'g')
endif
" Select the correct language flag depending on the executable, options
" and file extension
let l:executable = ale_linters#cpp#cc#GetExecutable(a:buffer)
let l:use_header_lang_flag = ale#Var(a:buffer, 'cpp_cc_use_header_lang_flag')
let l:header_exts = ale#Var(a:buffer, 'cpp_cc_header_exts')
let l:lang_flag = ale#c#GetLanguageFlag(
\ a:buffer,
\ l:executable,
\ l:use_header_lang_flag,
\ l:header_exts,
\ 'c++')
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
"

View File

@@ -586,13 +586,37 @@ function! ale#c#IncludeOptions(include_paths) abort
return join(l:option_list)
endfunction
" Get the language flag depending on if the file is a header or not.
function! ale#c#GetLanguageFlag(buffer, header_exts, linter_lang) abort
let l:buf_ext = expand('#' . a:buffer . ':e')
if index(a:header_exts, l:buf_ext) >= 0
return a:linter_lang . '-header'
" Get the language flag depending on on the executable, options and
" file extension
function! ale#c#GetLanguageFlag(
\ buffer,
\ executable,
\ use_header_lang_flag,
\ header_exts,
\ linter_lang_flag
\) abort
" Use only '-header' if the executable is 'clang' by default
if a:use_header_lang_flag == -1
let l:use_header_lang_flag = a:executable =~# 'clang'
else
let l:use_header_lang_flag = a:use_header_lang_flag
endif
return a:linter_lang
" If we don't use the header language flag, return the default linter
" language flag
if !l:use_header_lang_flag
return a:linter_lang_flag
endif
" Get the buffer file extension
let l:buf_ext = expand('#' . a:buffer . ':e')
" If the buffer file is an header according to its extension, use
" the linter language flag + '-header', ex: 'c-header'
if index(a:header_exts, l:buf_ext) >= 0
return a:linter_lang_flag . '-header'
endif
" Else, use the default linter language flag
return a:linter_lang_flag
endfunction

View File

@@ -133,7 +133,30 @@ g:ale_c_cc_options *g:ale_c_cc_options*
Type: |String|
Default: `'-std=c11 -Wall'`
This variable can be change to modify flags given to the C compiler.
This variable can be changed to modify flags given to the C compiler.
g:ale_c_cc_use_header_lang_flag *g:ale_c_cc_use_header_lang_flag*
*b:ale_c_cc_use_header_lang_flag*
Type: |Number|
Default: `-1`
By default, ALE will use `'-x c-header'` instead of `'-x c'` for header files
when using Clang.
This variable can be changed to manually activate or deactivate this flag
for header files.
- When set to `-1`, the default beviour is used, `'-x c-header'` is used with
Clang and `'-x c'` is used with other compilers.
- When set to `0`, the flag is deactivated, `'-x c'` is always used
independently of the compiler.
- When set to `1`, the flag is activated, `'-x c-header'` is always used
independently of the compiler.
Gcc does not support `'-x c-header'` when using `'-'` as input filename,
which is what ALE does. This why, by default, ALE only uses `'-x c-header'`
with Clang.
g:ale_c_cc_header_exts *g:ale_c_cc_header_exts*
@@ -141,10 +164,11 @@ g:ale_c_cc_header_exts *g:ale_c_cc_header_exts*
Type: |List|
Default: `['h']`
This variable can be change to modify the list of extensions of the files
This variable can be changed to modify the list of extensions of the files
considered as header files.
ALE will use `'-x c-header'` instead of `'-x c'` for header files.
This variable is only used when `'-x c-header'` is used instead of `'-x c'`,
see |ale_c_cc_use_header_lang_flag|.
===============================================================================

View File

@@ -62,7 +62,30 @@ g:ale_cpp_cc_options *g:ale_cpp_cc_options*
Type: |String|
Default: `'-std=c++14 -Wall'`
This variable can be change to modify flags given to the C++ compiler.
This variable can be changed to modify flags given to the C++ compiler.
g:ale_cpp_cc_use_header_lang_flag *g:ale_cpp_cc_use_header_lang_flag*
*b:ale_cpp_cc_use_header_lang_flag*
Type: |Number|
Default: `-1`
By default, ALE will use `'-x c++-header'` instead of `'-x c++'` for header
files when using Clang.
This variable can be changed to manually activate or deactivate this flag
for header files.
- When set to `-1`, the default beviour is used, `'-x c++-header'` is used with
Clang and `'-x c++'` is used with other compilers.
- When set to `0`, the flag is deactivated, `'-x c++'` is always used
independently of the compiler.
- When set to `1`, the flag is activated, `'-x c++-header'` is always used
independently of the compiler.
Gcc does not support `'-x c++-header'` when using `'-'` as input filename,
which is what ALE does. This why, by default, ALE only uses `'-x c++-header'`
with Clang.
g:ale_cpp_cc_header_exts *g:ale_cpp_cc_header_exts*
@@ -70,10 +93,11 @@ g:ale_cpp_cc_header_exts *g:ale_cpp_cc_header_exts*
Type: |List|
Default: `['h', 'hpp']`
This variable can be change to modify the list of extensions of the files
This variable can be changed to modify the list of extensions of the files
considered as header files.
ALE will use `'-x c++-header'` instead of `'-x c++'` for header files.
This variable is only used when `'-x c++-header'` is used instead of `'-x c++'`,
see |ale_cpp_cc_use_header_lang_flag|.
===============================================================================

View File

@@ -54,18 +54,41 @@ Execute(The -std flag should be replaced by parsed C flags):
AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail
Execute(The header files should use -x c-header):
Execute(gcc should not use -x c-header with header files by default):
call ale#test#SetFilename('../test-files/c/makefile_project/subdir/test.h')
AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail
Execute(clang should use -x c-header with header files by default):
let g:executable_map = {'clang': 1}
let b:command_tail = substitute(b:command_tail, '-x c', '-x c-header', '')
call ale#test#SetFilename('../test-files/c/makefile_project/subdir/test.h')
AssertLinter 'clang', ale#Escape('clang') . b:command_tail
Execute(gcc should use -x c-header with header files if configured to do so):
let b:ale_c_cc_use_header_lang_flag = 1
let b:command_tail = substitute(b:command_tail, '-x c', '-x c-header', '')
call ale#test#SetFilename('../test-files/c/makefile_project/subdir/test.h')
AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail
Execute(clang should not use -x c-header with header files if configured to do so):
let g:executable_map = {'clang': 1}
let b:ale_c_cc_use_header_lang_flag = 0
call ale#test#SetFilename('../test-files/c/makefile_project/subdir/test.h')
AssertLinter 'clang', ale#Escape('clang') . b:command_tail
Execute(The header file extensions should be configurable):
let g:executable_map = {'clang': 1}
let b:command_tail = substitute(b:command_tail, '-x c', '-x c-header', '')
call ale#assert#SetUpLinterTest('c', 'cc')
let b:ale_c_cc_header_exts = ['json']
call ale#test#SetFilename('../test-files/c/json_project/build/compile_commands.json')
AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail
AssertLinter 'clang', ale#Escape('clang') . b:command_tail

View File

@@ -54,18 +54,41 @@ Execute(The -std flag should be replaced by parsed C flags):
AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail
Execute(The header files should use -x c++-header):
Execute(gcc should not use -x c++-header with header files by default):
call ale#test#SetFilename('../test-files/c/hpp_file_project/test.hpp')
AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail
Execute(clang++ should use -x c++-header with header files by default):
let g:executable_map = {'clang++': 1}
let b:command_tail = substitute(b:command_tail, '-x c++', '-x c++-header', '')
call ale#test#SetFilename('../test-files/c/hpp_file_project/test.hpp')
AssertLinter 'clang++', ale#Escape('clang++') . b:command_tail
Execute(gcc should use -x c-header with header files if configured to do so):
let b:ale_cpp_cc_use_header_lang_flag = 1
let b:command_tail = substitute(b:command_tail, '-x c++', '-x c++-header', '')
call ale#test#SetFilename('../test-files/c/hpp_file_project/test.hpp')
AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail
Execute(clang should not use -x c-header with header files if configured to do so):
let g:executable_map = {'clang++': 1}
let b:ale_cpp_cc_use_header_lang_flag = 0
call ale#test#SetFilename('../test-files/c/hpp_file_project/test.hpp')
AssertLinter 'clang++', ale#Escape('clang++') . b:command_tail
Execute(The header file extensions should be configurable):
let g:executable_map = {'clang++': 1}
let b:command_tail = substitute(b:command_tail, '-x c++', '-x c++-header', '')
call ale#assert#SetUpLinterTest('cpp', 'cc')
let b:ale_cpp_cc_header_exts = ['json']
call ale#test#SetFilename('../test-files/c/json_project/build/compile_commands.json')
AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail
AssertLinter 'clang++', ale#Escape('clang++') . b:command_tail