[clang-tools-extra] c6c5dbc - [clangd] Add C++20 concepts support to findExplicitReferences() and semantic highlighting
Nathan Ridge via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 23 12:12:05 PST 2020
Author: Nathan Ridge
Date: 2020-01-23T15:11:46-05:00
New Revision: c6c5dbc824c508c5cd36da450ecfbd12858403c4
URL: https://github.com/llvm/llvm-project/commit/c6c5dbc824c508c5cd36da450ecfbd12858403c4
DIFF: https://github.com/llvm/llvm-project/commit/c6c5dbc824c508c5cd36da450ecfbd12858403c4.diff
LOG: [clangd] Add C++20 concepts support to findExplicitReferences() and semantic highlighting
Summary: Fixes https://github.com/clangd/clangd/issues/259
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73124
Added:
Modified:
clang-tools-extra/clangd/FindTarget.cpp
clang-tools-extra/clangd/SemanticHighlighting.cpp
clang-tools-extra/clangd/SemanticHighlighting.h
clang-tools-extra/clangd/test/semantic-highlighting.test
clang-tools-extra/clangd/unittests/FindTargetTests.cpp
clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 31cdcee0cfe7..6123ffbb76ac 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -618,6 +618,12 @@ llvm::SmallVector<ReferenceLoc, 2> refInExpr(const Expr *E) {
// FIXME: handle more complicated cases, e.g. ObjC, designated initializers.
llvm::SmallVector<ReferenceLoc, 2> Refs;
+ void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) {
+ Refs.push_back(ReferenceLoc{E->getNestedNameSpecifierLoc(),
+ E->getConceptNameLoc(),
+ /*IsDecl=*/false,
+ {E->getNamedConcept()}});
+ }
void VisitDeclRefExpr(const DeclRefExpr *E) {
Refs.push_back(ReferenceLoc{E->getQualifierLoc(),
E->getNameInfo().getLoc(),
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index 2b65625ae2d2..5c71db5d80b3 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -98,6 +98,8 @@ llvm::Optional<HighlightingKind> kindForDecl(const NamedDecl *D) {
if (isa<TemplateTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
isa<NonTypeTemplateParmDecl>(D))
return HighlightingKind::TemplateParameter;
+ if (isa<ConceptDecl>(D))
+ return HighlightingKind::Concept;
return llvm::None;
}
llvm::Optional<HighlightingKind> kindForType(const Type *TP) {
@@ -392,6 +394,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, HighlightingKind K) {
return OS << "Namespace";
case HighlightingKind::TemplateParameter:
return OS << "TemplateParameter";
+ case HighlightingKind::Concept:
+ return OS << "Concept";
case HighlightingKind::Primitive:
return OS << "Primitive";
case HighlightingKind::Macro:
@@ -534,6 +538,8 @@ llvm::StringRef toTextMateScope(HighlightingKind Kind) {
return "entity.name.namespace.cpp";
case HighlightingKind::TemplateParameter:
return "entity.name.type.template.cpp";
+ case HighlightingKind::Concept:
+ return "entity.name.type.concept.cpp";
case HighlightingKind::Primitive:
return "storage.type.primitive.cpp";
case HighlightingKind::Macro:
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.h b/clang-tools-extra/clangd/SemanticHighlighting.h
index 7a25ce5da060..cf4a51a341e7 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.h
+++ b/clang-tools-extra/clangd/SemanticHighlighting.h
@@ -41,6 +41,7 @@ enum class HighlightingKind {
DependentName,
Namespace,
TemplateParameter,
+ Concept,
Primitive,
Macro,
diff --git a/clang-tools-extra/clangd/test/semantic-highlighting.test b/clang-tools-extra/clangd/test/semantic-highlighting.test
index 4036c541069b..fca2b09a14eb 100644
--- a/clang-tools-extra/clangd/test/semantic-highlighting.test
+++ b/clang-tools-extra/clangd/test/semantic-highlighting.test
@@ -53,6 +53,9 @@
# CHECK-NEXT: "entity.name.type.template.cpp"
# CHECK-NEXT: ],
# CHECK-NEXT: [
+# CHECK-NEXT: "entity.name.type.concept.cpp"
+# CHECK-NEXT: ],
+# CHECK-NEXT: [
# CHECK-NEXT: "storage.type.primitive.cpp"
# CHECK-NEXT: ],
# CHECK-NEXT: [
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index ed3da28aa0d1..96e488d8a0f4 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -571,7 +571,7 @@ class FindExplicitReferencesTest : public ::testing::Test {
// FIXME: Auto-completion in a template requires disabling delayed template
// parsing.
TU.ExtraArgs.push_back("-fno-delayed-template-parsing");
- TU.ExtraArgs.push_back("-std=c++17");
+ TU.ExtraArgs.push_back("-std=c++2a");
auto AST = TU.build();
for (auto &D : AST.getDiagnostics()) {
@@ -1091,7 +1091,27 @@ TEST_F(FindExplicitReferencesTest, All) {
"0: targets = {foo::T}, decl\n"
"1: targets = {foo::V}, decl\n"
"2: targets = {vector}\n"
- "3: targets = {foo::T}\n"}};
+ "3: targets = {foo::T}\n"},
+ // Concept
+ {
+ R"cpp(
+ template <typename T>
+ concept Drawable = requires (T t) { t.draw(); };
+
+ namespace foo {
+ template <typename $0^T> requires $1^Drawable<$2^T>
+ void $3^bar($4^T $5^t) {
+ $6^t.draw();
+ }
+ }
+ )cpp",
+ "0: targets = {T}, decl\n"
+ "1: targets = {Drawable}\n"
+ "2: targets = {T}\n"
+ "3: targets = {foo::bar}, decl\n"
+ "4: targets = {T}\n"
+ "5: targets = {t}, decl\n"
+ "6: targets = {t}\n"}};
for (const auto &C : Cases) {
llvm::StringRef ExpectedCode = C.first;
diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
index 6dcad34857cd..d51f41af0359 100644
--- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
@@ -55,6 +55,7 @@ std::vector<HighlightingToken> getExpectedTokens(Annotations &Test) {
{HighlightingKind::DependentType, "DependentType"},
{HighlightingKind::DependentName, "DependentName"},
{HighlightingKind::TemplateParameter, "TemplateParameter"},
+ {HighlightingKind::Concept, "Concept"},
{HighlightingKind::Primitive, "Primitive"},
{HighlightingKind::Macro, "Macro"}};
std::vector<HighlightingToken> ExpectedTokens;
@@ -108,6 +109,7 @@ void checkHighlightings(llvm::StringRef Code,
// FIXME: Auto-completion in a template requires disabling delayed template
// parsing.
TU.ExtraArgs.push_back("-fno-delayed-template-parsing");
+ TU.ExtraArgs.push_back("-std=c++2a");
for (auto File : AdditionalFiles)
TU.AdditionalFiles.insert({File.first, File.second});
@@ -649,6 +651,19 @@ sizeof...($TemplateParameter[[Elements]]);
static const int $StaticField[[Value]] = $TemplateParameter[[T]]
::$DependentType[[Resolver]]::$DependentName[[Value]];
};
+ )cpp",
+ // Concepts
+ R"cpp(
+ template <typename $TemplateParameter[[T]]>
+ concept $Concept[[Fooable]] =
+ requires($TemplateParameter[[T]] $Parameter[[F]]) {
+ $Parameter[[F]].$DependentName[[foo]]();
+ };
+ template <typename $TemplateParameter[[T]]>
+ requires $Concept[[Fooable]]<$TemplateParameter[[T]]>
+ void $Function[[bar]]($TemplateParameter[[T]] $Parameter[[F]]) {
+ $Parameter[[F]].$DependentName[[foo]]();
+ }
)cpp"};
for (const auto &TestCase : TestCases) {
checkHighlightings(TestCase);
More information about the cfe-commits
mailing list