Skip to content

Commit c6c5dbc

Browse files
[clangd] Add C++20 concepts support to findExplicitReferences() and semantic highlighting
Summary: Fixes clangd/clangd#259 Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D73124
1 parent 210f088 commit c6c5dbc

File tree

6 files changed

+53
-2
lines changed

6 files changed

+53
-2
lines changed

clang-tools-extra/clangd/FindTarget.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,12 @@ llvm::SmallVector<ReferenceLoc, 2> refInExpr(const Expr *E) {
618618
// FIXME: handle more complicated cases, e.g. ObjC, designated initializers.
619619
llvm::SmallVector<ReferenceLoc, 2> Refs;
620620

621+
void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) {
622+
Refs.push_back(ReferenceLoc{E->getNestedNameSpecifierLoc(),
623+
E->getConceptNameLoc(),
624+
/*IsDecl=*/false,
625+
{E->getNamedConcept()}});
626+
}
621627
void VisitDeclRefExpr(const DeclRefExpr *E) {
622628
Refs.push_back(ReferenceLoc{E->getQualifierLoc(),
623629
E->getNameInfo().getLoc(),

clang-tools-extra/clangd/SemanticHighlighting.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ llvm::Optional<HighlightingKind> kindForDecl(const NamedDecl *D) {
9898
if (isa<TemplateTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
9999
isa<NonTypeTemplateParmDecl>(D))
100100
return HighlightingKind::TemplateParameter;
101+
if (isa<ConceptDecl>(D))
102+
return HighlightingKind::Concept;
101103
return llvm::None;
102104
}
103105
llvm::Optional<HighlightingKind> kindForType(const Type *TP) {
@@ -392,6 +394,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, HighlightingKind K) {
392394
return OS << "Namespace";
393395
case HighlightingKind::TemplateParameter:
394396
return OS << "TemplateParameter";
397+
case HighlightingKind::Concept:
398+
return OS << "Concept";
395399
case HighlightingKind::Primitive:
396400
return OS << "Primitive";
397401
case HighlightingKind::Macro:
@@ -534,6 +538,8 @@ llvm::StringRef toTextMateScope(HighlightingKind Kind) {
534538
return "entity.name.namespace.cpp";
535539
case HighlightingKind::TemplateParameter:
536540
return "entity.name.type.template.cpp";
541+
case HighlightingKind::Concept:
542+
return "entity.name.type.concept.cpp";
537543
case HighlightingKind::Primitive:
538544
return "storage.type.primitive.cpp";
539545
case HighlightingKind::Macro:

clang-tools-extra/clangd/SemanticHighlighting.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ enum class HighlightingKind {
4141
DependentName,
4242
Namespace,
4343
TemplateParameter,
44+
Concept,
4445
Primitive,
4546
Macro,
4647

clang-tools-extra/clangd/test/semantic-highlighting.test

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
# CHECK-NEXT: "entity.name.type.template.cpp"
5454
# CHECK-NEXT: ],
5555
# CHECK-NEXT: [
56+
# CHECK-NEXT: "entity.name.type.concept.cpp"
57+
# CHECK-NEXT: ],
58+
# CHECK-NEXT: [
5659
# CHECK-NEXT: "storage.type.primitive.cpp"
5760
# CHECK-NEXT: ],
5861
# CHECK-NEXT: [

clang-tools-extra/clangd/unittests/FindTargetTests.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ class FindExplicitReferencesTest : public ::testing::Test {
571571
// FIXME: Auto-completion in a template requires disabling delayed template
572572
// parsing.
573573
TU.ExtraArgs.push_back("-fno-delayed-template-parsing");
574-
TU.ExtraArgs.push_back("-std=c++17");
574+
TU.ExtraArgs.push_back("-std=c++2a");
575575

576576
auto AST = TU.build();
577577
for (auto &D : AST.getDiagnostics()) {
@@ -1091,7 +1091,27 @@ TEST_F(FindExplicitReferencesTest, All) {
10911091
"0: targets = {foo::T}, decl\n"
10921092
"1: targets = {foo::V}, decl\n"
10931093
"2: targets = {vector}\n"
1094-
"3: targets = {foo::T}\n"}};
1094+
"3: targets = {foo::T}\n"},
1095+
// Concept
1096+
{
1097+
R"cpp(
1098+
template <typename T>
1099+
concept Drawable = requires (T t) { t.draw(); };
1100+
1101+
namespace foo {
1102+
template <typename $0^T> requires $1^Drawable<$2^T>
1103+
void $3^bar($4^T $5^t) {
1104+
$6^t.draw();
1105+
}
1106+
}
1107+
)cpp",
1108+
"0: targets = {T}, decl\n"
1109+
"1: targets = {Drawable}\n"
1110+
"2: targets = {T}\n"
1111+
"3: targets = {foo::bar}, decl\n"
1112+
"4: targets = {T}\n"
1113+
"5: targets = {t}, decl\n"
1114+
"6: targets = {t}\n"}};
10951115

10961116
for (const auto &C : Cases) {
10971117
llvm::StringRef ExpectedCode = C.first;

clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ std::vector<HighlightingToken> getExpectedTokens(Annotations &Test) {
5555
{HighlightingKind::DependentType, "DependentType"},
5656
{HighlightingKind::DependentName, "DependentName"},
5757
{HighlightingKind::TemplateParameter, "TemplateParameter"},
58+
{HighlightingKind::Concept, "Concept"},
5859
{HighlightingKind::Primitive, "Primitive"},
5960
{HighlightingKind::Macro, "Macro"}};
6061
std::vector<HighlightingToken> ExpectedTokens;
@@ -108,6 +109,7 @@ void checkHighlightings(llvm::StringRef Code,
108109
// FIXME: Auto-completion in a template requires disabling delayed template
109110
// parsing.
110111
TU.ExtraArgs.push_back("-fno-delayed-template-parsing");
112+
TU.ExtraArgs.push_back("-std=c++2a");
111113

112114
for (auto File : AdditionalFiles)
113115
TU.AdditionalFiles.insert({File.first, File.second});
@@ -649,6 +651,19 @@ sizeof...($TemplateParameter[[Elements]]);
649651
static const int $StaticField[[Value]] = $TemplateParameter[[T]]
650652
::$DependentType[[Resolver]]::$DependentName[[Value]];
651653
};
654+
)cpp",
655+
// Concepts
656+
R"cpp(
657+
template <typename $TemplateParameter[[T]]>
658+
concept $Concept[[Fooable]] =
659+
requires($TemplateParameter[[T]] $Parameter[[F]]) {
660+
$Parameter[[F]].$DependentName[[foo]]();
661+
};
662+
template <typename $TemplateParameter[[T]]>
663+
requires $Concept[[Fooable]]<$TemplateParameter[[T]]>
664+
void $Function[[bar]]($TemplateParameter[[T]] $Parameter[[F]]) {
665+
$Parameter[[F]].$DependentName[[foo]]();
666+
}
652667
)cpp"};
653668
for (const auto &TestCase : TestCases) {
654669
checkHighlightings(TestCase);

0 commit comments

Comments
 (0)