2011-02-04 22:28:15 +00:00
|
|
|
//===--- iwyu_output.h - output-emitting code 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 file contains routines to deal with all output emitted by
|
|
|
|
// 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,
|
2011-12-01 02:30:18 +00:00
|
|
|
// etc.
|
2011-02-04 22:28:15 +00:00
|
|
|
|
2016-05-22 09:06:36 +01:00
|
|
|
#ifndef INCLUDE_WHAT_YOU_USE_IWYU_OUTPUT_H_
|
|
|
|
#define INCLUDE_WHAT_YOU_USE_IWYU_OUTPUT_H_
|
2011-02-04 22:28:15 +00:00
|
|
|
|
2011-05-04 19:30:53 +01:00
|
|
|
#include <map> // for map
|
|
|
|
#include <set> // for set
|
|
|
|
#include <string> // for string, operator<
|
|
|
|
#include <vector> // for vector
|
2011-02-04 22:28:15 +00:00
|
|
|
|
2019-12-26 12:18:47 +00:00
|
|
|
#include "iwyu_port.h" // for CHECK_
|
2011-02-04 22:28:15 +00:00
|
|
|
#include "iwyu_stl_util.h"
|
2018-02-25 09:03:06 +00:00
|
|
|
#include "iwyu_use_flags.h"
|
2011-02-04 22:28:15 +00:00
|
|
|
#include "clang/AST/Decl.h"
|
2011-05-04 19:29:59 +01:00
|
|
|
#include "clang/Basic/SourceLocation.h"
|
2011-02-04 22:28:15 +00:00
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
class FileEntry;
|
2015-10-04 20:02:36 +01:00
|
|
|
class UsingDecl;
|
2016-08-15 21:07:27 +01:00
|
|
|
} // namespace clang
|
2011-02-04 22:28:15 +00:00
|
|
|
|
|
|
|
namespace include_what_you_use {
|
|
|
|
|
|
|
|
using std::map;
|
|
|
|
using std::set;
|
|
|
|
using std::string;
|
|
|
|
using std::vector;
|
|
|
|
|
2011-04-12 05:56:17 +01:00
|
|
|
class IwyuPreprocessorInfo;
|
2011-02-04 22:28:15 +00:00
|
|
|
|
|
|
|
// This data structure holds information about a single use. Not all
|
|
|
|
// fields will be filled for all uses.
|
|
|
|
class OneUse {
|
|
|
|
public:
|
|
|
|
enum UseKind { kFullUse, kForwardDeclareUse };
|
|
|
|
|
2011-03-04 00:26:01 +00:00
|
|
|
OneUse(const clang::NamedDecl* decl,
|
|
|
|
clang::SourceLocation use_loc,
|
2018-10-25 07:42:17 +01:00
|
|
|
clang::SourceLocation decl_loc,
|
2011-03-04 00:26:01 +00:00
|
|
|
UseKind use_kind,
|
2018-02-25 09:03:06 +00:00
|
|
|
UseFlags flags,
|
2011-05-04 19:21:22 +01:00
|
|
|
const char* comment);
|
2014-04-24 17:08:25 +01:00
|
|
|
// Both dfn_file and dfn_filepath are specified to allow to create OneUse
|
|
|
|
// with dfn_filepath and without dfn_file. For example, in
|
|
|
|
// IwyuBaseAstVisitor::VisitCXXNewExpr we make a guess that placement
|
|
|
|
// operator new is called (which is defined in <new>), but we don't have
|
|
|
|
// <new> FileEntry.
|
2011-03-04 00:26:01 +00:00
|
|
|
OneUse(const string& symbol_name,
|
2014-04-24 17:08:25 +01:00
|
|
|
const clang::FileEntry* dfn_file,
|
2011-03-04 00:26:01 +00:00
|
|
|
const string& dfn_filepath,
|
2011-02-04 22:28:15 +00:00
|
|
|
clang::SourceLocation use_loc);
|
|
|
|
|
2023-01-03 21:55:12 +00:00
|
|
|
const string& symbol_name() const {
|
|
|
|
return symbol_name_;
|
|
|
|
}
|
|
|
|
const string& short_symbol_name() const {
|
|
|
|
return short_symbol_name_;
|
|
|
|
}
|
|
|
|
const clang::NamedDecl* decl() const {
|
|
|
|
return decl_;
|
|
|
|
}
|
|
|
|
const clang::FileEntry* decl_file() const {
|
|
|
|
return decl_file_;
|
|
|
|
}
|
|
|
|
const string& decl_filepath() const {
|
|
|
|
return decl_filepath_;
|
|
|
|
}
|
|
|
|
clang::SourceLocation use_loc() const {
|
|
|
|
return use_loc_;
|
|
|
|
}
|
|
|
|
clang::SourceLocation decl_loc() const {
|
|
|
|
return decl_loc_;
|
|
|
|
}
|
|
|
|
bool is_full_use() const {
|
|
|
|
return use_kind_ == kFullUse;
|
|
|
|
}
|
|
|
|
UseFlags flags() const {
|
|
|
|
return use_flags_;
|
|
|
|
}
|
|
|
|
const string& comment() const {
|
|
|
|
return comment_;
|
|
|
|
}
|
|
|
|
bool ignore_use() const {
|
|
|
|
return ignore_use_;
|
|
|
|
}
|
|
|
|
bool is_iwyu_violation() const {
|
|
|
|
return is_iwyu_violation_;
|
|
|
|
}
|
|
|
|
bool has_suggested_header() const {
|
|
|
|
return !suggested_header_.empty();
|
|
|
|
}
|
2016-08-15 21:04:47 +01:00
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
const string& suggested_header() const {
|
2011-03-04 00:29:56 +00:00
|
|
|
CHECK_(has_suggested_header() && "Must assign suggested_header first");
|
|
|
|
CHECK_(!ignore_use() && "Ignored uses have no suggested header");
|
2011-02-04 22:28:15 +00:00
|
|
|
return suggested_header_;
|
|
|
|
}
|
|
|
|
|
2014-04-24 17:08:25 +01:00
|
|
|
void reset_decl(const clang::NamedDecl* decl);
|
2011-02-04 22:28:15 +00:00
|
|
|
void set_full_use() { use_kind_ = kFullUse; }
|
2011-03-04 00:30:28 +00:00
|
|
|
void set_forward_declare_use() { use_kind_ = kForwardDeclareUse; }
|
2011-02-04 22:28:15 +00:00
|
|
|
void set_ignore_use() { ignore_use_ = true; }
|
|
|
|
void set_is_iwyu_violation() { is_iwyu_violation_ = true; }
|
|
|
|
void set_suggested_header(const string& fh) { suggested_header_ = fh; }
|
|
|
|
|
|
|
|
string PrintableUseLoc() const;
|
|
|
|
const vector<string>& public_headers(); // not const because we fill lazily
|
|
|
|
bool PublicHeadersContain(const string& elt);
|
|
|
|
bool NeedsSuggestedHeader() const; // not true for fwd-declare uses, e.g.
|
|
|
|
int UseLinenum() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
void SetPublicHeaders(); // sets based on decl_filepath_
|
|
|
|
|
|
|
|
string symbol_name_; // the symbol being used
|
2011-02-19 02:32:52 +00:00
|
|
|
string short_symbol_name_; // 'short' form of the symbol being used
|
2011-02-04 22:28:15 +00:00
|
|
|
const clang::NamedDecl* decl_; // decl of the symbol, if we know it
|
2017-10-01 13:35:16 +01:00
|
|
|
clang::SourceLocation decl_loc_; // where the decl is attributed to live
|
2014-04-24 17:08:25 +01:00
|
|
|
const clang::FileEntry* decl_file_; // file entry where the symbol lives
|
2011-02-04 22:28:15 +00:00
|
|
|
string decl_filepath_; // filepath where the symbol lives
|
|
|
|
clang::SourceLocation use_loc_; // where the symbol is used from
|
|
|
|
UseKind use_kind_; // kFullUse or kForwardDeclareUse
|
2018-02-25 09:03:06 +00:00
|
|
|
UseFlags use_flags_; // flags describing features of the use
|
2011-05-04 19:21:22 +01:00
|
|
|
string comment_; // If not empty, append to clang warning msg
|
2011-02-04 22:28:15 +00:00
|
|
|
vector<string> public_headers_; // header to #include if dfn hdr is private
|
|
|
|
string suggested_header_; // header that allows us to satisfy use
|
|
|
|
bool ignore_use_; // set to true if use is discarded
|
|
|
|
bool is_iwyu_violation_; // set to false when we figure out it's not
|
|
|
|
};
|
|
|
|
|
|
|
|
class OneIncludeOrForwardDeclareLine {
|
|
|
|
public:
|
|
|
|
explicit OneIncludeOrForwardDeclareLine(const clang::NamedDecl* fwd_decl);
|
2013-12-15 12:33:18 +00:00
|
|
|
OneIncludeOrForwardDeclareLine(const clang::FileEntry* included_file,
|
|
|
|
const string& quoted_include, int linenum);
|
2011-02-04 22:28:15 +00:00
|
|
|
|
2023-01-03 21:55:12 +00:00
|
|
|
const string& line() const {
|
|
|
|
return line_;
|
|
|
|
}
|
2011-02-04 22:28:15 +00:00
|
|
|
bool IsIncludeLine() const; // vs forward-declare line
|
|
|
|
string LineNumberString() const; // <startline>-<endline>
|
2023-01-03 21:55:12 +00:00
|
|
|
bool is_desired() const {
|
|
|
|
return is_desired_;
|
|
|
|
}
|
|
|
|
bool is_present() const {
|
|
|
|
return is_present_;
|
|
|
|
}
|
|
|
|
const map<string, int>& symbol_counts() const {
|
|
|
|
return symbol_counts_;
|
|
|
|
}
|
2016-08-15 21:04:47 +01:00
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
string quoted_include() const {
|
2011-03-04 00:29:56 +00:00
|
|
|
CHECK_(IsIncludeLine() && "Must call quoted_include() on include lines");
|
|
|
|
CHECK_(!fwd_decl_ && "quoted_include and fwd_decl are mutually exclusive");
|
2011-02-04 22:28:15 +00:00
|
|
|
return quoted_include_;
|
|
|
|
}
|
2016-08-15 21:04:47 +01:00
|
|
|
|
2013-12-15 12:33:18 +00:00
|
|
|
const clang::FileEntry* included_file() const {
|
|
|
|
CHECK_(IsIncludeLine() && "Must call included_file() on include lines");
|
|
|
|
CHECK_(!fwd_decl_ && "included_file and fwd_decl are mutually exclusive");
|
|
|
|
return included_file_;
|
|
|
|
}
|
2016-08-15 21:04:47 +01:00
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
const clang::NamedDecl* fwd_decl() const {
|
2011-03-04 00:29:56 +00:00
|
|
|
CHECK_(!IsIncludeLine() && "Must call fwd_decl() on forward-declare lines");
|
2013-12-15 12:33:18 +00:00
|
|
|
CHECK_(quoted_include_.empty() && !included_file_ &&
|
|
|
|
"quoted_include and fwd_decl don't mix");
|
2011-02-04 22:28:15 +00:00
|
|
|
return fwd_decl_;
|
|
|
|
}
|
|
|
|
|
2014-08-25 20:37:29 +01:00
|
|
|
bool matches(const string& quoted_include) const {
|
|
|
|
return IsIncludeLine() && (quoted_include_ == quoted_include);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool matches(const clang::NamedDecl* decl) const {
|
|
|
|
return !IsIncludeLine() && (fwd_decl_ == decl);
|
|
|
|
}
|
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
void set_present() { is_present_ = true; }
|
|
|
|
void set_desired() { is_desired_ = true; }
|
|
|
|
void clear_desired() { is_desired_ = false; }
|
|
|
|
void clear_line_numbers() { start_linenum_ = end_linenum_ = -1; }
|
|
|
|
// Another symbol we're using that's defined in this file.
|
|
|
|
void AddSymbolUse(const string& symbol_name);
|
|
|
|
bool HasSymbolUse(const string& symbol_name) const;
|
|
|
|
|
2011-09-23 18:19:07 +01:00
|
|
|
bool LineNumbersMatch(const OneIncludeOrForwardDeclareLine& that) const {
|
|
|
|
return (this->start_linenum_ == that.start_linenum_ &&
|
|
|
|
this->end_linenum_ == that.end_linenum_);
|
|
|
|
}
|
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
private:
|
|
|
|
string line_; // '#include XXX' or 'class YYY;'
|
|
|
|
int start_linenum_;
|
|
|
|
int end_linenum_;
|
|
|
|
bool is_desired_; // IWYU will recommend this line
|
|
|
|
bool is_present_; // line was present before the IWYU run
|
|
|
|
map<string, int> symbol_counts_; // how many times we referenced each symbol
|
2013-12-15 12:33:18 +00:00
|
|
|
// Only either two following members are set for includes
|
|
|
|
string quoted_include_; // quoted file name we're including
|
|
|
|
const clang::FileEntry* included_file_; // the file we're including
|
|
|
|
// ...or this member is set for the fwd-decl we're emitting.
|
|
|
|
const clang::NamedDecl* fwd_decl_;
|
2011-02-04 22:28:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// This class holds IWYU information about a single file (FileEntry)
|
|
|
|
// -- referred to, in the comments below, as "this file." The keys to
|
|
|
|
// most of these methods are all quoted header paths, which are the
|
|
|
|
// include names as they would occur in a source file, including <> or
|
|
|
|
// "". For instance, '<string>' or '"ads/test.h"'.
|
|
|
|
// TODO(csilvers): add unitests for this class.
|
|
|
|
class IwyuFileInfo {
|
|
|
|
public:
|
|
|
|
// TODO(csilvers): also take iwyufileinfos for 'associated' files (.h's).
|
|
|
|
// And a source-manager.
|
2011-04-12 05:56:17 +01:00
|
|
|
IwyuFileInfo(const clang::FileEntry* this_file,
|
2011-10-07 22:51:59 +01:00
|
|
|
const IwyuPreprocessorInfo* preprocessor_info,
|
|
|
|
const string& quoted_include_name);
|
2011-02-04 22:28:15 +00:00
|
|
|
|
2023-01-03 21:55:12 +00:00
|
|
|
bool is_prefix_header() const {
|
|
|
|
return is_prefix_header_;
|
|
|
|
}
|
2013-12-15 12:33:18 +00:00
|
|
|
void set_prefix_header() { is_prefix_header_ = true; }
|
|
|
|
|
2023-01-03 21:55:12 +00:00
|
|
|
bool is_pch_in_code() const {
|
|
|
|
return is_pch_in_code_;
|
|
|
|
}
|
2014-04-27 21:35:44 +01:00
|
|
|
void set_pch_in_code() { is_pch_in_code_ = true; }
|
|
|
|
|
2013-12-22 22:21:06 +00:00
|
|
|
// An 'associated' header is a header that this file #includes
|
2011-02-04 22:28:15 +00:00
|
|
|
// (possibly indirectly) that we should treat as being logically
|
|
|
|
// part of this file. In particular, when computing the direct
|
|
|
|
// includes of this file, we also include the direct includes of all
|
2013-12-22 22:21:06 +00:00
|
|
|
// associated headers. Examples: vector has bits/stl_vector.h as an
|
|
|
|
// associated header; foo.cc has foo.h and foo-inl.h as associated
|
|
|
|
// headers.
|
|
|
|
void AddAssociatedHeader(const IwyuFileInfo* other);
|
2011-02-04 22:28:15 +00:00
|
|
|
|
2015-10-04 20:02:36 +01:00
|
|
|
// Use these to register an iwyu declaration: either an #include,
|
|
|
|
// a forward-declaration or a using-declaration.
|
2011-02-04 22:28:15 +00:00
|
|
|
|
|
|
|
void AddInclude(const clang::FileEntry* includee,
|
|
|
|
const string& quoted_includee, int linenumber);
|
My check for whether a class was nested or not was entirely
broken -- it left out the common case that the class is being
used inside the outer class without a qualifier. A new test
shows where we would do the wrong thing in that case.
Fixing this brought up more problems, that could all be traced
to the fact we 'cheat' and create fake uses of
forward-declares when we want to be sure not to delete them.
I get rid of the cheating and just say, when we see a
forward-decalare, whether we want to definitely-keep it or
not. That yields much nicer code (I think).
I also don't know what I was thinking when I said "if there
are multiple fwd-decls in a class, just keep one arbitrarily."
Obviously we should keep the first one; the arbitrary one may
come too late. These changes brought that bug to light too
(an existing test started failing), but now it's squashed.
Finally, I resolved a TODO, getting rid of
IsDeclNodeInsideFriend. I had known this was possible for a
while, I just had never gotten around to actually doing it.
Doesn't affect any tests.
R=dsturtevant
DELTA=141 (75 added, 26 deleted, 40 changed)
Revision created by MOE tool push_codebase.
MOE_MIGRATION=1453
2011-04-14 05:48:03 +01:00
|
|
|
// definitely_keep_fwd_decl tells us that we should never suggest
|
|
|
|
// the fwd-decl be removed, even if we don't see any uses of it.
|
2016-08-15 21:24:39 +01:00
|
|
|
void AddForwardDeclare(const clang::NamedDecl* fwd_decl,
|
My check for whether a class was nested or not was entirely
broken -- it left out the common case that the class is being
used inside the outer class without a qualifier. A new test
shows where we would do the wrong thing in that case.
Fixing this brought up more problems, that could all be traced
to the fact we 'cheat' and create fake uses of
forward-declares when we want to be sure not to delete them.
I get rid of the cheating and just say, when we see a
forward-decalare, whether we want to definitely-keep it or
not. That yields much nicer code (I think).
I also don't know what I was thinking when I said "if there
are multiple fwd-decls in a class, just keep one arbitrarily."
Obviously we should keep the first one; the arbitrary one may
come too late. These changes brought that bug to light too
(an existing test started failing), but now it's squashed.
Finally, I resolved a TODO, getting rid of
IsDeclNodeInsideFriend. I had known this was possible for a
while, I just had never gotten around to actually doing it.
Doesn't affect any tests.
R=dsturtevant
DELTA=141 (75 added, 26 deleted, 40 changed)
Revision created by MOE tool push_codebase.
MOE_MIGRATION=1453
2011-04-14 05:48:03 +01:00
|
|
|
bool definitely_keep_fwd_decl);
|
2011-02-04 22:28:15 +00:00
|
|
|
|
2015-10-04 20:02:36 +01:00
|
|
|
void AddUsingDecl(const clang::UsingDecl* using_decl);
|
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
// Use these to register an iwyu 'use'. It's preferable to indicate
|
|
|
|
// an explicit type or decl being used, but if that's not available,
|
|
|
|
// a symbol-name is acceptable as well. There are two forms of each
|
|
|
|
// registration routine, one for when we need the full symbol info
|
|
|
|
// (via an #include), and one when forward-declaring is enough.
|
|
|
|
|
|
|
|
void ReportFullSymbolUse(clang::SourceLocation use_loc,
|
2011-03-04 00:26:01 +00:00
|
|
|
const clang::NamedDecl* decl,
|
2018-02-25 09:03:06 +00:00
|
|
|
UseFlags flags, const char* comment);
|
2014-04-24 17:08:25 +01:00
|
|
|
// This is used for symbols with a made up dfn_filepath. Currently it's used
|
|
|
|
// only for placement operator new in templates (see
|
|
|
|
// IwyuBaseAstVisitor::VisitCXXNewExpr).
|
2011-02-04 22:28:15 +00:00
|
|
|
void ReportFullSymbolUse(clang::SourceLocation use_loc,
|
2021-05-07 17:05:32 +01:00
|
|
|
const clang::FileEntry* dfn_file,
|
2011-02-04 22:28:15 +00:00
|
|
|
const string& symbol);
|
2011-08-01 21:57:19 +01:00
|
|
|
// TODO(dsturtevant): Can we determine in_cxx_method_body? Do we care?
|
2011-02-04 22:28:15 +00:00
|
|
|
|
2016-08-15 01:28:46 +01:00
|
|
|
// Called when using a macro in this file.
|
2014-04-24 17:08:25 +01:00
|
|
|
void ReportMacroUse(clang::SourceLocation use_loc,
|
|
|
|
clang::SourceLocation dfn_loc,
|
|
|
|
const string& symbol);
|
|
|
|
|
2016-08-15 01:28:46 +01:00
|
|
|
// Called when somebody uses a macro defined in this file.
|
|
|
|
void ReportDefinedMacroUse(const clang::FileEntry* used_in);
|
|
|
|
|
2011-05-04 19:21:22 +01:00
|
|
|
// We only allow forward-declaring of decls, not arbitrary symbols.
|
2011-02-04 22:28:15 +00:00
|
|
|
void ReportForwardDeclareUse(clang::SourceLocation use_loc,
|
2011-03-04 00:26:01 +00:00
|
|
|
const clang::NamedDecl* decl,
|
2018-02-25 09:03:06 +00:00
|
|
|
UseFlags flags, const char* comment);
|
2011-02-04 22:28:15 +00:00
|
|
|
|
2015-10-04 20:02:36 +01:00
|
|
|
// Called whenever a NamedDecl is accessed through a UsingDecl.
|
2020-03-20 01:02:40 +00:00
|
|
|
// ie: using std::swap; swap(a, b);
|
2015-10-04 20:02:36 +01:00
|
|
|
void ReportUsingDeclUse(clang::SourceLocation use_loc,
|
|
|
|
const clang::UsingDecl* using_decl,
|
2018-02-25 09:03:06 +00:00
|
|
|
UseFlags flags, const char* comment);
|
2015-10-04 20:02:36 +01:00
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
// This is used when we see a // NOLINT comment, for instance. It says
|
|
|
|
// '#include this header file as-is, without any public-header mapping.'
|
|
|
|
// Input is the include-line as desired: '<string.h>' or '"ads/foo.h"'.
|
2014-04-24 17:08:25 +01:00
|
|
|
void ReportIncludeFileUse(const clang::FileEntry* included_file,
|
|
|
|
const string& quoted_include);
|
2011-02-04 22:28:15 +00:00
|
|
|
|
2016-08-15 01:28:46 +01:00
|
|
|
// This is used when we see a file we want to keep not due to symbol-use
|
|
|
|
// reasons. For example, it can be #included with an "IWYU pragma: keep"
|
|
|
|
// comment or it can be an x-macro.
|
|
|
|
void ReportKnownDesiredFile(const clang::FileEntry* included_file);
|
2014-10-05 20:38:22 +01:00
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
// This is used only in iwyu_preprocessor.cc. TODO(csilvers): revamp?
|
|
|
|
const set<const clang::FileEntry*>& direct_includes_as_fileentries() const {
|
|
|
|
return direct_includes_as_fileentries_;
|
|
|
|
}
|
|
|
|
|
2016-08-15 01:28:46 +01:00
|
|
|
// Called when all macros in the file are processed.
|
|
|
|
void HandlePreprocessingDone();
|
|
|
|
|
2015-10-04 20:02:36 +01:00
|
|
|
// Resolve and pending analysis that needs to occur between AST traversal
|
|
|
|
// and CalculateAndReportIwyuViolations.
|
|
|
|
void ResolvePendingAnalysis();
|
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
// The meat of iwyu: compare the actual includes and forward-declares
|
|
|
|
// against the symbol uses, and report which uses are iwyu violations.
|
|
|
|
// Reports violations on errs(), and returns the number of violations.
|
2014-11-30 09:26:43 +00:00
|
|
|
size_t CalculateAndReportIwyuViolations();
|
2011-02-04 22:28:15 +00:00
|
|
|
|
|
|
|
private:
|
2023-01-03 21:55:12 +00:00
|
|
|
const set<string>& direct_includes() const {
|
|
|
|
return direct_includes_;
|
|
|
|
}
|
2016-08-15 21:04:47 +01:00
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
const set<string>& desired_includes() const {
|
2011-03-04 00:29:56 +00:00
|
|
|
CHECK_(desired_includes_have_been_calculated_ &&
|
2011-02-04 22:28:15 +00:00
|
|
|
"Must calculate desired includes before calling desired_includes()");
|
|
|
|
return desired_includes_;
|
|
|
|
}
|
2016-08-15 21:04:47 +01:00
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
set<string> AssociatedQuotedIncludes() const {
|
|
|
|
set<string> associated_quoted_includes;
|
2016-06-12 15:07:31 +01:00
|
|
|
for (const IwyuFileInfo* associated : associated_headers_)
|
|
|
|
associated_quoted_includes.insert(associated->quoted_file_);
|
2011-02-04 22:28:15 +00:00
|
|
|
return associated_quoted_includes;
|
|
|
|
}
|
|
|
|
|
2011-03-04 00:23:37 +00:00
|
|
|
set<const clang::FileEntry*> AssociatedFileEntries() const {
|
|
|
|
set<const clang::FileEntry*> associated_file_entries;
|
2016-06-12 15:07:31 +01:00
|
|
|
for (const IwyuFileInfo* associated : associated_headers_)
|
|
|
|
associated_file_entries.insert(associated->file_);
|
2011-03-04 00:23:37 +00:00
|
|
|
return associated_file_entries;
|
|
|
|
}
|
|
|
|
|
2013-11-07 14:09:22 +00:00
|
|
|
set<string> AssociatedDesiredIncludes() const {
|
|
|
|
set<string> associated_desired_includes;
|
2016-06-12 15:07:31 +01:00
|
|
|
for (const IwyuFileInfo* associated : associated_headers_)
|
|
|
|
InsertAllInto(associated->desired_includes(),
|
|
|
|
&associated_desired_includes);
|
2013-11-07 14:09:22 +00:00
|
|
|
return associated_desired_includes;
|
|
|
|
}
|
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
// Populates uses with full data, including is_iwyu_violation_.
|
|
|
|
void CalculateIwyuViolations(vector<OneUse>* uses);
|
|
|
|
// Uses uses to emit warning messages (at high enough verbosity).
|
|
|
|
// Returns the number of warning messages found.
|
|
|
|
int EmitWarningMessages(const vector<OneUse>& uses);
|
|
|
|
|
|
|
|
// The constructor arguments. file_ is 'this file'.
|
|
|
|
const clang::FileEntry* file_;
|
2011-04-12 05:56:17 +01:00
|
|
|
const IwyuPreprocessorInfo* preprocessor_info_;
|
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
string quoted_file_;
|
|
|
|
|
2013-12-15 12:33:18 +00:00
|
|
|
// Prefix header means included from command line via -include option.
|
|
|
|
bool is_prefix_header_;
|
|
|
|
|
2014-04-27 21:35:44 +01:00
|
|
|
// PCH in code refers to an #include directive that acts as a marker for
|
|
|
|
// precompiled header inclusion. This pattern can be used with GCC and is
|
|
|
|
// standard practice on MSVC, whereas Clang forces PCHs to be listed as prefix
|
|
|
|
// headers.
|
|
|
|
bool is_pch_in_code_;
|
|
|
|
|
2013-12-22 22:21:06 +00:00
|
|
|
// associated_headers_ are the files 'associated' with this file: if
|
|
|
|
// this file is foo.cc, associated_headers_ are the IwyuFileInfo's for
|
2011-02-04 22:28:15 +00:00
|
|
|
// foo.h and foo-inl.h, if present.
|
2013-12-22 22:21:06 +00:00
|
|
|
set<const IwyuFileInfo*> associated_headers_;
|
2011-02-04 22:28:15 +00:00
|
|
|
|
|
|
|
// Holds all the uses that are reported.
|
|
|
|
vector<OneUse> symbol_uses_;
|
|
|
|
|
|
|
|
// Holds all the lines (#include and fwd-declare) that are reported.
|
|
|
|
vector<OneIncludeOrForwardDeclareLine> lines_;
|
|
|
|
|
2015-10-04 20:02:36 +01:00
|
|
|
// Maps all the using-decls that are reported to a bool indicating whether
|
|
|
|
// or not a the using decl has been referenced in this file.
|
|
|
|
map<const clang::UsingDecl*, bool> using_decl_referenced_;
|
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
// We also hold the line information in a few other data structures,
|
|
|
|
// for ease of references.
|
|
|
|
set<string> direct_includes_; // key is the quoted include, eg '<set>'
|
|
|
|
set<const clang::FileEntry*> direct_includes_as_fileentries_;
|
|
|
|
set<const clang::NamedDecl*> direct_forward_declares_;
|
|
|
|
|
2016-08-15 01:28:46 +01:00
|
|
|
// Holds files forced to be kept. For example, files included with the
|
|
|
|
// "IWYU pragma: keep" comment and x-macros.
|
2014-10-05 20:38:22 +01:00
|
|
|
set<const clang::FileEntry*> kept_includes_;
|
|
|
|
|
2016-08-15 01:28:46 +01:00
|
|
|
// Holds files using macros defined in this file.
|
|
|
|
set<const clang::FileEntry*> macro_users_;
|
|
|
|
|
2011-02-04 22:28:15 +00:00
|
|
|
// What we will recommend the #includes to be.
|
|
|
|
set<string> desired_includes_;
|
|
|
|
bool desired_includes_have_been_calculated_;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Helpers for testing.
|
|
|
|
|
|
|
|
namespace internal {
|
|
|
|
|
|
|
|
class FakeNamedDecl : public clang::NamedDecl {
|
|
|
|
public:
|
|
|
|
FakeNamedDecl(const string& kind_name, const string& qual_name,
|
2011-02-19 02:32:52 +00:00
|
|
|
const string& decl_filepath, int decl_linenum);
|
2011-02-04 22:28:15 +00:00
|
|
|
|
2023-01-03 21:55:12 +00:00
|
|
|
string kind_name() const {
|
|
|
|
return kind_name_;
|
|
|
|
}
|
|
|
|
string qual_name() const {
|
|
|
|
return qual_name_;
|
|
|
|
}
|
|
|
|
string decl_filepath() const {
|
|
|
|
return decl_filepath_;
|
|
|
|
}
|
|
|
|
int decl_linenum() const {
|
|
|
|
return decl_linenum_;
|
|
|
|
}
|
2011-02-04 22:28:15 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
string kind_name_;
|
|
|
|
string qual_name_;
|
|
|
|
string decl_filepath_;
|
|
|
|
int decl_linenum_;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
|
|
|
|
} // namespace include_what_you_use
|
|
|
|
|
2016-05-22 09:06:36 +01:00
|
|
|
#endif // INCLUDE_WHAT_YOU_USE_IWYU_OUTPUT_H_
|