summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Grasman <kim.grasman@gmail.com>2018-02-25 10:03:06 +0100
committerKim Gräsman <kim.grasman@gmail.com>2018-03-09 20:37:52 +0100
commitaa2bc1f9e0b664065b5e1cbe45637fbd0f9e327e (patch)
treec533edc2f1684b277ecd397c584cc78d306075ed
parent314fc2d182a99386d073ebc44f7924a7d99cba43 (diff)
Replace in_cxx_method_body with an extensible use-flag
This makes it possible to pass more context information about a use from the detection phase to later IWYU analysis phases.
-rw-r--r--iwyu.cc10
-rw-r--r--iwyu_ast_util.cc9
-rw-r--r--iwyu_ast_util.h5
-rw-r--r--iwyu_output.cc20
-rw-r--r--iwyu_output.h13
-rw-r--r--iwyu_use_flags.h23
6 files changed, 59 insertions, 21 deletions
diff --git a/iwyu.cc b/iwyu.cc
index 6ed403b..f41dbc5 100644
--- a/iwyu.cc
+++ b/iwyu.cc
@@ -1400,7 +1400,7 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
preprocessor_info().FileInfoFor(macro_def_file);
file_info->ReportForwardDeclareUse(
spelling_loc, fwd_decl,
- IsNodeInsideCXXMethodBody(current_ast_node()), nullptr);
+ ComputeUseFlags(current_ast_node()), nullptr);
break;
}
}
@@ -1649,7 +1649,7 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
used_loc = GetCanonicalUseLocation(used_loc, target_decl);
const FileEntry* used_in = GetFileEntry(used_loc);
preprocessor_info().FileInfoFor(used_in)->ReportFullSymbolUse(
- used_loc, target_decl, IsNodeInsideCXXMethodBody(current_ast_node()),
+ used_loc, target_decl, ComputeUseFlags(current_ast_node()),
comment);
// Sometimes using a decl drags in a few other uses as well:
@@ -1668,7 +1668,7 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
= GetUsingDeclarationOf(used_decl,
GetDeclContext(current_ast_node()))) {
preprocessor_info().FileInfoFor(used_in)->ReportUsingDeclUse(
- used_loc, using_decl, IsNodeInsideCXXMethodBody(current_ast_node()),
+ used_loc, using_decl, ComputeUseFlags(current_ast_node()),
"(for using decl)");
}
@@ -1720,7 +1720,7 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
used_loc = GetCanonicalUseLocation(used_loc, target_decl);
const FileEntry* used_in = GetFileEntry(used_loc);
preprocessor_info().FileInfoFor(used_in)->ReportForwardDeclareUse(
- used_loc, target_decl, IsNodeInsideCXXMethodBody(current_ast_node()),
+ used_loc, target_decl, ComputeUseFlags(current_ast_node()),
comment);
// If we're a use that depends on a using declaration, make sure
@@ -1729,7 +1729,7 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
= GetUsingDeclarationOf(used_decl,
GetDeclContext(current_ast_node()))) {
preprocessor_info().FileInfoFor(used_in)->ReportUsingDeclUse(
- used_loc, using_decl, IsNodeInsideCXXMethodBody(current_ast_node()),
+ used_loc, using_decl, ComputeUseFlags(current_ast_node()),
"(for using decl)");
}
}
diff --git a/iwyu_ast_util.cc b/iwyu_ast_util.cc
index ea7919b..03e3dbf 100644
--- a/iwyu_ast_util.cc
+++ b/iwyu_ast_util.cc
@@ -262,6 +262,15 @@ bool IsNodeInsideCXXMethodBody(const ASTNode* ast_node) {
return false;
}
+UseFlags ComputeUseFlags(const ASTNode* ast_node) {
+ UseFlags flags = UF_None;
+
+ if (IsNodeInsideCXXMethodBody(ast_node))
+ flags |= UF_InCxxMethodBody;
+
+ return flags;
+}
+
bool IsNestedClassAsWritten(const ASTNode* ast_node) {
return (ast_node->IsA<RecordDecl>() &&
(ast_node->ParentIsA<CXXRecordDecl>() ||
diff --git a/iwyu_ast_util.h b/iwyu_ast_util.h
index dd3f5e0..847c68e 100644
--- a/iwyu_ast_util.h
+++ b/iwyu_ast_util.h
@@ -16,6 +16,7 @@
#include <set> // for set
#include <string> // for string
+#include "iwyu_use_flags.h"
#include "port.h" // for CHECK_
#include "llvm/Support/Casting.h"
#include "clang/AST/DeclBase.h"
@@ -386,6 +387,10 @@ bool IsQualifiedNameNode(const ASTNode* ast_node);
// implicitly), or the implicit (non-body) code of a destructor.
bool IsNodeInsideCXXMethodBody(const ASTNode* ast_node);
+// Return UseFlags for the current node.
+// These flags provide context around the use to help later IWYU analysis,
+UseFlags ComputeUseFlags(const ASTNode* ast_node);
+
// Return true if we're a nested class as written, that is, we're a
// class decl inside another class decl. The parent class may be
// templated, but we should not be. (We could extend the function to
diff --git a/iwyu_output.cc b/iwyu_output.cc
index 0c66010..cefb41f 100644
--- a/iwyu_output.cc
+++ b/iwyu_output.cc
@@ -237,7 +237,7 @@ string GetShortNameAsString(const clang::NamedDecl* named_decl) {
// Holds information about a single full or fwd-decl use of a symbol.
OneUse::OneUse(const NamedDecl* decl, SourceLocation use_loc,
- OneUse::UseKind use_kind, bool in_cxx_method_body,
+ OneUse::UseKind use_kind, UseFlags flags,
const char* comment)
: symbol_name_(internal::GetQualifiedNameAsString(decl)),
short_symbol_name_(internal::GetShortNameAsString(decl)),
@@ -247,7 +247,7 @@ OneUse::OneUse(const NamedDecl* decl, SourceLocation use_loc,
decl_filepath_(GetFilePath(decl_file_)),
use_loc_(use_loc),
use_kind_(use_kind), // full use or fwd-declare use
- in_cxx_method_body_(in_cxx_method_body),
+ use_flags_(flags),
comment_(comment ? comment : ""),
ignore_use_(false),
is_iwyu_violation_(false) {
@@ -263,7 +263,7 @@ OneUse::OneUse(const string& symbol_name, const FileEntry* dfn_file,
decl_filepath_(dfn_filepath),
use_loc_(use_loc),
use_kind_(kFullUse),
- in_cxx_method_body_(false),
+ use_flags_(UF_None),
ignore_use_(false),
is_iwyu_violation_(false) {
// Sometimes dfn_filepath is actually a fully quoted include. In
@@ -574,13 +574,13 @@ static void LogSymbolUse(const string& prefix, const OneUse& use) {
void IwyuFileInfo::ReportFullSymbolUse(SourceLocation use_loc,
const NamedDecl* decl,
- bool in_cxx_method_body,
+ UseFlags flags,
const char* comment) {
if (decl) {
// Since we need the full symbol, we need the decl's definition-site.
decl = GetDefinitionAsWritten(decl);
symbol_uses_.push_back(OneUse(decl, use_loc, OneUse::kFullUse,
- in_cxx_method_body, comment));
+ flags, comment));
LogSymbolUse("Marked full-info use of decl", symbol_uses_.back());
}
}
@@ -617,7 +617,7 @@ void IwyuFileInfo::ReportKnownDesiredFile(const FileEntry* included_file) {
void IwyuFileInfo::ReportForwardDeclareUse(SourceLocation use_loc,
const NamedDecl* decl,
- bool in_cxx_method_body,
+ UseFlags flags,
const char* comment) {
if (!decl)
return;
@@ -626,13 +626,13 @@ void IwyuFileInfo::ReportForwardDeclareUse(SourceLocation use_loc,
// happened here, replace the friend with a real fwd decl.
decl = GetNonfriendClassRedecl(decl);
symbol_uses_.push_back(OneUse(decl, use_loc, OneUse::kForwardDeclareUse,
- in_cxx_method_body, comment));
+ flags, comment));
LogSymbolUse("Marked fwd-decl use of decl", symbol_uses_.back());
}
void IwyuFileInfo::ReportUsingDeclUse(SourceLocation use_loc,
const UsingDecl* using_decl,
- bool in_cxx_method_body,
+ UseFlags flags,
const char* comment) {
// If accessing a symbol through a using decl in the same file that contains
// the using decl, we must mark the using decl as referenced. At the end of
@@ -648,7 +648,7 @@ void IwyuFileInfo::ReportUsingDeclUse(SourceLocation use_loc,
// When a symbol is accessed through a using decl, we must report
// that as a full use of the using decl because whatever file that
// using decl is in is now required.
- ReportFullSymbolUse(use_loc, using_decl, in_cxx_method_body, comment);
+ ReportFullSymbolUse(use_loc, using_decl, flags, comment);
}
// Given a collection of symbol-uses for symbols defined in various
@@ -1970,7 +1970,7 @@ void IwyuFileInfo::ResolvePendingAnalysis() {
if (using_decl->shadow_size() > 0) {
ReportForwardDeclareUse(using_decl->getUsingLoc(),
using_decl->shadow_begin()->getTargetDecl(),
- /* in_cxx_method_body */ false,
+ /* flags */ UF_None,
"(for un-referenced using)");
}
}
diff --git a/iwyu_output.h b/iwyu_output.h
index 190a0f6..f0d2db4 100644
--- a/iwyu_output.h
+++ b/iwyu_output.h
@@ -22,6 +22,7 @@
#include <vector> // for vector
#include "iwyu_stl_util.h"
+#include "iwyu_use_flags.h"
#include "port.h" // for CHECK_
#include "clang/AST/Decl.h"
#include "clang/Basic/SourceLocation.h"
@@ -50,7 +51,7 @@ class OneUse {
OneUse(const clang::NamedDecl* decl,
clang::SourceLocation use_loc,
UseKind use_kind,
- bool in_cxx_method_body,
+ UseFlags flags,
const char* comment);
// Both dfn_file and dfn_filepath are specified to allow to create OneUse
// with dfn_filepath and without dfn_file. For example, in
@@ -70,7 +71,7 @@ class OneUse {
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; }
- bool in_cxx_method_body() const { return in_cxx_method_body_; }
+ bool in_cxx_method_body() const { return (use_flags_ & UF_InCxxMethodBody); }
const string& comment() const { return comment_; }
bool ignore_use() const { return ignore_use_; }
bool is_iwyu_violation() const { return is_iwyu_violation_; }
@@ -106,7 +107,7 @@ class OneUse {
string decl_filepath_; // filepath where the symbol lives
clang::SourceLocation use_loc_; // where the symbol is used from
UseKind use_kind_; // kFullUse or kForwardDeclareUse
- bool in_cxx_method_body_; // true if use is inside a C++ method body
+ UseFlags use_flags_; // flags describing features of the use
string comment_; // If not empty, append to clang warning msg
vector<string> public_headers_; // header to #include if dfn hdr is private
string suggested_header_; // header that allows us to satisfy use
@@ -230,7 +231,7 @@ class IwyuFileInfo {
void ReportFullSymbolUse(clang::SourceLocation use_loc,
const clang::NamedDecl* decl,
- bool in_cxx_method_body, const char* comment);
+ UseFlags flags, const char* comment);
// 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).
@@ -250,13 +251,13 @@ class IwyuFileInfo {
// We only allow forward-declaring of decls, not arbitrary symbols.
void ReportForwardDeclareUse(clang::SourceLocation use_loc,
const clang::NamedDecl* decl,
- bool in_cxx_method_body, const char* comment);
+ UseFlags flags, const char* comment);
// Called whenever a NamedDecl is accessed through a UsingDecl.
// ie: using std::swap; swap(a, b);
void ReportUsingDeclUse(clang::SourceLocation use_loc,
const clang::UsingDecl* using_decl,
- bool in_cxx_method_body, const char* comment);
+ UseFlags flags, const char* comment);
// This is used when we see a // NOLINT comment, for instance. It says
// '#include this header file as-is, without any public-header mapping.'
diff --git a/iwyu_use_flags.h b/iwyu_use_flags.h
new file mode 100644
index 0000000..45a63a2
--- /dev/null
+++ b/iwyu_use_flags.h
@@ -0,0 +1,23 @@
+//===--- iwyu_use_flags.h - describe various contextual features of uses --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef INCLUDE_WHAT_YOU_USE_IWYU_USE_FLAGS_H_
+#define INCLUDE_WHAT_YOU_USE_IWYU_USE_FLAGS_H_
+
+namespace include_what_you_use {
+
+// Flags describing special features of a use that influence IWYU analysis.
+typedef unsigned UseFlags;
+
+const UseFlags UF_None = 0;
+const UseFlags UF_InCxxMethodBody = 1; // use is inside a C++ method body
+
+}
+
+#endif