summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Rix <tom.rix@sony.com>2019-03-07 09:45:22 -0800
committerKim Gräsman <kim.grasman@gmail.com>2019-03-30 15:22:35 +0100
commit3b10ae16a5de06812122e64e18419298b588e1f3 (patch)
tree30fe895cc3839aa0eeed807dbccb54d18c5d4b48
parentf7e19006194b28ff8d2f889e7c7937f658c8c2b1 (diff)
Add command line option --keep=<glob>
--keep is the command line equivalent to the keep pragma with globbing.
-rw-r--r--iwyu_globals.cc20
-rw-r--r--iwyu_globals.h6
-rw-r--r--iwyu_preprocessor.cc5
-rwxr-xr-xrun_iwyu_tests.py4
-rw-r--r--tests/c/keep_includes-d1.h11
-rw-r--r--tests/c/keep_includes.c22
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 */