Go deeper on template instantiation

When an expanded template param is itself a template specialization, and
is being full-used, and involves a user-provided template argument, then
we need to recursively expand that template to find more uses.
This commit is contained in:
John Bytheway 2020-03-31 20:25:35 -04:00 committed by Kim Gräsman
parent bb6522f2ef
commit 6c719a414d
1 changed files with 21 additions and 6 deletions

27
iwyu.cc
View File

@ -3184,13 +3184,28 @@ class InstantiatedTemplateVisitor
// recursively explore the instantiation of *that* template to see if the
// user's type is full-used therein.
// We attribute all uses in an instantiated template to the
// template's caller.
ReportTypeUse(caller_loc(), type);
if (IsKnownTemplateParam(type)) {
// We attribute all uses in an instantiated template to the
// template's caller.
ReportTypeUse(caller_loc(), type);
// Also report all previous explicit instantiations (declarations and
// definitions) as uses of the caller's location.
ReportExplicitInstantiations(type);
// Also report all previous explicit instantiations (declarations and
// definitions) as uses of the caller's location.
ReportExplicitInstantiations(type);
} else {
const Decl* decl = TypeToDeclAsWritten(type);
if (const auto* cts_decl =
dyn_cast<ClassTemplateSpecializationDecl>(decl)) {
if (ContainsKey(traversed_decls_, decl))
return; // avoid recursion & repetition
traversed_decls_.insert(decl);
VERRS(6)
<< "Recursively traversing " << PrintableDecl(cts_decl)
<< " which was full-used and involves a known template param\n";
TraverseDecl(const_cast<ClassTemplateSpecializationDecl*>(cts_decl));
}
}
}
// Our task is made easier since (at least in theory), every time we