Better handling of bad flags from extra conf
This commit is contained in:
parent
9c43634190
commit
2caf90637d
@ -28,6 +28,7 @@ NO_EXTRA_CONF_FILENAME_MESSAGE = ( 'No {0} file detected, so no compile flags '
|
|||||||
'DOCS *NOW*, DON\'T file a bug report.' ).format(
|
'DOCS *NOW*, DON\'T file a bug report.' ).format(
|
||||||
extra_conf_store.YCM_EXTRA_CONF_FILENAME )
|
extra_conf_store.YCM_EXTRA_CONF_FILENAME )
|
||||||
|
|
||||||
|
INCLUDE_FLAGS = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
|
||||||
|
|
||||||
class Flags( object ):
|
class Flags( object ):
|
||||||
"""Keeps track of the flags necessary to compile a file.
|
"""Keeps track of the flags necessary to compile a file.
|
||||||
@ -143,8 +144,13 @@ def _SanitizeFlags( flags ):
|
|||||||
def _RemoveUnusedFlags( flags, filename ):
|
def _RemoveUnusedFlags( flags, filename ):
|
||||||
"""Given an iterable object that produces strings (flags for Clang), removes
|
"""Given an iterable object that produces strings (flags for Clang), removes
|
||||||
the '-c' and '-o' options that Clang does not like to see when it's producing
|
the '-c' and '-o' options that Clang does not like to see when it's producing
|
||||||
completions for a file. Also removes the first flag in the list if it does not
|
completions for a file.
|
||||||
start with a '-' (it's highly likely to be the compiler name/path)."""
|
|
||||||
|
Also removes the first flag in the list if it does not
|
||||||
|
start with a '-' (it's highly likely to be the compiler name/path).
|
||||||
|
|
||||||
|
We also try to remove any stray filenames in the flags that aren't include
|
||||||
|
dirs."""
|
||||||
|
|
||||||
new_flags = []
|
new_flags = []
|
||||||
|
|
||||||
@ -154,23 +160,40 @@ def _RemoveUnusedFlags( flags, filename ):
|
|||||||
if not flags[ 0 ].startswith( '-' ):
|
if not flags[ 0 ].startswith( '-' ):
|
||||||
flags = flags[ 1: ]
|
flags = flags[ 1: ]
|
||||||
|
|
||||||
skip = False
|
skip_next = False
|
||||||
|
previous_flag_is_include = False
|
||||||
|
previous_flag_starts_with_dash = False
|
||||||
|
current_flag_starts_with_dash = False
|
||||||
for flag in flags:
|
for flag in flags:
|
||||||
if skip:
|
previous_flag_starts_with_dash = current_flag_starts_with_dash
|
||||||
skip = False
|
current_flag_starts_with_dash = flag.startswith( '-' )
|
||||||
|
if skip_next:
|
||||||
|
skip_next = False
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if flag == '-c':
|
if flag == '-c':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if flag == '-o':
|
if flag == '-o':
|
||||||
skip = True;
|
skip_next = True;
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if flag == filename or os.path.realpath( flag ) == filename:
|
if flag == filename or os.path.realpath( flag ) == filename:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# We want to make sure that we don't have any stray filenames in our flags;
|
||||||
|
# filenames that are part of include flags are ok, but others are not. This
|
||||||
|
# solves the case where we ask the compilation database for flags for
|
||||||
|
# "foo.cpp" when we are compiling "foo.h" because the comp db doesn't have
|
||||||
|
# flags for headers. The returned flags include "foo.cpp" and we need to
|
||||||
|
# remove that.
|
||||||
|
if ( not current_flag_starts_with_dash and
|
||||||
|
( not previous_flag_starts_with_dash or
|
||||||
|
( not previous_flag_is_include and '/' in flag ) ) ):
|
||||||
|
continue
|
||||||
|
|
||||||
new_flags.append( flag )
|
new_flags.append( flag )
|
||||||
|
previous_flag_is_include = flag in INCLUDE_FLAGS
|
||||||
return new_flags
|
return new_flags
|
||||||
|
|
||||||
|
|
||||||
|
@ -107,3 +107,30 @@ def RemoveUnusedFlags_RemoveFilename_test():
|
|||||||
flags._RemoveUnusedFlags(
|
flags._RemoveUnusedFlags(
|
||||||
expected[ :1 ] + to_remove + expected[ -1: ], filename ) )
|
expected[ :1 ] + to_remove + expected[ -1: ], filename ) )
|
||||||
|
|
||||||
|
|
||||||
|
def RemoveUnusedFlags_RemoveFlagWithoutPrecedingDashFlag_test():
|
||||||
|
expected = [ '-foo', '-x', 'c++', '-bar', 'include_dir' ]
|
||||||
|
to_remove = [ 'unrelated_file' ]
|
||||||
|
filename = 'file'
|
||||||
|
|
||||||
|
eq_( expected,
|
||||||
|
flags._RemoveUnusedFlags( expected + to_remove, filename ) )
|
||||||
|
|
||||||
|
eq_( expected,
|
||||||
|
flags._RemoveUnusedFlags( to_remove + expected, filename ) )
|
||||||
|
|
||||||
|
|
||||||
|
def RemoveUnusedFlags_RemoveFilenameWithoutPrecedingInclude_test():
|
||||||
|
expected = [ '-I', '/foo/bar', '-isystem/zoo/goo' ]
|
||||||
|
to_remove = [ '/moo/boo' ]
|
||||||
|
filename = 'file'
|
||||||
|
|
||||||
|
eq_( expected,
|
||||||
|
flags._RemoveUnusedFlags( expected + to_remove, filename ) )
|
||||||
|
|
||||||
|
eq_( expected,
|
||||||
|
flags._RemoveUnusedFlags( to_remove + expected, filename ) )
|
||||||
|
|
||||||
|
eq_( expected + expected,
|
||||||
|
flags._RemoveUnusedFlags( expected + to_remove + expected, filename ) )
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user