[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