diff options
author | Haojian Wu <hokein.wu@gmail.com> | 2023-12-20 10:08:43 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-20 10:08:43 +0100 |
commit | 3b1f06e52712a56bf33757d596482c60013d63fd (patch) | |
tree | a525f5568b1158269df2411490eec0fae617c078 | |
parent | 2349731992017087c6027e1a7fb0fa617c0208a4 (diff) | |
download | llvm-3b1f06e52712a56bf33757d596482c60013d63fd.zip llvm-3b1f06e52712a56bf33757d596482c60013d63fd.tar.gz llvm-3b1f06e52712a56bf33757d596482c60013d63fd.tar.bz2 |
[AST] RecursiveASTVisitor: traverse the require clause for partial template specializations. (#75795)
This fixes tooling (clangd, include-cleaner) bugs where we miss
functionalities on concept AST nodes.
-rw-r--r-- | clang/include/clang/AST/RecursiveASTVisitor.h | 7 | ||||
-rw-r--r-- | clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp | 19 |
2 files changed, 20 insertions, 6 deletions
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index c501801..8f2714e 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2036,12 +2036,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper( #define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \ DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \ /* The partial specialization. */ \ - if (TemplateParameterList *TPL = D->getTemplateParameters()) { \ - for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \ - I != E; ++I) { \ - TRY_TO(TraverseDecl(*I)); \ - } \ - } \ + TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \ /* The args that remains unspecialized. */ \ TRY_TO(TraverseTemplateArgumentLocsHelper( \ D->getTemplateArgsAsWritten()->getTemplateArgs(), \ diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp index 594b299..6a8d916 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp @@ -86,6 +86,25 @@ TEST(RecursiveASTVisitor, Concepts) { EXPECT_EQ(3, Visitor.ConceptRequirementsTraversed); EXPECT_EQ(1, Visitor.ConceptReferencesTraversed); EXPECT_EQ(1, Visitor.ConceptReferencesVisited); + + Visitor = {}; + llvm::StringRef Code = + R"cpp( +template<typename T> concept True = false; +template <typename F> struct Foo {}; + +template <typename F> + requires requires { requires True<F>; } +struct Foo<F> {}; + +template <typename F> requires True<F> +struct Foo<F> {}; + )cpp"; + EXPECT_TRUE(Visitor.runOver(Code, ConceptVisitor::Lang_CXX2a)); + // Check that the concept references from the partial specializations are + // visited. + EXPECT_EQ(2, Visitor.ConceptReferencesTraversed); + EXPECT_EQ(2, Visitor.ConceptReferencesVisited); } struct VisitDeclOnlyOnce : ExpectedLocationVisitor<VisitDeclOnlyOnce> { |