================
@@ -2196,23 +2208,23 @@ bool
RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
the source code anywhere. (Note the instatiated *type* --
\
set<int> -- is written, and will still get a callback of
\
TemplateSpecializationType). For explicit instantiations
\
- ("template set<int>;"), we do need a callback, since this
\
- is the only callback that's made for this instantiation.
\
- We use getTemplateArgsAsWritten() to distinguish. */
\
+ ("template set<int>;"), the ExplicitInstantiationDecl node
\
+ handles traversal of template args and qualifier.
\
+ For explicit specializations ("template<> set<int> {...};"),
\
+ we traverse template args here since there is no EID. */
\
if (const auto *ArgsWritten = D->getTemplateArgsAsWritten()) {
\
assert(D->getTemplateSpecializationKind() != TSK_ImplicitInstantiation);
\
- /* The args that remains unspecialized. */
\
- TRY_TO(TraverseTemplateArgumentLocsHelper(
\
- ArgsWritten->getTemplateArgs(), ArgsWritten->NumTemplateArgs));
\
+ if (D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) {
\
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
\
+ ArgsWritten->getTemplateArgs(), ArgsWritten->NumTemplateArgs));
\
+ }
\
}
\
\
if (getDerived().shouldVisitTemplateInstantiations() ||
\
D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) {
\
/* Traverse base definition for explicit specializations */
\
TRY_TO(Traverse##DECLKIND##Helper(D));
\
} else {
\
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
\
-
\
----------------
16bit-ykiko wrote:
The canonical decl for an explicit instantiation here is the
`ClassTemplateSpecializationDecl` / `VarTemplateSpecializationDecl`. Before
EID, these nodes partially assumed the responsibility of recording the source
location information for explicit instantiations (though sometimes
inaccurately, like with the NNS), which is why RAV traversed those locations
here.
Now that we have EID, the location information is both more complete and
accurate, so the traversal should be handled uniformly when visiting the EID
instead. If we also traverse the specialization node, downstream tools like
clang-tidy will receive duplicate callbacks (for example, `avoid-c-arrays`
would report two warnings for the same type, which was fixed in a previous
commit).
Note that we didn't just delete the traversal entirely; the
`TSK_ExplicitSpecialization` branch is kept because explicit specializations
(`template<>`) do not have a corresponding EID, meaning they still need to
traverse their own template arguments.
https://github.com/llvm/llvm-project/pull/191658
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits