summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ.Ru <juanruben.segovia@gmail.com>2018-10-25 08:42:17 +0200
committerJ.Ru <juanruben.segovia@gmail.com>2018-12-07 09:12:01 +0100
commit27da44e009660d8efc9726b1a4d80d8f9f063539 (patch)
treefbd8ca1abe4d3c40a598ed185483fa53f6b4da87
parent0d0832fee7adffd7ead9e5c90683e403de5e9b2b (diff)
Introduce an extra use flag UF_ExplicitInstantiation
To signal that the use refers to an explicit instantiation, for which the "canonical" decl is not suitable. Also, since it is meant to be used in a specific context, the ReportDeclUse prototype has been adapted to take optional extra flags as an additional input.
-rw-r--r--iwyu.cc26
-rw-r--r--iwyu_output.cc32
-rw-r--r--iwyu_output.h1
-rw-r--r--iwyu_use_flags.h6
4 files changed, 39 insertions, 26 deletions
diff --git a/iwyu.cc b/iwyu.cc
index a8cf92d..f5cfa5f 100644
--- a/iwyu.cc
+++ b/iwyu.cc
@@ -109,6 +109,7 @@
#include "iwyu_location_util.h"
#include "iwyu_output.h"
#include "iwyu_path_util.h"
+#include "iwyu_use_flags.h"
// This is needed for
// preprocessor_info().PublicHeaderIntendsToProvide(). Somehow IWYU
// removes it mistakenly.
@@ -1632,12 +1633,13 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
// Checkers, that tell iwyu_output about uses of symbols.
// We let, but don't require, subclasses to override these.
- // The comment, if not nullptr, is extra text that is included along
- // with the warning message that iwyu emits.
+ // The comment, if not nullptr, is extra text that is included along with
+ // the warning message that iwyu emits. The extra use flags is optional
+ // info that can be assigned to the use (see the UF_* constants)
virtual void ReportDeclUse(SourceLocation used_loc,
const NamedDecl* used_decl,
- const char* comment = nullptr) {
-
+ const char* comment = nullptr,
+ UseFlags extra_use_flags = 0) {
const NamedDecl* target_decl = used_decl;
// Sometimes a shadow decl comes between us and the 'real' decl.
@@ -1649,12 +1651,14 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
if (CanIgnoreDecl(target_decl))
return;
+ const UseFlags use_flags =
+ ComputeUseFlags(current_ast_node()) | extra_use_flags;
+
// Canonicalize the use location and report the use.
used_loc = GetCanonicalUseLocation(used_loc, target_decl);
const FileEntry* used_in = GetFileEntry(used_loc);
preprocessor_info().FileInfoFor(used_in)->ReportFullSymbolUse(
- used_loc, target_decl, ComputeUseFlags(current_ast_node()),
- comment);
+ used_loc, target_decl, use_flags, comment);
// Sometimes using a decl drags in a few other uses as well:
@@ -1672,8 +1676,7 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
= GetUsingDeclarationOf(used_decl,
GetDeclContext(current_ast_node()))) {
preprocessor_info().FileInfoFor(used_in)->ReportUsingDeclUse(
- used_loc, using_decl, ComputeUseFlags(current_ast_node()),
- "(for using decl)");
+ used_loc, using_decl, use_flags, "(for using decl)");
}
// For typedefs, the user of the type is sometimes the one
@@ -2910,19 +2913,20 @@ class InstantiatedTemplateVisitor
// (if templates call other templates, we have to find the right
// template).
void ReportDeclUse(SourceLocation used_loc, const NamedDecl* decl,
- const char* comment = nullptr) override {
+ const char* comment = nullptr,
+ UseFlags extra_use_flags = 0) override {
const SourceLocation actual_used_loc = GetLocOfTemplateThatProvides(decl);
if (actual_used_loc.isValid()) {
// If a template is responsible for this decl, then we don't add
// it to the cache; the cache is only for decls that the
// original caller is responsible for.
- Base::ReportDeclUse(actual_used_loc, decl, comment);
+ Base::ReportDeclUse(actual_used_loc, decl, comment, extra_use_flags);
} else {
// Let all the currently active types and decls know about this
// report, so they can update their cache entries.
for (CacheStoringScope* storer : cache_storers_)
storer->NoteReportedDecl(decl);
- Base::ReportDeclUse(caller_loc(), decl, comment);
+ Base::ReportDeclUse(caller_loc(), decl, comment, extra_use_flags);
}
}
diff --git a/iwyu_output.cc b/iwyu_output.cc
index 126aa50..797c4d3 100644
--- a/iwyu_output.cc
+++ b/iwyu_output.cc
@@ -237,12 +237,12 @@ 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, UseFlags flags,
- const char* comment)
+ SourceLocation decl_loc, OneUse::UseKind use_kind,
+ UseFlags flags, const char* comment)
: symbol_name_(internal::GetQualifiedNameAsString(decl)),
short_symbol_name_(internal::GetShortNameAsString(decl)),
decl_(decl),
- decl_loc_(GetInstantiationLoc(GetLocation(decl))),
+ decl_loc_(GetInstantiationLoc(decl_loc)),
decl_file_(GetFileEntry(decl_loc_)),
decl_filepath_(GetFilePath(decl_file_)),
use_loc_(use_loc),
@@ -577,15 +577,23 @@ void IwyuFileInfo::ReportFullSymbolUse(SourceLocation use_loc,
UseFlags flags,
const char* comment) {
if (decl) {
- // Since we need the full symbol, we need the decl's definition-site.
- // But only if we're not defining the function, in which case we want to use
- // all its preceding declarations, and not try to canonicalize.
- if (!(flags & UF_FunctionDfn)) {
- decl = GetDefinitionAsWritten(decl);
+ const NamedDecl* report_decl;
+ SourceLocation report_decl_loc;
+
+ if ((flags & (UF_FunctionDfn | UF_ExplicitInstantiation)) == 0) {
+ // Since we need the full symbol, we need the decl's definition-site too.
+ // Also, by default we canonicalize the location, using GetLocation.
+ report_decl = GetDefinitionAsWritten(decl);
+ report_decl_loc = GetLocation(report_decl);
+ } else {
+ // However, if we're defining the function or we are targeting an explicit
+ // instantiation, we want to use it as-is and not try to canonicalize at all.
+ report_decl = decl;
+ report_decl_loc = decl->getLocation();
}
- symbol_uses_.push_back(OneUse(decl, use_loc, OneUse::kFullUse,
- flags, comment));
+ symbol_uses_.push_back(OneUse(report_decl, use_loc, report_decl_loc,
+ OneUse::kFullUse, flags, comment));
LogSymbolUse("Marked full-info use of decl", symbol_uses_.back());
}
}
@@ -630,8 +638,8 @@ void IwyuFileInfo::ReportForwardDeclareUse(SourceLocation use_loc,
// combines friend decls with true forward-declare decls. If that
// happened here, replace the friend with a real fwd decl.
decl = GetNonfriendClassRedecl(decl);
- symbol_uses_.push_back(OneUse(decl, use_loc, OneUse::kForwardDeclareUse,
- flags, comment));
+ symbol_uses_.push_back(OneUse(decl, use_loc, GetLocation(decl),
+ OneUse::kForwardDeclareUse, flags, comment));
LogSymbolUse("Marked fwd-decl use of decl", symbol_uses_.back());
}
diff --git a/iwyu_output.h b/iwyu_output.h
index 3aed01d..719f821 100644
--- a/iwyu_output.h
+++ b/iwyu_output.h
@@ -50,6 +50,7 @@ class OneUse {
OneUse(const clang::NamedDecl* decl,
clang::SourceLocation use_loc,
+ clang::SourceLocation decl_loc,
UseKind use_kind,
UseFlags flags,
const char* comment);
diff --git a/iwyu_use_flags.h b/iwyu_use_flags.h
index 4a2e749..39cac34 100644
--- a/iwyu_use_flags.h
+++ b/iwyu_use_flags.h
@@ -16,9 +16,9 @@ namespace include_what_you_use {
typedef unsigned UseFlags;
const UseFlags UF_None = 0;
-const UseFlags UF_InCxxMethodBody = 1; // use is inside a C++ method body
-const UseFlags UF_FunctionDfn = 2; // use is a function being defined
-
+const UseFlags UF_InCxxMethodBody = 1; // use is inside a C++ method body
+const UseFlags UF_FunctionDfn = 2; // use is a function being defined
+const UseFlags UF_ExplicitInstantiation = 4; // use targets an explicit instantiation
}
#endif