diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -17,6 +17,7 @@ #include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/PrettyPrinter.h" @@ -279,6 +280,9 @@ void VisitCallExpr(const CallExpr *CE) { Outer.add(CE->getCalleeDecl(), Flags); } + void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) { + Outer.add(E->getNamedConcept(), Flags); + } void VisitDeclRefExpr(const DeclRefExpr *DRE) { const Decl *D = DRE->getDecl(); // UsingShadowDecl allows us to record the UsingDecl. diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -339,6 +339,24 @@ {"struct Test", Rel::TemplatePattern}); } +TEST_F(TargetDeclTest, Concept) { + Code = R"cpp( + template + concept Fooable = requires (T t) { t.foo(); }; + + template requires [[Fooable]] + void bar(T t) { + t.foo(); + } + )cpp"; + Flags.push_back("-std=c++2a"); + EXPECT_DECLS( + "ConceptSpecializationExpr", + // FIXME: Should we truncate the pretty-printed form of a concept decl + // somewhere? + {"template concept Fooable = requires (T t) { t.foo(); };"}); +} + TEST_F(TargetDeclTest, FunctionTemplate) { Code = R"cpp( // Implicit specialization.