Skip to content

Commit

Permalink
[AST] RecursiveASTVisitor: traverse the require clause for partial te…
Browse files Browse the repository at this point in the history
…mplate specializations. (#75795)

This fixes tooling (clangd, include-cleaner) bugs where we miss
functionalities on concept AST nodes.
  • Loading branch information
hokein committed Dec 20, 2023
1 parent 2349731 commit 3b1f06e
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 6 deletions.
7 changes: 1 addition & 6 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(), \
Expand Down
19 changes: 19 additions & 0 deletions clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down

0 comments on commit 3b1f06e

Please sign in to comment.