Fix template instantiation reporting
Full template specialization type use requires full information about its template-argument-dependent fields and nested typedefs. But earlier, it wasn't reported in many cases when template specialization type isn't written explicitly in non-fwd-decl context.
This commit is contained in:
parent
ac93b84f01
commit
526827957b
25
iwyu.cc
25
iwyu.cc
|
@ -1665,6 +1665,10 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
|
|||
comment);
|
||||
}
|
||||
} else {
|
||||
if (const auto* template_spec_type =
|
||||
dyn_cast<TemplateSpecializationType>(Desugar(type))) {
|
||||
this->getDerived().ReportTplSpecComponentTypes(template_spec_type);
|
||||
}
|
||||
if (const NamedDecl* decl = TypeToDeclAsWritten(type)) {
|
||||
decl = GetDefinitionAsWritten(decl);
|
||||
VERRS(6) << "(For type " << PrintableType(type) << "):\n";
|
||||
|
@ -2670,6 +2674,17 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
|
|||
visitor_state_->processed_overload_locs.insert(loc);
|
||||
}
|
||||
|
||||
// Report types needed for template instantiation in cases when template
|
||||
// specialization type isn't explicitly written in a source code
|
||||
// in a non-fwd-declarable context (otherwise, they should be reported from
|
||||
// VisitTemplateSpecializationType), e.g.:
|
||||
// template <class T> struct S { T t; };
|
||||
// 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*) {
|
||||
}
|
||||
|
||||
// Do not add any variables here! If you do, they will not be shared
|
||||
// between the normal iwyu ast visitor and the
|
||||
// template-instantiation visitor, which is almost always a mistake.
|
||||
|
@ -4197,6 +4212,16 @@ class IwyuAstConsumer
|
|||
return true;
|
||||
}
|
||||
|
||||
// --- Handler declared in IwyuBaseASTVisitor.
|
||||
|
||||
void ReportTplSpecComponentTypes(const TemplateSpecializationType* type) {
|
||||
const map<const Type*, const Type*> resugar_map =
|
||||
GetTplTypeResugarMapForClass(type);
|
||||
ASTNode node(type);
|
||||
node.SetParent(current_ast_node());
|
||||
instantiated_template_visitor_.ScanInstantiatedType(&node, resugar_map);
|
||||
}
|
||||
|
||||
private:
|
||||
// Class we call to handle instantiated template functions and classes.
|
||||
InstantiatedTemplateVisitor instantiated_template_visitor_;
|
||||
|
|
|
@ -1565,17 +1565,17 @@ int main() {
|
|||
// IWYU: i1_ns::I1_NamespaceClass is...*badinc-i1.h
|
||||
I1_Class* i1_class_tpl_ctor = new I1_Class(&i1_namespace_class, 1);
|
||||
|
||||
// TODO(csilvers): IWYU: I2_Class needs a declaration
|
||||
// IWYU: I2_Class is...*badinc-i2.h
|
||||
// IWYU: I2_Class::~I2_Class is...*badinc-i2-inl.h
|
||||
// IWYU: I1_Struct is...*badinc-i1.h
|
||||
// IWYU: I1_TemplateClass is...*badinc-i1.h
|
||||
delete newed_i1_template_class;
|
||||
// TODO(csilvers): IWYU: I2_Class needs a declaration
|
||||
// IWYU: I2_Class is...*badinc-i2.h
|
||||
// IWYU: I2_Class::~I2_Class is...*badinc-i2-inl.h
|
||||
// IWYU: I1_Struct is...*badinc-i1.h
|
||||
// IWYU: I1_TemplateClass is...*badinc-i1.h
|
||||
delete[] newed_i1_template_class_array;
|
||||
// TODO(csilvers): IWYU: I2_Class needs a declaration
|
||||
// IWYU: I2_Class is...*badinc-i2.h
|
||||
// IWYU: I2_Class::~I2_Class is...*badinc-i2-inl.h
|
||||
// IWYU: I1_Struct is...*badinc-i1.h
|
||||
// IWYU: I1_TemplateClass is...*badinc-i1.h
|
||||
|
|
|
@ -90,6 +90,7 @@ void PlacementNewOfTemplate() {
|
|||
|
||||
// Make sure we handle it right when we explicitly call the dtor, as well.
|
||||
// IWYU: ClassTemplate is...*placement_new-i1.h
|
||||
// IWYU: IndirectClass is...*indirect.h
|
||||
placement_newed_template->~ClassTemplate();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue