summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcsilvers <csilvers@812d1f90-f944-d88a-411a-122bdc93e1ea>2012-03-06 23:19:16 +0000
committercsilvers <csilvers@812d1f90-f944-d88a-411a-122bdc93e1ea>2012-03-06 23:19:16 +0000
commitc3064e48787afa2ee3ef7646dfd77ac2ccb245da (patch)
treecfaea1f52357fef42f46d0965f5629a8e65e02c3
parent80118553e093513ca74a160f53d84b547d103543 (diff)
Version of include-what-you-use that builds against llvm+clang 3.0; used to produce include-what-you-use-3.0-1.tar.gzclang_3.0
-rw-r--r--CMakeLists.txt2
-rw-r--r--iwyu.cc5
-rw-r--r--iwyu_ast_util.cc8
-rw-r--r--iwyu_driver.cc6
-rw-r--r--iwyu_globals.cc20
-rw-r--r--iwyu_globals.h11
-rw-r--r--iwyu_include_picker.cc63
-rw-r--r--iwyu_include_picker.h19
-rw-r--r--iwyu_lexer_utils.cc3
-rw-r--r--iwyu_output.cc13
-rw-r--r--iwyu_output.h22
-rw-r--r--iwyu_path_util.cc181
-rw-r--r--iwyu_path_util.h140
-rw-r--r--iwyu_preprocessor.cc2
-rw-r--r--iwyu_verrs.cc44
-rw-r--r--iwyu_verrs.h45
-rw-r--r--more_tests/iwyu_output_test.cc9
-rw-r--r--tests/badinc.cc3
-rw-r--r--tests/badinc.h4
-rw-r--r--tests/fwd_decl_of_nested_class_defined_later.cc40
-rw-r--r--tests/integer_template_arg.cc19
21 files changed, 236 insertions, 423 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1095a0e..96715e4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,9 +31,7 @@ add_clang_executable(include-what-you-use
iwyu_lexer_utils.cc
iwyu_location_util.cc
iwyu_output.cc
- iwyu_path_util.cc
iwyu_preprocessor.cc
- iwyu_verrs.cc
)
install(TARGETS include-what-you-use
diff --git a/iwyu.cc b/iwyu.cc
index 7923257..aa871ea 100644
--- a/iwyu.cc
+++ b/iwyu.cc
@@ -95,7 +95,6 @@
#include <stddef.h> // for size_t
#include <stdio.h> // for snprintf
#include <stdlib.h> // for atoi, exit
-#include <string.h>
#include <algorithm> // for swap, find, make_pair
#include <deque> // for swap
#include <iterator> // for find
@@ -118,7 +117,6 @@
#include "iwyu_preprocessor.h" // IWYU pragma: keep
#include "iwyu_stl_util.h"
#include "iwyu_string_util.h"
-#include "iwyu_verrs.h"
#include "port.h" // for CHECK_
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
@@ -1908,8 +1906,6 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
// These casts don't require any iwyu action.
case clang::CK_LValueToRValue:
- case clang::CK_AtomicToNonAtomic:
- case clang::CK_NonAtomicToAtomic:
break;
// We shouldn't be seeing any of these kinds.
@@ -1955,6 +1951,7 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
case clang::CK_ARCReclaimReturnedObject:
case clang::CK_BlockPointerToObjCPointerCast:
case clang::CK_CPointerToObjCPointerCast:
+ case clang::CK_GetObjCProperty:
case clang::CK_ObjCObjectLValueCast:
case clang::CK_VectorSplat:
CHECK_(false && "TODO(csilvers): for objc and clang lang extensions");
diff --git a/iwyu_ast_util.cc b/iwyu_ast_util.cc
index e05dfc9..135c5b8 100644
--- a/iwyu_ast_util.cc
+++ b/iwyu_ast_util.cc
@@ -17,10 +17,10 @@
#include "iwyu_globals.h"
#include "iwyu_location_util.h"
+#include "iwyu_output.h"
#include "iwyu_path_util.h"
#include "iwyu_stl_util.h"
#include "iwyu_string_util.h"
-#include "iwyu_verrs.h"
#include "port.h" // for CHECK_
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
@@ -224,9 +224,7 @@ bool IsNodeInsideCXXMethodBody(const ASTNode* ast_node) {
}
if (const CXXMethodDecl* method_decl =
ast_node->GetParentAs<CXXMethodDecl>()) {
- if (ast_node->ContentIs(method_decl->getBody())) {
- return true;
- }
+ return ast_node->ContentIs(method_decl->getBody());
}
}
return false;
@@ -1244,7 +1242,7 @@ bool IsCastToReferenceType(const CastExpr* expr) {
const ASTTemplateArgumentListInfo* GetExplicitTplArgs(const Expr* expr) {
if (const DeclRefExpr* decl_ref = DynCastFrom(expr))
- return decl_ref->getOptionalExplicitTemplateArgs();
+ return decl_ref->getExplicitTemplateArgsOpt();
if (const MemberExpr* member_expr = DynCastFrom(expr))
return member_expr->getOptionalExplicitTemplateArgs();
// Ugh, annoying casts needed because no const methods exist.
diff --git a/iwyu_driver.cc b/iwyu_driver.cc
index 7b73fbd..0dccfcd 100644
--- a/iwyu_driver.cc
+++ b/iwyu_driver.cc
@@ -25,7 +25,6 @@
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/DiagnosticOptions.h"
-#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendDiagnostic.h" // IWYU pragma: keep
#include "clang/Frontend/TextDiagnosticPrinter.h"
@@ -57,7 +56,7 @@ using llvm::cast;
using llvm::errs;
using llvm::isa;
using llvm::raw_svector_ostream;
-using llvm::sys::getDefaultTargetTriple;
+using llvm::sys::getHostTriple;
using llvm::sys::Path;
using std::set;
@@ -158,8 +157,7 @@ CompilerInstance* CreateCompilerInstance(int argc, const char **argv) {
IntrusiveRefCntPtr<DiagnosticIDs> diagnostic_id(new DiagnosticIDs());
DiagnosticsEngine diagnostics(diagnostic_id, diagnostic_client);
- Driver driver(path.str(), getDefaultTargetTriple(), "a.out", false,
- diagnostics);
+ Driver driver(path.str(), getHostTriple(), "a.out", false, diagnostics);
driver.setTitle("include what you use");
// Expand out any response files passed on the command line
diff --git a/iwyu_globals.cc b/iwyu_globals.cc
index 922e202..642ca39 100644
--- a/iwyu_globals.cc
+++ b/iwyu_globals.cc
@@ -22,10 +22,9 @@
#include "iwyu_getopt.h"
#include "iwyu_lexer_utils.h"
#include "iwyu_location_util.h"
-#include "iwyu_path_util.h"
+#include "iwyu_output.h"
#include "iwyu_stl_util.h"
#include "iwyu_string_util.h"
-#include "iwyu_verrs.h"
#include "port.h" // for CHECK_, etc
#include "llvm/Support/raw_ostream.h"
#include "clang/AST/PrettyPrinter.h"
@@ -42,6 +41,7 @@ namespace include_what_you_use {
static CommandlineFlags* commandline_flags = NULL;
static clang::SourceManager* source_manager = NULL;
+static vector<HeaderSearchPath>* search_paths = NULL;
static IncludePicker* include_picker = NULL;
static const clang::LangOptions default_lang_options;
static const clang::PrintingPolicy default_print_policy(default_lang_options);
@@ -117,7 +117,6 @@ int ParseIwyuCommandlineFlags(int argc, char** argv) {
CHECK_(commandline_flags == NULL && "Only parse commandline flags once");
commandline_flags = new CommandlineFlags;
const int retval = commandline_flags->ParseArgv(argc, argv);
- SetVerboseLevel(commandline_flags->verbose);
if (!commandline_flags->cwd.empty()) {
printf("-p/--cwd not yet implemented\n");
@@ -185,14 +184,13 @@ void InitGlobals(clang::SourceManager* sm, clang::HeaderSearch* header_search) {
CHECK_(sm && "InitGlobals() needs a non-NULL SourceManager");
source_manager = sm;
data_getter = new SourceManagerCharacterDataGetter(*source_manager);
- vector<HeaderSearchPath> search_paths =
- ComputeHeaderSearchPaths(header_search);
- SetHeaderSearchPaths(search_paths);
+ search_paths = new vector<HeaderSearchPath>(
+ ComputeHeaderSearchPaths(header_search));
include_picker = new IncludePicker;
function_calls_full_use_cache = new FullUseCache;
class_members_full_use_cache = new FullUseCache;
- for (Each<HeaderSearchPath> it(&search_paths); !it.AtEnd(); ++it) {
+ for (Each<HeaderSearchPath> it(search_paths); !it.AtEnd(); ++it) {
const char* path_type_name
= (it->path_type == HeaderSearchPath::kSystemPath ? "system" : "user");
VERRS(6) << "Search path: " << it->path << " (" << path_type_name << ")\n";
@@ -214,6 +212,11 @@ clang::SourceManager* GlobalSourceManager() {
return source_manager;
}
+const vector<HeaderSearchPath>& GlobalHeaderSearchPaths() {
+ assert(search_paths && "Must call InitGlobals() before calling this");
+ return *search_paths;
+}
+
const IncludePicker& GlobalIncludePicker() {
CHECK_(include_picker && "Must call InitGlobals() before calling this");
return *include_picker;
@@ -272,7 +275,8 @@ void InitGlobalsAndFlagsForTesting() {
search_path_map["."] = HeaderSearchPath::kUserPath;
search_path_map["/usr/src/linux-headers-2.6.24-gg23/include"] = HeaderSearchPath::kSystemPath;
- SetHeaderSearchPaths(NormalizeHeaderSearchPaths(search_path_map));
+ search_paths = new vector<HeaderSearchPath>(
+ NormalizeHeaderSearchPaths(search_path_map));
}
} // namespace include_what_you_use
diff --git a/iwyu_globals.h b/iwyu_globals.h
index 3e68fe1..ac86b3b 100644
--- a/iwyu_globals.h
+++ b/iwyu_globals.h
@@ -76,12 +76,23 @@ struct CommandlineFlags {
int verbose; // -v: how much information to emit as we parse
};
+// One entry in the search-path list of where to find #include files.
+struct HeaderSearchPath {
+ enum Type { kUnusedPath = 0, kSystemPath, kUserPath };
+ HeaderSearchPath(const string& p, Type pt) : path(p), path_type(pt) { }
+ string path; // the path-entry as specified on the commandline (via -I)
+ Type path_type;
+};
+
const CommandlineFlags& GlobalFlags();
// Used by tests as an easy way to simulate calling with different --flags.
CommandlineFlags* MutableGlobalFlagsForTesting();
clang::SourceManager* GlobalSourceManager();
+// The directories to look for #includes in, including from -I, -isystem, etc.
+const vector<HeaderSearchPath>& GlobalHeaderSearchPaths();
+
const IncludePicker& GlobalIncludePicker();
IncludePicker* MutableGlobalIncludePicker(); // only use at great need!
diff --git a/iwyu_include_picker.cc b/iwyu_include_picker.cc
index 12bb057..cea409e 100644
--- a/iwyu_include_picker.cc
+++ b/iwyu_include_picker.cc
@@ -15,19 +15,18 @@
#include <iterator> // for find
// not hash_map: it's not as portable and needs hash<string>.
#include <map> // for map, map<>::mapped_type, etc
-#include <ostream>
#include <string> // for string, basic_string, etc
#include <utility> // for pair, make_pair
#include <vector> // for vector, vector<>::iterator
+#include "iwyu_globals.h"
+#include "iwyu_output.h"
#include "iwyu_path_util.h"
#include "iwyu_stl_util.h"
#include "iwyu_string_util.h"
-#include "iwyu_verrs.h"
#include "port.h" // for CHECK_
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Regex.h"
-#include "llvm/Support/raw_ostream.h"
using std::find;
using std::map;
@@ -600,7 +599,6 @@ const IncludePicker::IncludeMapEntry cpp_include_map[] = {
// I don't think we want to be having people move to 'backward/'
// yet. (These hold deprecated STL classes that we still use
// actively.) These are the ones that turned up in an analysis of
- { "<backward/auto_ptr.h>", kPrivate, "<memory>", kPublic },
{ "<backward/binders.h>", kPrivate, "<functional>", kPublic },
{ "<backward/hash_fun.h>", kPrivate, "<hash_map>", kPublic },
{ "<backward/hash_fun.h>", kPrivate, "<hash_set>", kPublic },
@@ -609,7 +607,6 @@ const IncludePicker::IncludeMapEntry cpp_include_map[] = {
{ "<backward/strstream>", kPrivate, "<strstream>", kPublic },
// We have backward as part of the -I search path now, so have the
// non-backwards-prefix version as well.
- { "<auto_ptr.h>", kPrivate, "<memory>", kPublic },
{ "<binders.h>", kPrivate, "<functional>", kPublic },
{ "<hash_fun.h>", kPrivate, "<hash_map>", kPublic },
{ "<hash_fun.h>", kPrivate, "<hash_set>", kPublic },
@@ -819,8 +816,64 @@ void MakeMapTransitive(IncludePicker::IncludeMap* filename_map) {
MakeNodeTransitive(filename_map, &seen_nodes, &node_stack, it->first);
}
+
} // namespace
+// Converts a file-path, such as /usr/include/stdio.h, to a
+// quoted include, such as <stdio.h>.
+string ConvertToQuotedInclude(const string& filepath) {
+ // First, get rid of leading ./'s and the like.
+ string path = NormalizeFilePath(filepath);
+
+ // Case 1: Uses an explicit entry on the search path (-I) list.
+ const vector<HeaderSearchPath>& search_paths = GlobalHeaderSearchPaths();
+ // GlobalHeaderSearchPaths is sorted to be longest-first, so this
+ // loop will prefer the longest prefix: /usr/include/c++/4.4/foo
+ // will be mapped to <foo>, not <c++/4.4/foo>.
+ for (Each<HeaderSearchPath> it(&search_paths); !it.AtEnd(); ++it) {
+ if (StripLeft(&path, it->path)) {
+ StripLeft(&path, "/");
+ if (it->path_type == HeaderSearchPath::kSystemPath)
+ return "<" + path + ">";
+ else
+ return "\"" + path + "\"";
+ }
+ }
+
+
+ // Case 2: Uses the implicit "-I." entry on the search path. Always local.
+ return "\"" + path + "\"";
+}
+
+bool IsQuotedInclude(const string& s) {
+ if (s.size() < 2)
+ return false;
+ return ((StartsWith(s, "<") && EndsWith(s, ">")) ||
+ (StartsWith(s, "\"") && EndsWith(s, "\"")));
+}
+
+// Returns whether this is a system (as opposed to user) include file,
+// based on where it lives.
+bool IsSystemIncludeFile(const string& filepath) {
+ return ConvertToQuotedInclude(filepath)[0] == '<';
+}
+
+// Returns true if the given file is third-party. Google-authored
+// code living in third_party/ is not considered third-party.
+bool IsThirdPartyFile(string quoted_path) {
+ if (!StripLeft(&quoted_path, "\"third_party/"))
+ return false;
+
+ // These are Google-authored libraries living in third_party/
+ // because of old licensing constraints.
+ if (StartsWith(quoted_path, "car/") ||
+ StartsWith(quoted_path, "gtest/") ||
+ StartsWith(quoted_path, "gmock/"))
+ return false;
+
+ return true;
+}
+
#define IWYU_ARRAYSIZE(ar) (sizeof(ar) / sizeof(*(ar)))
IncludePicker::IncludePicker()
diff --git a/iwyu_include_picker.h b/iwyu_include_picker.h
index 6834693..652b796 100644
--- a/iwyu_include_picker.h
+++ b/iwyu_include_picker.h
@@ -59,6 +59,25 @@ using std::string;
using std::vector;
+// Below, we talk 'quoted' includes. A quoted include is something
+// that would be written on an #include line, complete with the <> or
+// "". In the line '#include <time.h>', "<time.h>" is the quoted
+// include.
+
+// Converts a file-path, such as /usr/include/stdio.h, to a
+// quoted include, such as <stdio.h>.
+string ConvertToQuotedInclude(const string& filepath);
+
+bool IsQuotedInclude(const string& s);
+
+// Returns whether this is a system (as opposed to user) include
+// file, based on where it lives.
+bool IsSystemIncludeFile(const string& filepath);
+
+// Returns true if the given file is third-party. Google-authored
+// code living in third_party/ is not considered third-party.
+bool IsThirdPartyFile(string quoted_path);
+
class IncludePicker {
public:
enum Visibility { kUnusedVisibility, kPublic, kPrivate };
diff --git a/iwyu_lexer_utils.cc b/iwyu_lexer_utils.cc
index 81f57e4..ca17340 100644
--- a/iwyu_lexer_utils.cc
+++ b/iwyu_lexer_utils.cc
@@ -10,11 +10,10 @@
#include "iwyu_lexer_utils.h"
-#include <string.h>
#include <string>
#include <vector>
-#include "iwyu_verrs.h"
+#include "iwyu_output.h"
#include "port.h"
#include "llvm/Support/raw_ostream.h"
#include "clang/Basic/LangOptions.h"
diff --git a/iwyu_output.cc b/iwyu_output.cc
index 1a84e56..a83f878 100644
--- a/iwyu_output.cc
+++ b/iwyu_output.cc
@@ -25,7 +25,6 @@
#include "iwyu_preprocessor.h" // IWYU pragma: keep
#include "iwyu_stl_util.h"
#include "iwyu_string_util.h"
-#include "iwyu_verrs.h"
// TODO(wan): remove this once the IWYU bug is fixed.
// IWYU pragma: no_include "foo/bar/baz.h"
#include "llvm/Support/Casting.h"
@@ -63,6 +62,18 @@ using std::pair;
using std::sort;
using std::vector;
+bool ShouldPrintSymbolFromFile(const FileEntry* file) {
+ if (GlobalFlags().verbose < 5) {
+ return false;
+ } else if (GlobalFlags().verbose < 10) {
+ return ShouldReportIWYUViolationsFor(file);
+ } else if (GlobalFlags().verbose < 11) {
+ return !IsSystemIncludeFile(GetFilePath(file));
+ } else {
+ return true;
+ }
+}
+
namespace internal {
namespace {
diff --git a/iwyu_output.h b/iwyu_output.h
index 4954750..c05a782 100644
--- a/iwyu_output.h
+++ b/iwyu_output.h
@@ -11,7 +11,7 @@
// iwyu plug-in. This includes functions to sanitize include-files
// (though most of the underlying logic is in iwyu_sanitize_filepath),
// to sanitize symbol names, to emit desired include-lines properly,
-// etc.
+// etc. It also controls logging and verbosity levels.
#ifndef DEVTOOLS_MAINTENANCE_INCLUDE_WHAT_YOU_USE_IWYU_OUTPUT_H_
#define DEVTOOLS_MAINTENANCE_INCLUDE_WHAT_YOU_USE_IWYU_OUTPUT_H_
@@ -21,8 +21,10 @@
#include <string> // for string, operator<
#include <vector> // for vector
+#include "iwyu_globals.h"
#include "iwyu_stl_util.h"
#include "port.h" // for CHECK_
+#include "llvm/Support/raw_ostream.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/SourceLocation.h"
@@ -41,6 +43,24 @@ using std::vector;
class IwyuPreprocessorInfo;
+// Returns true if we should print a message at the given verbosity level.
+inline bool ShouldPrint(int verbose_level) {
+ return verbose_level <= GlobalFlags().verbose;
+}
+
+// Returns true if we should print information about a symbol in the
+// given file, at the current verbosity level. For instance, at most
+// normal verbosities, we don't print information about symbols in
+// system header files.
+bool ShouldPrintSymbolFromFile(const clang::FileEntry* file);
+
+// VERRS(n) << blah;
+// prints blah to errs() if the verbose level is >= n.
+#define VERRS(verbose_level) \
+ if (!::include_what_you_use::ShouldPrint( \
+ verbose_level)) ; else ::llvm::errs()
+
+
// This data structure holds information about a single use. Not all
// fields will be filled for all uses.
class OneUse {
diff --git a/iwyu_path_util.cc b/iwyu_path_util.cc
deleted file mode 100644
index cd9e3f2..0000000
--- a/iwyu_path_util.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-//===--- iwyu_path_util.cc - path utilities for iwyu ----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "iwyu_path_util.h"
-
-#include <stddef.h>
-
-#include "iwyu_stl_util.h"
-
-namespace include_what_you_use {
-
-namespace {
-vector<HeaderSearchPath>* header_search_paths;
-} // namespace
-
-void SetHeaderSearchPaths(const vector<HeaderSearchPath>& search_paths) {
- if (header_search_paths != NULL) {
- delete header_search_paths;
- }
- header_search_paths = new vector<HeaderSearchPath>(search_paths);
-}
-
-const vector<HeaderSearchPath>& HeaderSearchPaths() {
- if (header_search_paths == NULL) {
- header_search_paths = new vector<HeaderSearchPath>();
- }
- return *header_search_paths;
-}
-
-namespace {
-
-} // namespace
-
-bool IsHeaderFile(string path) {
- if (EndsWith(path, "\"") || EndsWith(path, ">"))
- path = path.substr(0, path.length() - 1);
-
- // Some headers don't have an extension (e.g. <string>), or have an
- // unusual one (the compiler doesn't care), so it's safer to
- // enumerate non-header extensions instead.
- if (EndsWith(path, ".cc") || EndsWith(path, ".c") ||
- EndsWith(path, ".cxx") || EndsWith(path, ".cpp"))
- return false;
- return true;
-}
-
-string GetCWD() {
- char cwd[PATH_MAX];
- if (getcwd(cwd, sizeof(cwd)))
- return cwd;
- return "";
-}
-
-string Basename(const string& path) {
- string::size_type last_slash = path.rfind('/');
- if (last_slash != string::npos) {
- return path.substr(last_slash + 1);
- }
- return path;
-}
-
-string CanonicalizeFilePath(const string& path) {
- string result = path;
-
-#ifdef _MSC_VER
- // canonicalise directory separators (forward slashes considered canonical)
- for (size_t i = 0; i < result.size(); ++i) {
- if (result[i] == '\\')
- result[i] = '/';
- }
-#endif
-
- // We may also want to collapse ../ here.
-
- return result;
-}
-
-string GetCanonicalName(string file_path) {
- // Get rid of any <> and "" in case file_path is really an #include line.
- StripLeft(&file_path, "\"") || StripLeft(&file_path, "<");
- StripRight(&file_path, "\"") || StripRight(&file_path, ">");
-
- file_path = CanonicalizeFilePath(file_path);
-
- StripRight(&file_path, ".h")
- || StripRight(&file_path, ".hpp")
- || StripRight(&file_path, ".hxx")
- || StripRight(&file_path, ".hh")
- || StripRight(&file_path, ".inl")
- || StripRight(&file_path, ".cxx")
- || StripRight(&file_path, ".cpp")
- || StripRight(&file_path, ".cc")
- || StripRight(&file_path, ".c");
- StripRight(&file_path, "_unittest")
- || StripRight(&file_path, "_regtest")
- || StripRight(&file_path, "_test")
- || StripLeft(&file_path, "test_headercompile_");
- StripRight(&file_path, "-inl");
- // .h files in /public/ match .cc files in /internal/
- const string::size_type internal_pos = file_path.find("/internal/");
- if (internal_pos != string::npos)
- file_path = (file_path.substr(0, internal_pos) + "/public/" +
- file_path.substr(internal_pos + strlen("/internal/")));
-
- // .h files in /include/ match .cc files in /src/
- const string::size_type include_pos = file_path.find("/include/");
- if (include_pos != string::npos)
- file_path = (file_path.substr(0, include_pos) + "/src/" +
- file_path.substr(include_pos + strlen("/include/")));
- return file_path;
-}
-
-string NormalizeFilePath(const string& path) {
- string result = CanonicalizeFilePath(path);
- while (StripLeft(&result, "./")) {
- }
- return result;
-}
-
-// Converts a file-path, such as /usr/include/stdio.h, to a
-// quoted include, such as <stdio.h>.
-string ConvertToQuotedInclude(const string& filepath) {
- // First, get rid of leading ./'s and the like.
- string path = NormalizeFilePath(filepath);
-
- // Case 1: Uses an explicit entry on the search path (-I) list.
- const vector<HeaderSearchPath>& search_paths = HeaderSearchPaths();
- // HeaderSearchPaths is sorted to be longest-first, so this
- // loop will prefer the longest prefix: /usr/include/c++/4.4/foo
- // will be mapped to <foo>, not <c++/4.4/foo>.
- for (Each<HeaderSearchPath> it(&search_paths); !it.AtEnd(); ++it) {
- if (StripLeft(&path, it->path)) {
- StripLeft(&path, "/");
- if (it->path_type == HeaderSearchPath::kSystemPath)
- return "<" + path + ">";
- else
- return "\"" + path + "\"";
- }
- }
-
-
- // Case 2: Uses the implicit "-I." entry on the search path. Always local.
- return "\"" + path + "\"";
-}
-
-bool IsQuotedInclude(const string& s) {
- if (s.size() < 2)
- return false;
- return ((StartsWith(s, "<") && EndsWith(s, ">")) ||
- (StartsWith(s, "\"") && EndsWith(s, "\"")));
-}
-
-// Returns whether this is a system (as opposed to user) include file,
-// based on where it lives.
-bool IsSystemIncludeFile(const string& filepath) {
- return ConvertToQuotedInclude(filepath)[0] == '<';
-}
-
-// Returns true if the given file is third-party. Google-authored
-// code living in third_party/ is not considered third-party.
-bool IsThirdPartyFile(string quoted_path) {
- if (!StripLeft(&quoted_path, "\"third_party/"))
- return false;
-
- // These are Google-authored libraries living in third_party/
- // because of old licensing constraints.
- if (StartsWith(quoted_path, "car/") ||
- StartsWith(quoted_path, "gtest/") ||
- StartsWith(quoted_path, "gmock/"))
- return false;
-
- return true;
-}
-
-} // namespace include_what_you_use
diff --git a/iwyu_path_util.h b/iwyu_path_util.h
index c4ec715..b956d6c 100644
--- a/iwyu_path_util.h
+++ b/iwyu_path_util.h
@@ -20,72 +20,102 @@
#include <unistd.h> // for getcwd
#endif
#include <string> // for string, allocator, etc
-#include <vector>
#include "iwyu_string_util.h"
namespace include_what_you_use {
using std::string;
-using std::vector;
-// One entry in the search-path list of where to find #include files.
-struct HeaderSearchPath {
- enum Type { kUnusedPath = 0, kSystemPath, kUserPath };
- HeaderSearchPath(const string& p, Type pt) : path(p), path_type(pt) { }
- string path; // the path-entry as specified on the commandline (via -I)
- Type path_type;
-};
-
-// The directories to look for #includes in, including from -I, -isystem, etc.
-void SetHeaderSearchPaths(const vector<HeaderSearchPath>& search_paths);
-const vector<HeaderSearchPath>& HeaderSearchPaths();
-
// Returns true if 'path' is a path of a (possibly enclosed in double
// quotes or <>) C++ header file.
-bool IsHeaderFile(string path);
-
-// Return the current working directory of this process.
-string GetCWD();
-
-// If the path has a slash, return the part after the last slash,
-// else return the input path.
-string Basename(const string& path);
-
-// On Microsoft platforms, convert \ to /.
-string CanonicalizeFilePath(const string& path);
-
-// Removes enclosing <> or "", then strips uninteresting suffixes from
-// the file name. Replaces "/internal/" with "/public/" and
-// "/include/" with "/src". "Canonicalize" the path on Microsoft
-// platforms.
-string GetCanonicalName(string file_path);
-
-
-// "Canonicals" the name on Microsoft platforms, then recursively
-// removes all "./" prefixes.
-string NormalizeFilePath(const string& path);
-
-// Below, we talk 'quoted' includes. A quoted include is something
-// that would be written on an #include line, complete with the <> or
-// "". In the line '#include <time.h>', "<time.h>" is the quoted
-// include.
-
-// Converts a file-path, such as /usr/include/stdio.h, to a
-// quoted include, such as <stdio.h>.
-string ConvertToQuotedInclude(const string& filepath);
-
-// Returns true if the string is a quoted include.
-bool IsQuotedInclude(const string& s);
-
-// Returns whether this is a system (as opposed to user) include
-// file, based on where it lives.
-bool IsSystemIncludeFile(const string& filepath);
+inline bool IsHeaderFile(string path) {
+ if (EndsWith(path, "\"") || EndsWith(path, ">"))
+ path = path.substr(0, path.length() - 1);
+
+ // Some headers don't have an extension (e.g. <string>), or have an
+ // unusual one (the compiler doesn't care), so it's safer to
+ // enumerate non-header extensions instead.
+ if (EndsWith(path, ".cc") || EndsWith(path, ".c") ||
+ EndsWith(path, ".cxx") || EndsWith(path, ".cpp"))
+ return false;
+ return true;
+}
+
+inline string GetCWD() {
+ char cwd[PATH_MAX];
+ if (getcwd(cwd, sizeof(cwd)))
+ return cwd;
+ return "";
+}
+
+inline string Basename(const string& path) {
+ string::size_type last_slash = path.rfind('/');
+ if (last_slash != string::npos) {
+ return path.substr(last_slash + 1);
+ }
+ return path;
+}
+
+inline string CanonicalizeFilePath(const string& path) {
+ string result = path;
+
+#ifdef _MSC_VER
+ // canonicalise directory separators (forward slashes considered canonical)
+ for (size_t i = 0; i < result.size(); ++i) {
+ if (result[i] == '\\')
+ result[i] = '/';
+ }
+#endif
-// Returns true if the given file is third-party. Google-authored
-// code living in third_party/ is not considered third-party.
-bool IsThirdPartyFile(string quoted_path);
+ // We may also want to collapse ../ here.
+
+ return result;
+}
+
+// Strips uninteresting suffixes from the file name.
+inline string GetCanonicalName(string file_path) {
+ // Get rid of any <> and "" in case file_path is really an #include line.
+ StripLeft(&file_path, "\"") || StripLeft(&file_path, "<");
+ StripRight(&file_path, "\"") || StripRight(&file_path, ">");
+
+ file_path = CanonicalizeFilePath(file_path);
+
+ StripRight(&file_path, ".h")
+ || StripRight(&file_path, ".hpp")
+ || StripRight(&file_path, ".hxx")
+ || StripRight(&file_path, ".hh")
+ || StripRight(&file_path, ".inl")
+ || StripRight(&file_path, ".cxx")
+ || StripRight(&file_path, ".cpp")
+ || StripRight(&file_path, ".cc")
+ || StripRight(&file_path, ".c");
+ StripRight(&file_path, "_unittest")
+ || StripRight(&file_path, "_regtest")
+ || StripRight(&file_path, "_test")
+ || StripLeft(&file_path, "test_headercompile_");
+ StripRight(&file_path, "-inl");
+ // .h files in /public/ match .cc files in /internal/
+ const string::size_type internal_pos = file_path.find("/internal/");
+ if (internal_pos != string::npos)
+ file_path = (file_path.substr(0, internal_pos) + "/public/" +
+ file_path.substr(internal_pos + strlen("/internal/")));
+
+ // .h files in /include/ match .cc files in /src/
+ const string::size_type include_pos = file_path.find("/include/");
+ if (include_pos != string::npos)
+ file_path = (file_path.substr(0, include_pos) + "/src/" +
+ file_path.substr(include_pos + strlen("/include/")));
+ return file_path;
+}
+
+inline string NormalizeFilePath(const string& path) {
+ string result = CanonicalizeFilePath(path);
+ while (StripLeft(&result, "./")) {
+ }
+ return result;
+}
} // namespace include_what_you_use
diff --git a/iwyu_preprocessor.cc b/iwyu_preprocessor.cc
index 9745362..a0ed157 100644
--- a/iwyu_preprocessor.cc
+++ b/iwyu_preprocessor.cc
@@ -11,7 +11,6 @@
#include "iwyu_preprocessor.h"
#include <stddef.h> // for size_t
-#include <string.h>
#include <string> // for string, basic_string, etc
#include <utility> // for pair, make_pair
@@ -24,7 +23,6 @@
#include "iwyu_path_util.h"
#include "iwyu_stl_util.h"
#include "iwyu_string_util.h"
-#include "iwyu_verrs.h"
#include "port.h" // for CHECK_
// TODO(wan): remove this once the IWYU bug is fixed.
// IWYU pragma: no_include "foo/bar/baz.h"
diff --git a/iwyu_verrs.cc b/iwyu_verrs.cc
deleted file mode 100644
index 8995f3a..0000000
--- a/iwyu_verrs.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-//===--- iwyu_verrs.h - debug output 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_verrs.h"
-
-#include "iwyu_globals.h"
-#include "iwyu_location_util.h"
-#include "iwyu_path_util.h"
-
-namespace include_what_you_use {
-
-using clang::FileEntry;
-
-namespace {
-int verbose_level = 1;
-} // namespace
-
-void SetVerboseLevel(int level) {
- verbose_level = level;
-}
-
-int GetVerboseLevel() {
- return verbose_level;
-}
-
-bool ShouldPrintSymbolFromFile(const FileEntry* file) {
- if (GetVerboseLevel() < 5) {
- return false;
- } else if (GetVerboseLevel() < 10) {
- return ShouldReportIWYUViolationsFor(file);
- } else if (GetVerboseLevel() < 11) {
- return !IsSystemIncludeFile(GetFilePath(file));
- } else {
- return true;
- }
-}
-
-} // namespace include_what_you_use
diff --git a/iwyu_verrs.h b/iwyu_verrs.h
deleted file mode 100644
index b816d40..0000000
--- a/iwyu_verrs.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//===--- iwyu_verrs.h - debug output 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.
-//
-//===----------------------------------------------------------------------===//
-
-// This module controls logging and verbosity levels for include-what-you-use.
-
-#ifndef DEVTOOLS_MAINTENANCE_INCLUDE_WHAT_YOU_USE_IWYU_VERRS_H_
-#define DEVTOOLS_MAINTENANCE_INCLUDE_WHAT_YOU_USE_IWYU_VERRS_H_
-
-#include "llvm/Support/raw_ostream.h"
-
-namespace clang {
-class FileEntry;
-}
-
-namespace include_what_you_use {
-
-void SetVerboseLevel(int level);
-int GetVerboseLevel();
-
-// Returns true if we should print a message at the given verbosity level.
-inline bool ShouldPrint(int verbose_level) {
- return verbose_level <= GetVerboseLevel();
-}
-
-// Returns true if we should print information about a symbol in the
-// given file, at the current verbosity level. For instance, at most
-// normal verbosities, we don't print information about symbols in
-// system header files.
-bool ShouldPrintSymbolFromFile(const clang::FileEntry* file);
-
-// VERRS(n) << blah;
-// prints blah to errs() if the verbose level is >= n.
-#define VERRS(verbose_level) \
- if (!::include_what_you_use::ShouldPrint( \
- verbose_level)) ; else ::llvm::errs()
-
-} // namespace include_what_you_use
-
-#endif // DEVTOOLS_MAINTENANCE_INCLUDE_WHAT_YOU_USE_IWYU_VERRS_H_
diff --git a/more_tests/iwyu_output_test.cc b/more_tests/iwyu_output_test.cc
index 434e9d0..a41a822 100644
--- a/more_tests/iwyu_output_test.cc
+++ b/more_tests/iwyu_output_test.cc
@@ -11,15 +11,14 @@
#include "iwyu_output.h"
-#include <stddef.h>
#include <set>
#include "iwyu_ast_util.h"
#include "iwyu_globals.h"
-#include "iwyu_verrs.h"
#include "testing/base/public/gunit.h"
#undef ATTRIBUTE_UNUSED
+#include "clang/AST/Decl.h"
#include "clang/Basic/SourceLocation.h"
using clang::NamedDecl;
@@ -233,7 +232,7 @@ TEST(CalculateDesiredIncludesAndForwardDeclaresTest, Works) {
// between tests to prevent leaking side effects.
class VerboseTest : public ::testing::Test {
protected:
- VerboseTest() : old_verbose_level_(GetVerboseLevel()) {
+ VerboseTest() : old_verbose_level_(GlobalFlags().verbose) {
// 2 is the default verbose level for tests that don't care much
// about the level.
SetVerboseLevel(2);
@@ -243,6 +242,10 @@ class VerboseTest : public ::testing::Test {
SetVerboseLevel(old_verbose_level_);
}
+ void SetVerboseLevel(int level) {
+ MutableGlobalFlagsForTesting()->verbose = level;
+ }
+
private:
const int old_verbose_level_;
};
diff --git a/tests/badinc.cc b/tests/badinc.cc
index 6a7e268..ed28309 100644
--- a/tests/badinc.cc
+++ b/tests/badinc.cc
@@ -131,6 +131,8 @@ int i1_macro_symbol_with_value_and_value2_var2;
#if __LINE__ || __STDC__ || defined(__cplusplus)
#endif
+extern "C" std::string Flag3Value() { return 0; }
+
// Using declarations and statements.
// TODO(csilvers): I don't see a consistent way to say whether
// "i1_ns2" is an iwyu violation or not, since namespaces can be
@@ -264,7 +266,6 @@ class MultipleInheritanceSubclass : public I2_ThisClassIsOnlySubclassed,
// IWYU: I2_Class is...*badinc-i2.h
virtual I2_Class {
public:
- // IWYU: I2_Class is...*badinc-i2.h
// IWYU: I2_Struct is...*badinc-i2.h
// IWYU: I2_MACRO is...*badinc-i2.h
MultipleInheritanceSubclass() : I2_Class(I2_Struct().a + I2_MACRO) { }
diff --git a/tests/badinc.h b/tests/badinc.h
index 22700ff..5a13bee 100644
--- a/tests/badinc.h
+++ b/tests/badinc.h
@@ -130,6 +130,8 @@ class H_Class {
case I21: return 21;
// IWYU: I22 is...*badinc-i2.h
case I22: return 22;
+ // IWYU: I23 is...*badinc-i2.h
+ case I23: return 23;
default: return errno;
}
}
@@ -404,7 +406,7 @@ The full include-list for tests/badinc.h:
#include <vector> // for vector
#include "tests/badinc-d3.h" // for D3_Enum, D3_Enum::D31
#include "tests/badinc-i2-inl.h" // for I2_Class::I2_Class, I2_Class::InlFileFn, I2_Class::InlFileStaticFn, I2_Class::InlFileTemplateFn, I2_Class::~I2_Class, I2_TemplateClass::I2_TemplateClass<FOO>, I2_TemplateClass::InlFileTemplateClassFn, I2_TemplateClass::~I2_TemplateClass<FOO>
-#include "tests/badinc-i2.h" // for I2_Class, I2_Enum, I2_Enum::I21, I2_Enum::I22, I2_EnumForTypedefs, I2_MACRO, I2_Struct, I2_TemplateClass, I2_Typedef, I2_TypedefOnly_Class (ptr only), TemplateForHClassTplFn (ptr only)
+#include "tests/badinc-i2.h" // for I2_Class, I2_Enum, I2_Enum::I21, I2_Enum::I22, I2_Enum::I23, I2_EnumForTypedefs, I2_MACRO, I2_Struct, I2_TemplateClass, I2_Typedef, I2_TypedefOnly_Class (ptr only), TemplateForHClassTplFn (ptr only)
class Cc_Class; // lines XX-XX
// TODO(csilvers): this should change to struct Cc_Struct.
class Cc_Struct; // lines XX-XX
diff --git a/tests/fwd_decl_of_nested_class_defined_later.cc b/tests/fwd_decl_of_nested_class_defined_later.cc
deleted file mode 100644
index 69159fc..0000000
--- a/tests/fwd_decl_of_nested_class_defined_later.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-//===--- fwd_decl_of_nested_class_defined_later.cc - 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.
-//
-//===----------------------------------------------------------------------===//
-// This tests a particular situation which until recently IWYU did not
-// handle correctly. In certain cases, it would have unnecessarily recommended
-// a forward declaration *outside* of a class definition which really
-// belonged inside the class definition.
-
-#include <utility>
-
-class Foo {
- private:
- int Bar() {
- // The bug was that in the AST tree that IWYU generates, a
- // CXXMethodDecl node representing the pair destructor declaration
- // intervened in the chain from the node corresponding to the use
- // of Baz up to the CXXMethodDecl node for Bar. This caused
- // IsNodeInsideCXXMethodBody to return false for the node
- // corresponding to the use of Baz.
- // The fix was to not stop at the destructor declaration when
- // walking up the tree, since the context was not the body of the
- // destructor.
- return std::make_pair(Baz(), 0).second;
- }
-
- struct Baz {
- int value_;
- };
-};
-
-/**** IWYU_SUMMARY
-
-(tests/fwd_decl_of_nested_class_defined_later.cc has correct #includes/fwd-decls)
-
-***** IWYU_SUMMARY */
diff --git a/tests/integer_template_arg.cc b/tests/integer_template_arg.cc
deleted file mode 100644
index c11db7f..0000000
--- a/tests/integer_template_arg.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-//===--- integer_template_arg.cc - 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.
-//
-//===----------------------------------------------------------------------===//
-
-// This is a test to make sure a Clang crashing bug doesn't regress.
-
-template <int Arg> class Base {};
-class Derived : public Base<1> {};
-
-/**** IWYU_SUMMARY
-
-(tests/integer_template_arg.cc has correct #includes/fwd-decls)
-
-***** IWYU_SUMMARY */