Handle sugared template specs in template args
Non-sugared template specialization type template arguments are already analyzed due to 'TraverseType' call inside 'InstantiatedTemplateVisitor::TraverseSubstTemplateTypeParmTypeHelper' and subsequent 'TraverseTemplateSpecializationTypeHelper' call. Components of sugared template specialization types are added into resugar_map, otherwise their template arguments would not be reported. Test case has been extended.
This commit is contained in:
parent
06f7c21cbc
commit
c3bcb661f6
9
iwyu.cc
9
iwyu.cc
|
@ -2682,8 +2682,7 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
|
|||
// void fn(const S<Class>& s) { // Forward declarations are sufficient here.
|
||||
// (void)s.t; // Full 'Class' type is needed due to template instantiation.
|
||||
// }
|
||||
void ReportTplSpecComponentTypes(const TemplateSpecializationType*) {
|
||||
}
|
||||
void ReportTplSpecComponentTypes(const TemplateSpecializationType*) = delete;
|
||||
|
||||
// Do not add any variables here! If you do, they will not be shared
|
||||
// between the normal iwyu ast visitor and the
|
||||
|
@ -3236,6 +3235,12 @@ class InstantiatedTemplateVisitor
|
|||
return Base::VisitCXXConstructExpr(expr);
|
||||
}
|
||||
|
||||
// --- Handler declared in IwyuBaseASTVisitor.
|
||||
|
||||
void ReportTplSpecComponentTypes(const TemplateSpecializationType* type) {
|
||||
TraverseDataAndTypeMembersOfClassHelper(type);
|
||||
}
|
||||
|
||||
private:
|
||||
// Clears the state of the visitor.
|
||||
void Clear() {
|
||||
|
|
|
@ -547,12 +547,35 @@ class TypeEnumerator : public RecursiveASTVisitor<TypeEnumerator> {
|
|||
}
|
||||
|
||||
// --- Methods on RecursiveASTVisitor
|
||||
bool TraverseType(QualType type) {
|
||||
TraverseArgumentsOfSugaredTemplates(type);
|
||||
return Base::TraverseType(type);
|
||||
}
|
||||
|
||||
bool TraverseTypeLoc(TypeLoc type_loc) {
|
||||
TraverseArgumentsOfSugaredTemplates(type_loc.getType());
|
||||
return Base::TraverseTypeLoc(type_loc);
|
||||
}
|
||||
|
||||
bool VisitType(Type* type) {
|
||||
seen_types_.insert(type);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// Clang doesn't traverse underlying type for most of the sugar types.
|
||||
// If a TemplateSpecializationType occurs in a sugaring chain, traverse its
|
||||
// arguments explicitly, otherwise they aren't put into resugar_map.
|
||||
void TraverseArgumentsOfSugaredTemplates(QualType type) {
|
||||
if (type.isNull())
|
||||
return;
|
||||
|
||||
if (const auto* template_spec = type->getAs<TemplateSpecializationType>()) {
|
||||
for (const TemplateArgument& arg : template_spec->template_arguments())
|
||||
TraverseTemplateArgument(arg);
|
||||
}
|
||||
}
|
||||
|
||||
set<const Type*> seen_types_;
|
||||
};
|
||||
|
||||
|
|
|
@ -80,6 +80,10 @@ void PointerClassArguments() {
|
|||
|
||||
template<typename T> struct Outer { T t; };
|
||||
template<typename T> struct Inner { T t; };
|
||||
struct StaticTemplateFieldStruct {
|
||||
// IWYU: IndirectClass needs a declaration
|
||||
static Inner<IndirectClass> tpl;
|
||||
};
|
||||
|
||||
void NestedTemplateArguments() {
|
||||
// IWYU: IndirectClass needs a declaration
|
||||
|
@ -94,6 +98,23 @@ void NestedTemplateArguments() {
|
|||
// IWYU: IndirectClass needs a declaration
|
||||
Outer<Inner<IndirectClass> >* opi;
|
||||
(void)opi;
|
||||
|
||||
// Test that use of template specialization type template argument is not
|
||||
// hidden by any sugar in the AST.
|
||||
|
||||
// IWYU: IndirectClass is...*indirect.h
|
||||
Outer<decltype(StaticTemplateFieldStruct::tpl)> osi;
|
||||
// Member referencing also requires template instantiation and nested member
|
||||
// full-type-use reporting.
|
||||
// IWYU: IndirectClass is...*indirect.h
|
||||
(void)osi.t;
|
||||
|
||||
Outer<decltype(StaticTemplateFieldStruct::tpl)*> osip;
|
||||
(void)osip.t;
|
||||
|
||||
Outer<decltype(StaticTemplateFieldStruct::tpl)>* opsi;
|
||||
// IWYU: IndirectClass is...*indirect.h
|
||||
(void)opsi->t;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue