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.
This commit is contained in:
parent
0d0832fee7
commit
27da44e009
26
iwyu.cc
26
iwyu.cc
|
@ -109,6 +109,7 @@
|
||||||
#include "iwyu_location_util.h"
|
#include "iwyu_location_util.h"
|
||||||
#include "iwyu_output.h"
|
#include "iwyu_output.h"
|
||||||
#include "iwyu_path_util.h"
|
#include "iwyu_path_util.h"
|
||||||
|
#include "iwyu_use_flags.h"
|
||||||
// This is needed for
|
// This is needed for
|
||||||
// preprocessor_info().PublicHeaderIntendsToProvide(). Somehow IWYU
|
// preprocessor_info().PublicHeaderIntendsToProvide(). Somehow IWYU
|
||||||
// removes it mistakenly.
|
// removes it mistakenly.
|
||||||
|
@ -1632,12 +1633,13 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
|
||||||
// Checkers, that tell iwyu_output about uses of symbols.
|
// Checkers, that tell iwyu_output about uses of symbols.
|
||||||
// We let, but don't require, subclasses to override these.
|
// We let, but don't require, subclasses to override these.
|
||||||
|
|
||||||
// The comment, if not nullptr, is extra text that is included along
|
// The comment, if not nullptr, is extra text that is included along with
|
||||||
// with the warning message that iwyu emits.
|
// 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,
|
virtual void ReportDeclUse(SourceLocation used_loc,
|
||||||
const NamedDecl* used_decl,
|
const NamedDecl* used_decl,
|
||||||
const char* comment = nullptr) {
|
const char* comment = nullptr,
|
||||||
|
UseFlags extra_use_flags = 0) {
|
||||||
const NamedDecl* target_decl = used_decl;
|
const NamedDecl* target_decl = used_decl;
|
||||||
|
|
||||||
// Sometimes a shadow decl comes between us and the 'real' 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))
|
if (CanIgnoreDecl(target_decl))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const UseFlags use_flags =
|
||||||
|
ComputeUseFlags(current_ast_node()) | extra_use_flags;
|
||||||
|
|
||||||
// Canonicalize the use location and report the use.
|
// Canonicalize the use location and report the use.
|
||||||
used_loc = GetCanonicalUseLocation(used_loc, target_decl);
|
used_loc = GetCanonicalUseLocation(used_loc, target_decl);
|
||||||
const FileEntry* used_in = GetFileEntry(used_loc);
|
const FileEntry* used_in = GetFileEntry(used_loc);
|
||||||
preprocessor_info().FileInfoFor(used_in)->ReportFullSymbolUse(
|
preprocessor_info().FileInfoFor(used_in)->ReportFullSymbolUse(
|
||||||
used_loc, target_decl, ComputeUseFlags(current_ast_node()),
|
used_loc, target_decl, use_flags, comment);
|
||||||
comment);
|
|
||||||
|
|
||||||
// Sometimes using a decl drags in a few other uses as well:
|
// Sometimes using a decl drags in a few other uses as well:
|
||||||
|
|
||||||
|
@ -1672,8 +1676,7 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
|
||||||
= GetUsingDeclarationOf(used_decl,
|
= GetUsingDeclarationOf(used_decl,
|
||||||
GetDeclContext(current_ast_node()))) {
|
GetDeclContext(current_ast_node()))) {
|
||||||
preprocessor_info().FileInfoFor(used_in)->ReportUsingDeclUse(
|
preprocessor_info().FileInfoFor(used_in)->ReportUsingDeclUse(
|
||||||
used_loc, using_decl, ComputeUseFlags(current_ast_node()),
|
used_loc, using_decl, use_flags, "(for using decl)");
|
||||||
"(for using decl)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For typedefs, the user of the type is sometimes the one
|
// 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
|
// (if templates call other templates, we have to find the right
|
||||||
// template).
|
// template).
|
||||||
void ReportDeclUse(SourceLocation used_loc, const NamedDecl* decl,
|
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);
|
const SourceLocation actual_used_loc = GetLocOfTemplateThatProvides(decl);
|
||||||
if (actual_used_loc.isValid()) {
|
if (actual_used_loc.isValid()) {
|
||||||
// If a template is responsible for this decl, then we don't add
|
// 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
|
// it to the cache; the cache is only for decls that the
|
||||||
// original caller is responsible for.
|
// original caller is responsible for.
|
||||||
Base::ReportDeclUse(actual_used_loc, decl, comment);
|
Base::ReportDeclUse(actual_used_loc, decl, comment, extra_use_flags);
|
||||||
} else {
|
} else {
|
||||||
// Let all the currently active types and decls know about this
|
// Let all the currently active types and decls know about this
|
||||||
// report, so they can update their cache entries.
|
// report, so they can update their cache entries.
|
||||||
for (CacheStoringScope* storer : cache_storers_)
|
for (CacheStoringScope* storer : cache_storers_)
|
||||||
storer->NoteReportedDecl(decl);
|
storer->NoteReportedDecl(decl);
|
||||||
Base::ReportDeclUse(caller_loc(), decl, comment);
|
Base::ReportDeclUse(caller_loc(), decl, comment, extra_use_flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -237,12 +237,12 @@ string GetShortNameAsString(const clang::NamedDecl* named_decl) {
|
||||||
|
|
||||||
// Holds information about a single full or fwd-decl use of a symbol.
|
// Holds information about a single full or fwd-decl use of a symbol.
|
||||||
OneUse::OneUse(const NamedDecl* decl, SourceLocation use_loc,
|
OneUse::OneUse(const NamedDecl* decl, SourceLocation use_loc,
|
||||||
OneUse::UseKind use_kind, UseFlags flags,
|
SourceLocation decl_loc, OneUse::UseKind use_kind,
|
||||||
const char* comment)
|
UseFlags flags, const char* comment)
|
||||||
: symbol_name_(internal::GetQualifiedNameAsString(decl)),
|
: symbol_name_(internal::GetQualifiedNameAsString(decl)),
|
||||||
short_symbol_name_(internal::GetShortNameAsString(decl)),
|
short_symbol_name_(internal::GetShortNameAsString(decl)),
|
||||||
decl_(decl),
|
decl_(decl),
|
||||||
decl_loc_(GetInstantiationLoc(GetLocation(decl))),
|
decl_loc_(GetInstantiationLoc(decl_loc)),
|
||||||
decl_file_(GetFileEntry(decl_loc_)),
|
decl_file_(GetFileEntry(decl_loc_)),
|
||||||
decl_filepath_(GetFilePath(decl_file_)),
|
decl_filepath_(GetFilePath(decl_file_)),
|
||||||
use_loc_(use_loc),
|
use_loc_(use_loc),
|
||||||
|
@ -577,15 +577,23 @@ void IwyuFileInfo::ReportFullSymbolUse(SourceLocation use_loc,
|
||||||
UseFlags flags,
|
UseFlags flags,
|
||||||
const char* comment) {
|
const char* comment) {
|
||||||
if (decl) {
|
if (decl) {
|
||||||
// Since we need the full symbol, we need the decl's definition-site.
|
const NamedDecl* report_decl;
|
||||||
// But only if we're not defining the function, in which case we want to use
|
SourceLocation report_decl_loc;
|
||||||
// all its preceding declarations, and not try to canonicalize.
|
|
||||||
if (!(flags & UF_FunctionDfn)) {
|
if ((flags & (UF_FunctionDfn | UF_ExplicitInstantiation)) == 0) {
|
||||||
decl = GetDefinitionAsWritten(decl);
|
// 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,
|
symbol_uses_.push_back(OneUse(report_decl, use_loc, report_decl_loc,
|
||||||
flags, comment));
|
OneUse::kFullUse, flags, comment));
|
||||||
LogSymbolUse("Marked full-info use of decl", symbol_uses_.back());
|
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
|
// combines friend decls with true forward-declare decls. If that
|
||||||
// happened here, replace the friend with a real fwd decl.
|
// happened here, replace the friend with a real fwd decl.
|
||||||
decl = GetNonfriendClassRedecl(decl);
|
decl = GetNonfriendClassRedecl(decl);
|
||||||
symbol_uses_.push_back(OneUse(decl, use_loc, OneUse::kForwardDeclareUse,
|
symbol_uses_.push_back(OneUse(decl, use_loc, GetLocation(decl),
|
||||||
flags, comment));
|
OneUse::kForwardDeclareUse, flags, comment));
|
||||||
LogSymbolUse("Marked fwd-decl use of decl", symbol_uses_.back());
|
LogSymbolUse("Marked fwd-decl use of decl", symbol_uses_.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ class OneUse {
|
||||||
|
|
||||||
OneUse(const clang::NamedDecl* decl,
|
OneUse(const clang::NamedDecl* decl,
|
||||||
clang::SourceLocation use_loc,
|
clang::SourceLocation use_loc,
|
||||||
|
clang::SourceLocation decl_loc,
|
||||||
UseKind use_kind,
|
UseKind use_kind,
|
||||||
UseFlags flags,
|
UseFlags flags,
|
||||||
const char* comment);
|
const char* comment);
|
||||||
|
|
|
@ -16,9 +16,9 @@ namespace include_what_you_use {
|
||||||
typedef unsigned UseFlags;
|
typedef unsigned UseFlags;
|
||||||
|
|
||||||
const UseFlags UF_None = 0;
|
const UseFlags UF_None = 0;
|
||||||
const UseFlags UF_InCxxMethodBody = 1; // use is inside a C++ method body
|
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_FunctionDfn = 2; // use is a function being defined
|
||||||
|
const UseFlags UF_ExplicitInstantiation = 4; // use targets an explicit instantiation
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue