Skip to content

Commit

Permalink
Use the definition to check if decl is provided by template
Browse files Browse the repository at this point in the history
TypeToDeclAsWritten would not return the written definition in all cases.

For templates, for example, the selected declaration could be the one
where it was explicitly instantiatiated. That, in turn, affects the source
location that is returned and ultimately the outcome of the function.

Make sure to always get to the definition before using it to determine
whether the template being instantiated provides the decl.

Fixes #558
  • Loading branch information
jru committed Dec 7, 2018
1 parent a9f3656 commit edfc3be
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 3 deletions.
6 changes: 4 additions & 2 deletions iwyu.cc
Expand Up @@ -3207,7 +3207,7 @@ class InstantiatedTemplateVisitor
ast_node != caller_ast_node_; ast_node = ast_node->parent()) {
if (preprocessor_info().PublicHeaderIntendsToProvide(
GetFileEntry(ast_node->GetLocation()),
GetFileEntry(decl)))
GetFileEntry(decl->getLocation())))
return ast_node->GetLocation();
}
return SourceLocation(); // an invalid source-loc
Expand All @@ -3219,8 +3219,10 @@ class InstantiatedTemplateVisitor
bool IsProvidedByTemplate(const Type* type) const {
type = RemoveSubstTemplateTypeParm(type);
type = RemovePointersAndReferences(type); // get down to the decl
if (const NamedDecl* decl = TypeToDeclAsWritten(type))
if (const NamedDecl* decl = TypeToDeclAsWritten(type)) {
decl = GetDefinitionAsWritten(decl);
return GetLocOfTemplateThatProvides(decl).isValid();
}
return true; // we always provide non-decl types like int, etc.
}

Expand Down
8 changes: 8 additions & 0 deletions tests/cxx/explicit_instantiation2-template_helpers.h
Expand Up @@ -37,4 +37,12 @@ class TemplateTemplateArgShortFwd {
T<short>* t;
};

template <class T>
class ProvidedTemplate {};

template <class U = short, class T = ProvidedTemplate<U>>
class TemplateAsDefaultFullProvided {
T t;
};

#endif // INCLUDE_WHAT_YOU_USE_TESTS_CXX_EXPLICIT_INSTANTIATION2_TEMPLATE_HELPERS_H_
2 changes: 2 additions & 0 deletions tests/cxx/explicit_instantiation2-template_short.h
Expand Up @@ -12,4 +12,6 @@

extern template class Template<short>;

extern template class ProvidedTemplate<short>;

#endif // INCLUDE_WHAT_YOU_USE_TESTS_CXX_EXPLICIT_INSTANTIATION2_TEMPLATE_SHORT_H_
6 changes: 5 additions & 1 deletion tests/cxx/explicit_instantiation2.cc
Expand Up @@ -29,6 +29,8 @@
// 6: Fwd-decl use in a template, provided as a default parameter.
// 9: Implicit instantiation of Template<int>
// 10: Specialization of Template<T>
// 11: Explicit instantiation with a dependent instantiation declaration, but
// provided by the template helper itself.


// IWYU: Template is...*explicit_instantiation-template.h
Expand Down Expand Up @@ -81,6 +83,8 @@ template <> class Template<char> {};

TemplateAsDefaultFull<char> t10; // 10

TemplateAsDefaultFullProvided<> t11; // 11

/**** IWYU_SUMMARY
tests/cxx/explicit_instantiation2.cc should add these lines:
Expand All @@ -93,7 +97,7 @@ tests/cxx/explicit_instantiation2.cc should remove these lines:
The full include-list for tests/cxx/explicit_instantiation2.cc:
#include "explicit_instantiation-template.h" // for Template
#include "explicit_instantiation2-template_helpers.h" // for FullUseArg, FwdDeclUseArg, TemplateAsDefaultFull, TemplateAsDefaultFwd, TemplateTemplateArgShortFull, TemplateTemplateArgShortFwd
#include "explicit_instantiation2-template_helpers.h" // for FullUseArg, FwdDeclUseArg, TemplateAsDefaultFull, TemplateAsDefaultFullProvided, TemplateAsDefaultFwd, TemplateTemplateArgShortFull, TemplateTemplateArgShortFwd
#include "explicit_instantiation2-template_short.h" // for Template
***** IWYU_SUMMARY */

0 comments on commit edfc3be

Please sign in to comment.