diff options
author | Tom Rix <tom.rix@sony.com> | 2019-03-07 09:45:22 -0800 |
---|---|---|
committer | Kim Gräsman <kim.grasman@gmail.com> | 2019-03-30 15:22:35 +0100 |
commit | 3b10ae16a5de06812122e64e18419298b588e1f3 (patch) | |
tree | 30fe895cc3839aa0eeed807dbccb54d18c5d4b48 | |
parent | f7e19006194b28ff8d2f889e7c7937f658c8c2b1 (diff) |
Add command line option --keep=<glob>
--keep is the command line equivalent to the keep pragma with globbing.
-rw-r--r-- | iwyu_globals.cc | 20 | ||||
-rw-r--r-- | iwyu_globals.h | 6 | ||||
-rw-r--r-- | iwyu_preprocessor.cc | 5 | ||||
-rwxr-xr-x | run_iwyu_tests.py | 4 | ||||
-rw-r--r-- | tests/c/keep_includes-d1.h | 11 | ||||
-rw-r--r-- | tests/c/keep_includes.c | 22 |
6 files changed, 67 insertions, 1 deletions
diff --git a/iwyu_globals.cc b/iwyu_globals.cc index 55c4a0d..a971ad2 100644 --- a/iwyu_globals.cc +++ b/iwyu_globals.cc @@ -62,6 +62,9 @@ static void PrintHelp(const char* extra_msg) { " to the default of reporting for the input .cc file and its\n" " associated .h files). This flag may be specified multiple\n" " times to specify multiple glob patterns.\n" + " --keep=<glob>: tells iwyu to always keep these includes.\n" + " This flag may be specified multiple times to specify\n" + " multiple glob patterns.\n" " --mapping_file=<filename>: gives iwyu a mapping file.\n" " --no_default_mappings: do not add iwyu's default mappings.\n" " --pch_in_code: mark the first include in a translation unit as a\n" @@ -168,6 +171,7 @@ CommandlineFlags::CommandlineFlags() int CommandlineFlags::ParseArgv(int argc, char** argv) { static const struct option longopts[] = { {"check_also", required_argument, nullptr, 'c'}, // can be specified >once + {"keep", required_argument, nullptr, 'k'}, // can be specified >once {"transitive_includes_only", no_argument, nullptr, 't'}, {"verbose", required_argument, nullptr, 'v'}, {"mapping_file", required_argument, nullptr, 'm'}, @@ -185,6 +189,7 @@ int CommandlineFlags::ParseArgv(int argc, char** argv) { while (true) { switch (getopt_long(argc, argv, shortopts, longopts, nullptr)) { case 'c': AddGlobToReportIWYUViolationsFor(optarg); break; + case 'k': AddGlobToKeepIncludes(optarg); break; case 't': transitive_includes_only = true; break; case 'v': verbose = atoi(optarg); break; case 'm': mapping_files.push_back(optarg); break; @@ -382,6 +387,21 @@ bool ShouldReportIWYUViolationsFor(const clang::FileEntry* file) { return false; } +void AddGlobToKeepIncludes(const string& glob) { + CHECK_(commandline_flags && "Call ParseIwyuCommandlineFlags() before this"); + commandline_flags->keep.insert(NormalizeFilePath(glob)); +} + +bool ShouldKeepIncludeFor(const clang::FileEntry* file) { + if (GlobalFlags().keep.empty()) + return false; + const string filepath = GetFilePath(file); + for (const string& glob : GlobalFlags().keep) + if (GlobMatchesPath(glob.c_str(), filepath.c_str())) + return true; + return false; +} + void InitGlobalsAndFlagsForTesting() { CHECK_(commandline_flags == nullptr && "Only parse commandline flags once"); CHECK_(include_picker == nullptr && "Only call InitGlobals[ForTesting] once"); diff --git a/iwyu_globals.h b/iwyu_globals.h index 35530bb..af40256 100644 --- a/iwyu_globals.h +++ b/iwyu_globals.h @@ -87,6 +87,7 @@ struct CommandlineFlags { int ParseArgv(int argc, char** argv); // parses flags from argv set<string> check_also; // -c: globs to report iwyu violations for + set<string> keep; // -k: globs to force-keep includes for bool transitive_includes_only; // -t: don't add 'new' #includes to files int verbose; // -v: how much information to emit as we parse vector<string> mapping_files; // -m: mapping files @@ -128,6 +129,11 @@ FullUseCache* ClassMembersFullUseCache(); void AddGlobToReportIWYUViolationsFor(const string& glob); bool ShouldReportIWYUViolationsFor(const clang::FileEntry* file); +// For the commandline option --keep. +// Similar to AddGlobToReportIWYUViolationsFor. +void AddGlobToKeepIncludes(const string& glob); +bool ShouldKeepIncludeFor(const clang::FileEntry* file); + } // namespace include_what_you_use #endif // INCLUDE_WHAT_YOU_USE_IWYU_GLOBALS_H_ diff --git a/iwyu_preprocessor.cc b/iwyu_preprocessor.cc index 763192b..bacfa70 100644 --- a/iwyu_preprocessor.cc +++ b/iwyu_preprocessor.cc @@ -400,6 +400,11 @@ void IwyuPreprocessorInfo::MaybeProtectInclude( protect_reason = "pragma_keep"; FileInfoFor(includer)->ReportKnownDesiredFile(includee); + } else if (ShouldKeepIncludeFor(includee)) { + // The command line version of pragma keep. + protect_reason = "--keep"; + FileInfoFor(includer)->ReportKnownDesiredFile(includee); + } else if (LineHasText(includer_loc, "// IWYU pragma: export") || LineHasText(includer_loc, "/* IWYU pragma: export") || HasOpenBeginExports(includer)) { diff --git a/run_iwyu_tests.py b/run_iwyu_tests.py index 249e1dd..5cdba9c 100755 --- a/run_iwyu_tests.py +++ b/run_iwyu_tests.py @@ -70,7 +70,8 @@ class OneIwyuTest(unittest.TestCase): self.CheckAlsoExtension('-fnreturn.h'), self.CheckAlsoExtension('-typedefs.h'), self.CheckAlsoExtension('-d2.h')], - 'keep_mapping.cc': [self.CheckAlsoExtension('-public.h'), + 'keep_includes.c': ['--keep=tests/c/keep_includes*.h'], + 'keep_mapping.cc': [self.CheckAlsoExtension('-public.h'), self.MappingFile('keep_mapping.imp')], 'macro_location.cc': [self.CheckAlsoExtension('-d2.h')], 'mapping_to_self.cc': [self.MappingFile('mapping_to_self.imp')], @@ -155,6 +156,7 @@ class OneIwyuTest(unittest.TestCase): 'include_with_using.cc': ['.'], 'internal/internal_files.cc': ['.'], 'iwyu_stricter_than_cpp.cc': ['.'], + 'keep_includes.c': ['.'], 'keep_mapping.cc': ['.'], 'lateparsed_template.cc': ['.'], 'macro_defined_by_includer.cc': ['.'], diff --git a/tests/c/keep_includes-d1.h b/tests/c/keep_includes-d1.h new file mode 100644 index 0000000..77367a1 --- /dev/null +++ b/tests/c/keep_includes-d1.h @@ -0,0 +1,11 @@ +//===--- keep_includes-d1.h - test header for iwyu ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// This is an empty file. +// Without --keep, this file should be removed. diff --git a/tests/c/keep_includes.c b/tests/c/keep_includes.c new file mode 100644 index 0000000..7866b4c --- /dev/null +++ b/tests/c/keep_includes.c @@ -0,0 +1,22 @@ +//===--- keep_includes.c - test input file for iwyu -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// keep_includes-d1.h is an empty file. +// Normally it would be removed. +// In this test we are exercising the --keep command line option. +// IWYU should not remove keep_include-d1.h when +// --keep=tests/c/keep_includes*.h is used. + +#include "keep_includes-d1.h" + +/**** IWYU_SUMMARY + +(tests/c/keep_includes.c has correct #includes/fwd-decls) + +***** IWYU_SUMMARY */ |