530 lines
21 KiB
C++
530 lines
21 KiB
C++
//===--- iwyu_globals.cc - global variables for include-what-you-use ------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "iwyu_globals.h"
|
|
|
|
#include <algorithm> // for sort, make_pair
|
|
#include <cstdio> // for printf
|
|
#include <cstdlib> // for atoi, exit, getenv
|
|
#include <map> // for map
|
|
#include <set> // for set
|
|
#include <string> // for string, operator<, etc
|
|
#include <utility> // for make_pair, pair
|
|
|
|
#include "iwyu_cache.h"
|
|
#include "iwyu_include_picker.h"
|
|
#include "iwyu_getopt.h"
|
|
#include "iwyu_lexer_utils.h"
|
|
#include "iwyu_location_util.h"
|
|
#include "iwyu_path_util.h"
|
|
#include "iwyu_port.h" // for CHECK_, etc
|
|
#include "iwyu_regex.h"
|
|
#include "iwyu_stl_util.h"
|
|
#include "iwyu_string_util.h"
|
|
#include "iwyu_verrs.h"
|
|
#include "iwyu_version.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include "clang/AST/PrettyPrinter.h"
|
|
#include "clang/Basic/FileManager.h"
|
|
#include "clang/Basic/Version.h"
|
|
#include "clang/Lex/HeaderSearch.h"
|
|
|
|
using clang::DirectoryEntry;
|
|
using std::make_pair;
|
|
using std::map;
|
|
using std::string;
|
|
using std::vector;
|
|
|
|
namespace include_what_you_use {
|
|
|
|
static CommandlineFlags* commandline_flags = nullptr;
|
|
static clang::SourceManager* source_manager = nullptr;
|
|
static IncludePicker* include_picker = nullptr;
|
|
static const clang::LangOptions default_lang_options;
|
|
static const clang::PrintingPolicy default_print_policy(default_lang_options);
|
|
static SourceManagerCharacterDataGetter* data_getter = nullptr;
|
|
static FullUseCache* function_calls_full_use_cache = nullptr;
|
|
static FullUseCache* class_members_full_use_cache = nullptr;
|
|
static int ParseIwyuCommandlineFlags(int argc, char** argv);
|
|
static int ParseInterceptedCommandlineFlags(int argc, char** argv);
|
|
|
|
static void PrintHelp(const char* extra_msg) {
|
|
printf("USAGE: include-what-you-use [-Xiwyu --iwyu_opt]... <clang opts>"
|
|
" <source file>\n"
|
|
"Here are the <iwyu_opts> you can specify (e.g. -Xiwyu --verbose=3):\n"
|
|
" --check_also=<glob>: tells iwyu to print iwyu-violation info\n"
|
|
" for all files matching the given glob pattern (in addition\n"
|
|
" 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"
|
|
" precompiled header. Use --pch_in_code to prevent IWYU from\n"
|
|
" removing necessary PCH includes. Though Clang forces PCHs\n"
|
|
" to be listed as prefix headers, the PCH-in-code pattern can\n"
|
|
" be used with GCC and is standard practice on MSVC\n"
|
|
" (e.g. stdafx.h).\n"
|
|
" --prefix_header_includes=<value>: tells iwyu what to do with\n"
|
|
" in-source includes and forward declarations involving\n"
|
|
" prefix headers. Prefix header is a file included via\n"
|
|
" command-line option -include. If prefix header makes\n"
|
|
" include or forward declaration obsolete, presence of such\n"
|
|
" include can be controlled with the following values\n"
|
|
" add: new lines are added\n"
|
|
" keep: new lines aren't added, existing are kept intact\n"
|
|
" remove: new lines aren't added, existing are removed\n"
|
|
" Default value is 'add'.\n"
|
|
" --transitive_includes_only: do not suggest that a file add\n"
|
|
" foo.h unless foo.h is already visible in the file's\n"
|
|
" transitive includes.\n"
|
|
" --max_line_length: maximum line length for includes.\n"
|
|
" Note that this only affects comments and alignment thereof,\n"
|
|
" the maximum line length can still be exceeded with long\n"
|
|
" file names (default: 80).\n"
|
|
" --comment_style=<level> set verbosity of 'why' comments to one\n"
|
|
" of the following values:\n"
|
|
" none: do not add 'why' comments\n"
|
|
" short: 'why' comments do not include namespaces\n"
|
|
" long: 'why' comments include namespaces\n"
|
|
" Default value is 'short'.\n"
|
|
" --no_comments: do not add 'why' comments.\n"
|
|
" --update_comments: update and insert 'why' comments, even if no\n"
|
|
" #include lines need to be added or removed.\n"
|
|
" --no_fwd_decls: do not use forward declarations.\n"
|
|
" --verbose=<level>: the higher the level, the more output.\n"
|
|
" --quoted_includes_first: when sorting includes, place quoted\n"
|
|
" ones first.\n"
|
|
" --cxx17ns: suggests the more concise syntax introduced in C++17\n"
|
|
" --error[=N]: exit with N (default: 1) for iwyu violations\n"
|
|
" --error_always[=N]: always exit with N (default: 1) (for use\n"
|
|
" with 'make -k')\n"
|
|
" --debug=flag[,flag...]: debug flags (undocumented)\n"
|
|
" --regex=<dialect>: use specified regex dialect in IWYU:\n"
|
|
" llvm: fast and simple (default)\n"
|
|
" ecmascript: slower, but more feature-complete\n"
|
|
"\n"
|
|
"In addition to IWYU-specific options you can specify the following\n"
|
|
"options without -Xiwyu prefix:\n"
|
|
" --help: prints this help and exits.\n"
|
|
" --version: prints version and exits.\n");
|
|
if (extra_msg)
|
|
printf("\n%s\n\n", extra_msg);
|
|
}
|
|
|
|
static void PrintVersion() {
|
|
llvm::outs() << "include-what-you-use " << IWYU_VERSION_STRING;
|
|
// IWYU_GIT_REV should be provided by build system.
|
|
string iwyu_rev = IWYU_GIT_REV;
|
|
if (!iwyu_rev.empty()) {
|
|
llvm::outs() << " (git:" << iwyu_rev << ")";
|
|
}
|
|
llvm::outs() << " based on " << clang::getClangFullVersion()
|
|
<< "\n";
|
|
}
|
|
|
|
static bool ParseIntegerOptarg(const char* optarg, int* res) {
|
|
char* endptr = nullptr;
|
|
long val = strtol(optarg, &endptr, 10);
|
|
if (!endptr || endptr == optarg)
|
|
return false;
|
|
|
|
if (*endptr != '\0')
|
|
return false;
|
|
|
|
if (val > INT_MAX || val < INT_MIN)
|
|
return false;
|
|
|
|
*res = (int)val;
|
|
return true;
|
|
}
|
|
|
|
OptionsParser::OptionsParser(int argc, char** argv) {
|
|
// Separate out iwyu-specific, intercepted, and clang flags. iwyu-specific
|
|
// flags are "-Xiwyu <iwyu_flag>", intercepted flags are usual clang flags
|
|
// like --version, --help, which we intercept to provide custom handling.
|
|
char** iwyu_argv = new char*[argc + 1];
|
|
iwyu_argv[0] = argv[0];
|
|
int iwyu_argc = 1;
|
|
char** intercepted_argv = new char*[argc + 1];
|
|
intercepted_argv[0] = argv[0];
|
|
int intercepted_argc = 1;
|
|
clang_argv_ = new const char*[argc + 1];
|
|
clang_argv_[0] = argv[0];
|
|
clang_argc_ = 1;
|
|
for (int i = 1; i < argc; ++i) {
|
|
if (i < argc - 1 && strcmp(argv[i], "-Xiwyu") == 0)
|
|
iwyu_argv[iwyu_argc++] = argv[++i]; // the word after -Xiwyu
|
|
else if (strcmp(argv[i], "--help") == 0)
|
|
intercepted_argv[intercepted_argc++] = argv[i]; // intercept --help
|
|
else if (strcmp(argv[i], "--version") == 0)
|
|
intercepted_argv[intercepted_argc++] = argv[i]; // intercept --version
|
|
else
|
|
clang_argv_[clang_argc_++] = argv[i];
|
|
}
|
|
// argv should be nullptr-terminated
|
|
iwyu_argv[iwyu_argc] = nullptr;
|
|
intercepted_argv[intercepted_argc] = nullptr;
|
|
clang_argv_[clang_argc_] = nullptr;
|
|
|
|
ParseInterceptedCommandlineFlags(intercepted_argc, intercepted_argv);
|
|
ParseIwyuCommandlineFlags(iwyu_argc, iwyu_argv);
|
|
|
|
delete [] iwyu_argv;
|
|
delete [] intercepted_argv;
|
|
}
|
|
|
|
OptionsParser::~OptionsParser() {
|
|
delete [] clang_argv_;
|
|
}
|
|
|
|
CommandlineFlags::CommandlineFlags()
|
|
: transitive_includes_only(false),
|
|
verbose(getenv("IWYU_VERBOSE") ? atoi(getenv("IWYU_VERBOSE")) : 1),
|
|
no_default_mappings(false),
|
|
max_line_length(80),
|
|
prefix_header_include_policy(CommandlineFlags::kAdd),
|
|
pch_in_code(false),
|
|
no_comments(false),
|
|
update_comments(false),
|
|
comments_with_namespace(false),
|
|
no_fwd_decls(false),
|
|
quoted_includes_first(false),
|
|
cxx17ns(false),
|
|
exit_code_error(EXIT_SUCCESS),
|
|
exit_code_always(EXIT_SUCCESS),
|
|
regex_dialect(RegexDialect::LLVM) {
|
|
// Always keep Qt .moc includes; its moc compiler does its own IWYU analysis.
|
|
keep.emplace("*.moc");
|
|
}
|
|
|
|
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'},
|
|
{"no_default_mappings", no_argument, nullptr, 'n'},
|
|
{"prefix_header_includes", required_argument, nullptr, 'x'},
|
|
{"pch_in_code", no_argument, nullptr, 'h'},
|
|
{"max_line_length", required_argument, nullptr, 'l'},
|
|
{"comment_style", required_argument, nullptr, 'i'},
|
|
{"no_comments", no_argument, nullptr, 'o'},
|
|
{"update_comments", no_argument, nullptr, 'u'},
|
|
{"no_fwd_decls", no_argument, nullptr, 'f'},
|
|
{"quoted_includes_first", no_argument, nullptr, 'q' },
|
|
{"cxx17ns", no_argument, nullptr, 'C'},
|
|
{"error", optional_argument, nullptr, 'e'},
|
|
{"error_always", optional_argument, nullptr, 'a'},
|
|
{"debug", required_argument, nullptr, 'd'},
|
|
{"regex", required_argument, nullptr, 'r'},
|
|
{nullptr, 0, nullptr, 0}
|
|
};
|
|
static const char shortopts[] = "v:c:m:d:nr";
|
|
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;
|
|
case 'n': no_default_mappings = true; break;
|
|
case 'o': no_comments = true; break;
|
|
case 'u': update_comments = true; break;
|
|
case 'i':
|
|
if (strcmp(optarg, "none") == 0) {
|
|
no_comments = true;
|
|
} else if (strcmp(optarg, "short") == 0) {
|
|
comments_with_namespace = false;
|
|
} else if (strcmp(optarg, "long") == 0) {
|
|
comments_with_namespace = true;
|
|
} else {
|
|
PrintHelp("FATAL ERROR: unknown comment style.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
break;
|
|
case 'f': no_fwd_decls = true; break;
|
|
case 'x':
|
|
if (strcmp(optarg, "add") == 0) {
|
|
prefix_header_include_policy = CommandlineFlags::kAdd;
|
|
} else if (strcmp(optarg, "keep") == 0) {
|
|
prefix_header_include_policy = CommandlineFlags::kKeep;
|
|
} else if (strcmp(optarg, "remove") == 0) {
|
|
prefix_header_include_policy = CommandlineFlags::kRemove;
|
|
} else {
|
|
PrintHelp("FATAL ERROR: unknown --prefix_header_includes value.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
break;
|
|
case 'h': pch_in_code = true; break;
|
|
case 'l':
|
|
max_line_length = atoi(optarg);
|
|
CHECK_((max_line_length >= 0) && "Max line length must be positive");
|
|
break;
|
|
case 'q': quoted_includes_first = true; break;
|
|
case 'C': cxx17ns = true; break;
|
|
case 'e':
|
|
if (!optarg) {
|
|
exit_code_error = EXIT_FAILURE;
|
|
} else if (!ParseIntegerOptarg(optarg, &exit_code_error)) {
|
|
PrintHelp("FATAL ERROR: --error argument must be valid integer.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
break;
|
|
case 'a':
|
|
if (!optarg) {
|
|
exit_code_always = EXIT_FAILURE;
|
|
} else if (!ParseIntegerOptarg(optarg, &exit_code_always)) {
|
|
PrintHelp(
|
|
"FATAL ERROR: --error_always argument must be valid "
|
|
"integer.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
break;
|
|
case 'd': {
|
|
// Split argument on comma and save in global, ignoring empty elements.
|
|
vector<string> flags = Split(optarg, ",", 0);
|
|
dbg_flags.insert(flags.begin(),
|
|
std::remove(flags.begin(), flags.end(), string()));
|
|
// Print all effective flags for traceability.
|
|
for (const string& f : dbg_flags) {
|
|
llvm::errs() << "Debug flag enabled: '" << f << "'\n";
|
|
}
|
|
break;
|
|
}
|
|
case 'r':
|
|
if (!ParseRegexDialect(optarg, ®ex_dialect)) {
|
|
PrintHelp("FATAL ERROR: unsupported regex dialect.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
break;
|
|
case -1:
|
|
return optind; // means 'no more input'
|
|
default:
|
|
PrintHelp("FATAL ERROR: unknown flag.");
|
|
exit(EXIT_FAILURE);
|
|
break;
|
|
}
|
|
}
|
|
|
|
CHECK_UNREACHABLE_("All switches should be handled above");
|
|
}
|
|
|
|
bool CommandlineFlags::HasDebugFlag(const char* flag) const {
|
|
return dbg_flags.find(string(flag)) != dbg_flags.end();
|
|
}
|
|
|
|
// Though option -v prints version too, it isn't intercepted because it also
|
|
// provides other functionality like printing clang invocation, header search
|
|
// paths.
|
|
// TODO(vsapsai): provide IWYU version in Driver::PrintVersion when version
|
|
// callbacks are supported (see FIXME in Driver::PrintVersion).
|
|
static int ParseInterceptedCommandlineFlags(int argc, char** argv) {
|
|
static const struct option longopts[] = {
|
|
{"help", no_argument, nullptr, 'h'},
|
|
{"version", no_argument, nullptr, 'v'},
|
|
{nullptr, 0, nullptr, 0}
|
|
};
|
|
static const char shortopts[] = "";
|
|
while (true) {
|
|
switch (getopt_long(argc, argv, shortopts, longopts, nullptr)) {
|
|
case 'h': PrintHelp(""); exit(EXIT_SUCCESS); break;
|
|
case 'v': PrintVersion(); exit(EXIT_SUCCESS); break;
|
|
case -1:
|
|
return optind; // means 'no more input'
|
|
default:
|
|
PrintHelp("FATAL ERROR: unknown flag.");
|
|
exit(EXIT_FAILURE);
|
|
break;
|
|
}
|
|
}
|
|
return optind; // unreachable
|
|
}
|
|
|
|
// Handles all iwyu-specific flags, like --verbose. Returns the index into
|
|
// argv past all the iwyu commandline flags.
|
|
static int ParseIwyuCommandlineFlags(int argc, char** argv) {
|
|
CHECK_(commandline_flags == nullptr && "Only parse commandline flags once");
|
|
commandline_flags = new CommandlineFlags;
|
|
const int retval = commandline_flags->ParseArgv(argc, argv);
|
|
SetVerboseLevel(commandline_flags->verbose);
|
|
|
|
VERRS(4) << "Setting verbose-level to " << commandline_flags->verbose << "\n";
|
|
|
|
return retval;
|
|
}
|
|
|
|
// Make sure we put longer search-paths first, so iwyu will map
|
|
// /usr/include/c++/4.4/foo to <foo> rather than <c++/4.4/foo>.
|
|
static bool SortByDescendingLength(const HeaderSearchPath& left,
|
|
const HeaderSearchPath& right) {
|
|
return left.path.length() > right.path.length();
|
|
}
|
|
|
|
// Sorts them by descending length, does other kinds of cleanup.
|
|
static vector<HeaderSearchPath> NormalizeHeaderSearchPaths(
|
|
const map<string, HeaderSearchPath::Type>& include_dirs_map) {
|
|
vector<HeaderSearchPath> include_dirs;
|
|
for (const auto& entry : include_dirs_map) {
|
|
include_dirs.push_back(HeaderSearchPath(entry.first, entry.second));
|
|
}
|
|
|
|
sort(include_dirs.begin(), include_dirs.end(), &SortByDescendingLength);
|
|
return include_dirs;
|
|
}
|
|
|
|
// Asks clang what the search-paths are for include files, normalizes
|
|
// them, and returns them in a vector.
|
|
static vector<HeaderSearchPath> ComputeHeaderSearchPaths(
|
|
clang::HeaderSearch* header_search) {
|
|
map<string, HeaderSearchPath::Type> search_path_map;
|
|
for (auto it = header_search->system_dir_begin();
|
|
it != header_search->system_dir_end(); ++it) {
|
|
if (const DirectoryEntry* entry = it->getDir()) {
|
|
const string path = NormalizeDirPath(MakeAbsolutePath(entry->getName().str()));
|
|
search_path_map[path] = HeaderSearchPath::kSystemPath;
|
|
}
|
|
}
|
|
for (auto it = header_search->search_dir_begin();
|
|
it != header_search->search_dir_end(); ++it) {
|
|
if (const DirectoryEntry* entry = it->getDir()) {
|
|
// search_dir_begin()/end() includes both system and user paths.
|
|
// If it's a system path, it's already in the map, so everything
|
|
// new is a user path. The insert only 'takes' for new entries.
|
|
const string path = NormalizeDirPath(MakeAbsolutePath(entry->getName().str()));
|
|
search_path_map.insert(make_pair(path, HeaderSearchPath::kUserPath));
|
|
}
|
|
}
|
|
return NormalizeHeaderSearchPaths(search_path_map);
|
|
}
|
|
|
|
void InitGlobals(clang::SourceManager* sm, clang::HeaderSearch* header_search) {
|
|
CHECK_(sm && "InitGlobals() needs a non-nullptr SourceManager");
|
|
source_manager = sm;
|
|
data_getter = new SourceManagerCharacterDataGetter(*source_manager);
|
|
vector<HeaderSearchPath> search_paths =
|
|
ComputeHeaderSearchPaths(header_search);
|
|
SetHeaderSearchPaths(search_paths);
|
|
include_picker = new IncludePicker(GlobalFlags().no_default_mappings,
|
|
GlobalFlags().regex_dialect);
|
|
function_calls_full_use_cache = new FullUseCache;
|
|
class_members_full_use_cache = new FullUseCache;
|
|
|
|
for (const HeaderSearchPath& entry : search_paths) {
|
|
const char* path_type_name =
|
|
(entry.path_type == HeaderSearchPath::kSystemPath ? "system" : "user");
|
|
VERRS(6) << "Search path: " << entry.path << " (" << path_type_name
|
|
<< ")\n";
|
|
}
|
|
|
|
// Add mappings.
|
|
for (const string& mapping_file : GlobalFlags().mapping_files) {
|
|
include_picker->AddMappingsFromFile(mapping_file);
|
|
}
|
|
}
|
|
|
|
const CommandlineFlags& GlobalFlags() {
|
|
CHECK_(commandline_flags && "Call ParseIwyuCommandlineFlags() before this");
|
|
return *commandline_flags;
|
|
}
|
|
|
|
CommandlineFlags* MutableGlobalFlagsForTesting() {
|
|
CHECK_(commandline_flags && "Call ParseIwyuCommandlineFlags() before this");
|
|
return commandline_flags;
|
|
}
|
|
|
|
clang::SourceManager* GlobalSourceManager() {
|
|
CHECK_(source_manager && "Must call InitGlobals() before calling this");
|
|
return source_manager;
|
|
}
|
|
|
|
const IncludePicker& GlobalIncludePicker() {
|
|
CHECK_(include_picker && "Must call InitGlobals() before calling this");
|
|
return *include_picker;
|
|
}
|
|
|
|
IncludePicker* MutableGlobalIncludePicker() {
|
|
CHECK_(include_picker && "Must call InitGlobals() before calling this");
|
|
return include_picker;
|
|
}
|
|
|
|
const clang::PrintingPolicy& DefaultPrintPolicy() {
|
|
return default_print_policy;
|
|
}
|
|
|
|
const SourceManagerCharacterDataGetter& DefaultDataGetter() {
|
|
CHECK_(data_getter && "Must call InitGlobals() before calling this");
|
|
return *data_getter;
|
|
}
|
|
|
|
FullUseCache* FunctionCallsFullUseCache() {
|
|
return function_calls_full_use_cache;
|
|
}
|
|
|
|
FullUseCache* ClassMembersFullUseCache() {
|
|
return class_members_full_use_cache;
|
|
}
|
|
|
|
void AddGlobToReportIWYUViolationsFor(const string& glob) {
|
|
CHECK_(commandline_flags && "Call ParseIwyuCommandlineFlags() before this");
|
|
commandline_flags->check_also.insert(NormalizeFilePath(glob));
|
|
}
|
|
|
|
bool ShouldReportIWYUViolationsFor(const clang::FileEntry* file) {
|
|
const string filepath = GetFilePath(file);
|
|
for (const string& glob : GlobalFlags().check_also)
|
|
if (GlobMatchesPath(glob.c_str(), filepath.c_str()))
|
|
return true;
|
|
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");
|
|
commandline_flags = new CommandlineFlags;
|
|
source_manager = nullptr;
|
|
data_getter = nullptr;
|
|
include_picker = new IncludePicker(GlobalFlags().no_default_mappings,
|
|
GlobalFlags().regex_dialect);
|
|
function_calls_full_use_cache = new FullUseCache;
|
|
class_members_full_use_cache = new FullUseCache;
|
|
|
|
// Use a reasonable default for the -I flags.
|
|
map<string, HeaderSearchPath::Type> search_path_map;
|
|
search_path_map["/usr/include/"] = HeaderSearchPath::kSystemPath;
|
|
search_path_map["/usr/include/c++/4.3/"] = HeaderSearchPath::kSystemPath;
|
|
search_path_map["/usr/include/c++/4.2/"] = HeaderSearchPath::kSystemPath;
|
|
search_path_map["./"] = HeaderSearchPath::kUserPath;
|
|
search_path_map["/usr/src/linux-headers-2.6.24-gg23/include/"] =
|
|
HeaderSearchPath::kSystemPath;
|
|
|
|
SetHeaderSearchPaths(NormalizeHeaderSearchPaths(search_path_map));
|
|
}
|
|
|
|
} // namespace include_what_you_use
|