summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Kilroy <kilroyd@googlemail.com>2023-03-21 12:09:53 +0000
committerKim Gräsman <kim.grasman@gmail.com>2023-04-02 12:22:20 +0200
commita3bfcc8ecb1783e16ec36f06492514f570acf8a3 (patch)
tree86ccbefa436ea4cfb4691eb7ad7bb331e47b365f
parentff6936ab99454ec4f5fa9109673e555b9ea5b189 (diff)
Refactor to allow stdlib selection
Allow independent selection of the internal standard library mappings in IncludePicker construction. For now only the GNU implementations are available, the alternative being no mapping (selected by --no_default_mappings). In preparation for an alternative C++ library, move the current libstdc++ symbol mappings (which are kludges for how to treat particular symbols) to a generic table that can be shared, and add a separate table specifically for libstdc++.
-rw-r--r--iwyu_globals.cc23
-rw-r--r--iwyu_include_picker.cc56
-rw-r--r--iwyu_include_picker.h7
3 files changed, 61 insertions, 25 deletions
diff --git a/iwyu_globals.cc b/iwyu_globals.cc
index bf0831d..b43a480 100644
--- a/iwyu_globals.cc
+++ b/iwyu_globals.cc
@@ -415,8 +415,15 @@ void InitGlobals(clang::SourceManager* sm, clang::HeaderSearch* header_search) {
vector<HeaderSearchPath> search_paths =
ComputeHeaderSearchPaths(header_search);
SetHeaderSearchPaths(search_paths);
- include_picker = new IncludePicker(GlobalFlags().no_default_mappings,
- GlobalFlags().regex_dialect);
+ CStdLib cstdlib = CStdLib::Glibc;
+ CXXStdLib cxxstdlib = CXXStdLib::Libstdcxx;
+ if (GlobalFlags().no_default_mappings) {
+ cstdlib = CStdLib::None;
+ cxxstdlib = CXXStdLib::None;
+ }
+
+ include_picker =
+ new IncludePicker(GlobalFlags().regex_dialect, cstdlib, cxxstdlib);
function_calls_full_use_cache = new FullUseCache;
class_members_full_use_cache = new FullUseCache;
@@ -509,8 +516,16 @@ void InitGlobalsAndFlagsForTesting() {
commandline_flags = new CommandlineFlags;
source_manager = nullptr;
data_getter = nullptr;
- include_picker = new IncludePicker(GlobalFlags().no_default_mappings,
- GlobalFlags().regex_dialect);
+ CStdLib cstdlib = CStdLib::Glibc;
+ CXXStdLib cxxstdlib = CXXStdLib::Libstdcxx;
+ if (GlobalFlags().no_default_mappings) {
+ cstdlib = CStdLib::None;
+ cxxstdlib = CXXStdLib::None;
+ }
+
+ include_picker =
+ new IncludePicker(GlobalFlags().regex_dialect, cstdlib, cxxstdlib);
+
function_calls_full_use_cache = new FullUseCache;
class_members_full_use_cache = new FullUseCache;
diff --git a/iwyu_include_picker.cc b/iwyu_include_picker.cc
index 8ee61f8..638bf3f 100644
--- a/iwyu_include_picker.cc
+++ b/iwyu_include_picker.cc
@@ -339,9 +339,9 @@ const IncludeMapEntry libc_symbol_map[] = {
{ "NULL", kPrivate, "<wchar.h>", kPublic },
};
-// Symbol -> include mappings for GNU libstdc++
-const IncludeMapEntry libstdcpp_symbol_map[] = {
- // Kludge time: almost all STL types take an allocator, but they
+// Common kludges for C++ standard libraries
+const IncludeMapEntry stdlib_cxx_symbol_map[] = {
+ // Almost all STL types take an allocator, but they
// almost always use the default value. Usually we detect that
// and don't try to do IWYU, but sometimes it passes through.
// For instance, when adding two strings, we end up calling
@@ -374,6 +374,9 @@ const IncludeMapEntry libstdcpp_symbol_map[] = {
{ "std::size_t", kPrivate, "<cwchar>", kPublic },
};
+// Symbol -> include mappings for GNU libstdc++
+const IncludeMapEntry libstdcpp_symbol_map[] = {};
+
const IncludeMapEntry libc_include_map[] = {
// Private -> public include mappings for GNU libc
// ( cd /usr/include && grep '^ *# *include' {sys/,net/,}* | perl -nle 'm/^([^:]+).*<([^>]+)>/ && print qq@ { "<$2>", kPrivate, "<$1>", kPublic },@' | grep bits/ | sort )
@@ -1231,28 +1234,43 @@ bool MappedInclude::HasAbsoluteQuotedInclude() const {
return IsAbsolutePath(path);
}
-IncludePicker::IncludePicker(bool no_default_mappings,
- RegexDialect regex_dialect)
+IncludePicker::IncludePicker(RegexDialect regex_dialect,
+ CStdLib cstdlib,
+ CXXStdLib cxxstdlib)
: has_called_finalize_added_include_lines_(false),
regex_dialect(regex_dialect) {
- if (!no_default_mappings) {
- AddDefaultMappings();
- }
+ AddDefaultMappings(cstdlib, cxxstdlib);
}
-void IncludePicker::AddDefaultMappings() {
- AddSymbolMappings(libc_symbol_map, IWYU_ARRAYSIZE(libc_symbol_map));
- AddSymbolMappings(libstdcpp_symbol_map, IWYU_ARRAYSIZE(libstdcpp_symbol_map));
+void IncludePicker::AddDefaultMappings(CStdLib cstdlib,
+ CXXStdLib cxxstdlib) {
+ if (cstdlib == CStdLib::Glibc) {
+ AddSymbolMappings(libc_symbol_map, IWYU_ARRAYSIZE(libc_symbol_map));
+ AddIncludeMappings(libc_include_map, IWYU_ARRAYSIZE(libc_include_map));
+ }
- AddIncludeMappings(libc_include_map,
- IWYU_ARRAYSIZE(libc_include_map));
- AddIncludeMappings(stdlib_c_include_map,
- IWYU_ARRAYSIZE(stdlib_c_include_map));
- AddIncludeMappings(libstdcpp_include_map,
- IWYU_ARRAYSIZE(libstdcpp_include_map));
+ if (cxxstdlib == CXXStdLib::Libstdcxx) {
+ AddSymbolMappings(libstdcpp_symbol_map,
+ IWYU_ARRAYSIZE(libstdcpp_symbol_map));
+ AddIncludeMappings(libstdcpp_include_map,
+ IWYU_ARRAYSIZE(libstdcpp_include_map));
+ }
+
+ if (cxxstdlib != CXXStdLib::None) {
+ // Map C headers to associated C++ headers. The standard library
+ // mappings shouldn't be mentioning the C headers.
+ AddIncludeMappings(stdlib_c_include_map,
+ IWYU_ARRAYSIZE(stdlib_c_include_map));
- AddPublicIncludes(stdlib_cpp_public_headers,
- IWYU_ARRAYSIZE(stdlib_cpp_public_headers));
+ // Add common C++ mappings to deal with generic C++ standard
+ // library symbol issues (so the standard library doesn't have to
+ // do this too). If it does that's ok.
+ AddSymbolMappings(stdlib_cxx_symbol_map,
+ IWYU_ARRAYSIZE(stdlib_cxx_symbol_map));
+
+ AddPublicIncludes(stdlib_cpp_public_headers,
+ IWYU_ARRAYSIZE(stdlib_cpp_public_headers));
+ }
}
void IncludePicker::MarkVisibility(VisibilityMap* map,
diff --git a/iwyu_include_picker.h b/iwyu_include_picker.h
index ccf9177..712389c 100644
--- a/iwyu_include_picker.h
+++ b/iwyu_include_picker.h
@@ -67,6 +67,8 @@ struct IncludeMapEntry;
enum class RegexDialect;
enum IncludeVisibility { kUnusedVisibility, kPublic, kPrivate };
+enum class CStdLib { None, Glibc };
+enum class CXXStdLib { None, Libstdcxx };
// When a symbol or file is mapped to an include, that include is represented
// by this struct. It always has a quoted_include and may also have a path
@@ -92,7 +94,8 @@ class IncludePicker {
// visibility of the respective files.
typedef map<string, IncludeVisibility> VisibilityMap;
- IncludePicker(bool no_default_mappings, RegexDialect regex_dialect);
+ IncludePicker(RegexDialect regex_dialect, CStdLib cstdlib,
+ CXXStdLib cxxstdlib);
// ----- Routines to dynamically modify the include-picker
@@ -190,7 +193,7 @@ class IncludePicker {
const vector<string>& search_path);
// Adds all hard-coded default mappings.
- void AddDefaultMappings();
+ void AddDefaultMappings(CStdLib cstdlib, CXXStdLib cxxstdlib);
// Adds a mapping from a one header to another, typically
// from a private to a public quoted include.