[clang-tools-extra] [clang-tidy] do not diagnose array types within implicit instantiations of a template (PR #132924)
Julian Schmidt via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 31 15:40:34 PDT 2025
================
@@ -39,6 +39,55 @@ AST_MATCHER(clang::ParmVarDecl, isArgvOfMain) {
return FD ? FD->isMain() : false;
}
+template <typename TargetType, typename NodeType>
+const TargetType *getAs(const NodeType *Node) {
+ if constexpr (std::is_same_v<NodeType, clang::DynTypedNode>)
+ return Node->template get<TargetType>();
+ else
+ return llvm::dyn_cast<TargetType>(Node);
+}
+
+AST_MATCHER(clang::TypeLoc, isWithinImplicitTemplateInstantiation) {
+ const auto IsImplicitTemplateInstantiation = [](const auto *Node) {
+ const auto IsImplicitInstantiation = [](const auto *Node) {
+ return (Node != nullptr) && (Node->getTemplateSpecializationKind() ==
+ TSK_ImplicitInstantiation);
+ };
+ return (IsImplicitInstantiation(getAs<clang::CXXRecordDecl>(Node)) ||
+ IsImplicitInstantiation(getAs<clang::FunctionDecl>(Node)) ||
+ IsImplicitInstantiation(getAs<clang::VarDecl>(Node)));
+ };
+
+ DynTypedNodeList ParentNodes = Finder->getASTContext().getParents(Node);
+ const clang::NamedDecl *ParentDecl = nullptr;
+ while (!ParentNodes.empty()) {
+ const DynTypedNode &ParentNode = ParentNodes[0];
+ if (IsImplicitTemplateInstantiation(&ParentNode))
+ return true;
+
+ // in case of a `NamedDecl` as parent node, it is more efficient to proceed
+ // with the upward traversal via DeclContexts (see below) instead of via
+ // parent nodes
+ if ((ParentDecl = ParentNode.template get<clang::NamedDecl>()))
+ break;
+
+ ParentNodes = Finder->getASTContext().getParents(ParentNode);
+ }
+
+ if (ParentDecl != nullptr) {
+ const clang::DeclContext *DeclContext = ParentDecl->getDeclContext();
+ while (DeclContext != nullptr) {
+ for (const clang::Decl *Decl : DeclContext->decls()) {
+ if (IsImplicitTemplateInstantiation(Decl))
+ return true;
+ }
----------------
5chmidti wrote:
This would traverse down again. Certain things like `FunctionDecl` inherit from `DeclContext`, so, instead you should use the `DeclContext` variable itself to check for the template instantiation kind (`getAs` might work, otherwise you can use `llvm::dyn_cast` in the above lambda). Otherwise, you would check e.g. `C` when you were really just looking at `B`. The `decls()` method gives you the contained declarations of the DeclContext.
```
A
/ \
B C
```
https://github.com/llvm/llvm-project/pull/132924
More information about the cfe-commits
mailing list