ilya-biryukov updated this revision to Diff 425198.
ilya-biryukov added a comment.

- clang-format the code


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D124441/new/

https://reviews.llvm.org/D124441

Files:
  clang-tools-extra/clangd/CodeComplete.cpp
  clang-tools-extra/clangd/Protocol.cpp
  clang-tools-extra/clangd/Quality.cpp
  clang-tools-extra/clangd/index/SymbolCollector.cpp
  clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
  clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
  clang-tools-extra/clangd/unittests/TestIndex.cpp
  clang-tools-extra/clangd/unittests/TestIndex.h
  clang-tools-extra/clangd/unittests/XRefsTests.cpp
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Index/IndexSymbol.h
  clang/lib/Index/IndexBody.cpp
  clang/lib/Index/IndexDecl.cpp
  clang/lib/Index/IndexSymbol.cpp
  clang/lib/Index/IndexTypeSourceInfo.cpp
  clang/lib/Index/IndexingContext.cpp
  clang/lib/Index/USRGeneration.cpp
  clang/tools/libclang/CXIndexDataConsumer.cpp

Index: clang/tools/libclang/CXIndexDataConsumer.cpp
===================================================================
--- clang/tools/libclang/CXIndexDataConsumer.cpp
+++ clang/tools/libclang/CXIndexDataConsumer.cpp
@@ -1247,6 +1247,7 @@
   case SymbolKind::TemplateTypeParm:
   case SymbolKind::TemplateTemplateParm:
   case SymbolKind::NonTypeTemplateParm:
+  case SymbolKind::Concept:
     return CXIdxEntity_Unexposed;
 
   case SymbolKind::Enum: return CXIdxEntity_Enum;
Index: clang/lib/Index/USRGeneration.cpp
===================================================================
--- clang/lib/Index/USRGeneration.cpp
+++ clang/lib/Index/USRGeneration.cpp
@@ -103,6 +103,7 @@
   void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
   void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
   void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
+  void VisitConceptDecl(const ConceptDecl *D);
 
   void VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
     IgnoreResults = true; // No USRs for linkage specs themselves.
@@ -1007,7 +1008,13 @@
   Out << D->getName(); // Simple name.
 }
 
-
+void USRGenerator::VisitConceptDecl(const ConceptDecl *D) {
+  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
+    return;
+  VisitDeclContext(D->getDeclContext());
+  Out << "@CT@";
+  EmitDeclName(D);
+}
 
 //===----------------------------------------------------------------------===//
 // USR generation functions.
Index: clang/lib/Index/IndexingContext.cpp
===================================================================
--- clang/lib/Index/IndexingContext.cpp
+++ clang/lib/Index/IndexingContext.cpp
@@ -86,7 +86,6 @@
        isa<TemplateTemplateParmDecl>(D))) {
     return true;
   }
-
   return handleDeclOccurrence(D, Loc, /*IsRef=*/true, Parent, Roles, Relations,
                               RefE, RefD, DC);
 }
@@ -259,12 +258,9 @@
   if (auto MD = dyn_cast<ObjCMethodDecl>(D))
     return MD->isThisDeclarationADefinition() || isa<ObjCImplDecl>(ContainerDC);
 
-  if (isa<TypedefNameDecl>(D) ||
-      isa<EnumConstantDecl>(D) ||
-      isa<FieldDecl>(D) ||
-      isa<MSPropertyDecl>(D) ||
-      isa<ObjCImplDecl>(D) ||
-      isa<ObjCPropertyImplDecl>(D))
+  if (isa<TypedefNameDecl>(D) || isa<EnumConstantDecl>(D) ||
+      isa<FieldDecl>(D) || isa<MSPropertyDecl>(D) || isa<ObjCImplDecl>(D) ||
+      isa<ObjCPropertyImplDecl>(D) || isa<ConceptDecl>(D))
     return true;
 
   return false;
Index: clang/lib/Index/IndexTypeSourceInfo.cpp
===================================================================
--- clang/lib/Index/IndexTypeSourceInfo.cpp
+++ clang/lib/Index/IndexTypeSourceInfo.cpp
@@ -7,7 +7,10 @@
 //===----------------------------------------------------------------------===//
 
 #include "IndexingContext.h"
+#include "clang/AST/ASTConcept.h"
+#include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/TypeLoc.h"
 #include "llvm/ADT/ScopeExit.h"
 
 using namespace clang;
@@ -77,6 +80,13 @@
     return true;
   }
 
+  bool VisitAutoTypeLoc(AutoTypeLoc TL) {
+    if (auto *C = TL.getNamedConcept())
+      return IndexCtx.handleReference(C, TL.getConceptNameLoc(), Parent,
+                                      ParentDC);
+    return true;
+  }
+
   bool traverseParamVarHelper(ParmVarDecl *D) {
     TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
     if (D->getTypeSourceInfo())
Index: clang/lib/Index/IndexSymbol.cpp
===================================================================
--- clang/lib/Index/IndexSymbol.cpp
+++ clang/lib/Index/IndexSymbol.cpp
@@ -371,6 +371,9 @@
     case Decl::NonTypeTemplateParm:
       Info.Kind = SymbolKind::NonTypeTemplateParm;
       break;
+    case Decl::Concept:
+      Info.Kind = SymbolKind::Concept;
+      break;
     // Other decls get the 'unknown' kind.
     default:
       break;
@@ -534,6 +537,8 @@
   case SymbolKind::TemplateTypeParm: return "template-type-param";
   case SymbolKind::TemplateTemplateParm: return "template-template-param";
   case SymbolKind::NonTypeTemplateParm: return "non-type-template-param";
+  case SymbolKind::Concept:
+    return "concept";
   }
   llvm_unreachable("invalid symbol kind");
 }
Index: clang/lib/Index/IndexDecl.cpp
===================================================================
--- clang/lib/Index/IndexDecl.cpp
+++ clang/lib/Index/IndexDecl.cpp
@@ -7,10 +7,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "IndexingContext.h"
+#include "clang/AST/ASTConcept.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DeclVisitor.h"
 #include "clang/Index/IndexDataConsumer.h"
+#include "clang/Index/IndexSymbol.h"
 
 using namespace clang;
 using namespace index;
@@ -129,6 +132,8 @@
         }
       }
     }
+    if (auto *C = D->getTrailingRequiresClause())
+      IndexCtx.indexBody(C, Parent);
   }
 
   bool handleObjCMethod(const ObjCMethodDecl *D,
@@ -681,36 +686,52 @@
     return true;
   }
 
-  bool VisitTemplateDecl(const TemplateDecl *D) {
+  void indexTemplateParameters(TemplateParameterList *Params,
+                               const NamedDecl *Parent) {
+    for (const NamedDecl *TP : *Params) {
+      if (IndexCtx.shouldIndexTemplateParameters())
+        IndexCtx.handleDecl(TP);
+      if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
+        if (TTP->hasDefaultArgument())
+          IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent);
+        if (auto *C = TTP->getTypeConstraint())
+          IndexCtx.handleReference(C->getNamedConcept(), C->getConceptNameLoc(),
+                                   Parent, TTP->getLexicalDeclContext());
+      } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) {
+        if (NTTP->hasDefaultArgument())
+          IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent);
+      } else if (const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) {
+        if (TTPD->hasDefaultArgument())
+          handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
+                                    TP->getLexicalDeclContext());
+      }
+    }
+    if (auto *R = Params->getRequiresClause())
+      IndexCtx.indexBody(R, Parent);
+  }
 
+  bool VisitTemplateDecl(const TemplateDecl *D) {
     const NamedDecl *Parent = D->getTemplatedDecl();
     if (!Parent)
       return true;
 
     // Index the default values for the template parameters.
-    if (D->getTemplateParameters() &&
-        shouldIndexTemplateParameterDefaultValue(Parent)) {
-      const TemplateParameterList *Params = D->getTemplateParameters();
-      for (const NamedDecl *TP : *Params) {
-        if (IndexCtx.shouldIndexTemplateParameters())
-          IndexCtx.handleDecl(TP);
-        if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
-          if (TTP->hasDefaultArgument())
-            IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent);
-        } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) {
-          if (NTTP->hasDefaultArgument())
-            IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent);
-        } else if (const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) {
-          if (TTPD->hasDefaultArgument())
-            handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
-                                      TP->getLexicalDeclContext());
-        }
-      }
+    auto *Params = D->getTemplateParameters();
+    if (Params && shouldIndexTemplateParameterDefaultValue(Parent)) {
+      indexTemplateParameters(Params, Parent);
     }
 
     return Visit(Parent);
   }
 
+  bool VisitConceptDecl(const ConceptDecl *D) {
+    if (auto *Params = D->getTemplateParameters())
+      indexTemplateParameters(Params, D);
+    if (auto *E = D->getConstraintExpr())
+      IndexCtx.indexBody(E, D);
+    return IndexCtx.handleDecl(D);
+  }
+
   bool VisitFriendDecl(const FriendDecl *D) {
     if (auto ND = D->getFriendDecl()) {
       // FIXME: Ignore a class template in a dependent context, these are not
Index: clang/lib/Index/IndexBody.cpp
===================================================================
--- clang/lib/Index/IndexBody.cpp
+++ clang/lib/Index/IndexBody.cpp
@@ -7,8 +7,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "IndexingContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/ASTConcept.h"
 #include "clang/AST/ASTLambda.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/ExprConcepts.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/Type.h"
 
 using namespace clang;
 using namespace clang::index;
@@ -455,10 +459,10 @@
   }
 
   bool VisitParmVarDecl(ParmVarDecl* D) {
-    // Index the parameters of lambda expression.
+    // Index the parameters of lambda expression and requires expression.
     if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
       const auto *DC = D->getDeclContext();
-      if (DC && isLambdaCallOperator(DC))
+      if (DC && (isLambdaCallOperator(DC) || isa<RequiresExprBodyDecl>(DC)))
         IndexCtx.handleDecl(D);
     }
     return true;
@@ -472,6 +476,21 @@
                                Relations, E);
     return true;
   }
+
+  bool VisitConceptSpecializationExpr(ConceptSpecializationExpr *R) {
+    IndexCtx.handleReference(R->getNamedConcept(), R->getConceptNameLoc(),
+                             Parent, ParentDC);
+    return true;
+  }
+
+  bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+    // This handles references in return type requirements of RequiresExpr.
+    // E.g. `requires (T x) { {*x} -> ConceptRef }`
+    if (auto *C = D->getTypeConstraint())
+      IndexCtx.handleReference(C->getNamedConcept(), C->getConceptNameLoc(),
+                               Parent, ParentDC);
+    return true;
+  }
 };
 
 } // anonymous namespace
Index: clang/include/clang/Index/IndexSymbol.h
===================================================================
--- clang/include/clang/Index/IndexSymbol.h
+++ clang/include/clang/Index/IndexSymbol.h
@@ -57,6 +57,8 @@
   TemplateTypeParm,
   TemplateTemplateParm,
   NonTypeTemplateParm,
+
+  Concept, /// C++20 concept.
 };
 
 enum class SymbolLanguage : uint8_t {
Index: clang/include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- clang/include/clang/AST/RecursiveASTVisitor.h
+++ clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2841,9 +2841,10 @@
       if (!ExprReq->isExprSubstitutionFailure())
         TRY_TO(TraverseStmt(ExprReq->getExpr()));
       auto &RetReq = ExprReq->getReturnTypeRequirement();
-      if (RetReq.isTypeConstraint())
-        TRY_TO(TraverseTemplateParameterListHelper(
-                   RetReq.getTypeConstraintTemplateParameterList()));
+      if (RetReq.isTypeConstraint()) {
+        TRY_TO(TraverseStmt(
+            RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint()));
+      }
     } else {
       auto *NestedReq = cast<concepts::NestedRequirement>(Req);
       if (!NestedReq->isSubstitutionFailure())
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -1850,6 +1850,8 @@
 void checkFindRefs(llvm::StringRef Test, bool UseIndex = false) {
   Annotations T(Test);
   auto TU = TestTU::withCode(T.code());
+  TU.ExtraArgs.push_back("-std=c++20");
+
   auto AST = TU.build();
   std::vector<Matcher<ReferencesResult::Reference>> ExpectedLocations;
   for (const auto &R : T.ranges())
@@ -2064,6 +2066,38 @@
     checkFindRefs(Test);
 }
 
+TEST(FindReferences, ConceptsWithinAST) {
+  constexpr llvm::StringLiteral Code = R"cpp(
+    template <class T>
+    concept $def[[IsSmal^l]] = sizeof(T) <= 8;
+
+    template <class T>
+    concept IsSmallPtr = requires(T x) {
+      { *x } -> [[IsSmal^l]];
+    };
+
+    [[IsSmall]] auto i = 'c';
+    template<[[IsSmal^l]] U> void foo();
+    template<class U> void bar() requires [[IsSmal^l]]<U>;
+    template<class U> requires [[IsSmal^l]]<U> void baz();
+    static_assert([[IsSma^ll]]<char>);
+  )cpp";
+  checkFindRefs(Code);
+}
+
+TEST(FindReferences, RequiresExprParameters) {
+  constexpr llvm::StringLiteral Code = R"cpp(
+    template <class T>
+    concept IsSmall = sizeof(T) <= 8;
+
+    template <class T>
+    concept IsSmallPtr = requires(T $def[[^x]]) {
+      { *[[^x]] } -> IsSmall;
+    };
+  )cpp";
+  checkFindRefs(Code);
+}
+
 TEST(FindReferences, IncludeOverrides) {
   llvm::StringRef Test =
       R"cpp(
Index: clang-tools-extra/clangd/unittests/TestIndex.h
===================================================================
--- clang-tools-extra/clangd/unittests/TestIndex.h
+++ clang-tools-extra/clangd/unittests/TestIndex.h
@@ -31,6 +31,8 @@
 Symbol var(llvm::StringRef Name);
 // Creates a namespace symbol.
 Symbol ns(llvm::StringRef Name);
+// Create a C++20 concept symbol.
+Symbol conceptSym(llvm::StringRef Name);
 
 // Create a slab of symbols with the given qualified names as IDs and names.
 SymbolSlab generateSymbols(std::vector<std::string> QualifiedNames);
Index: clang-tools-extra/clangd/unittests/TestIndex.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/TestIndex.cpp
+++ clang-tools-extra/clangd/unittests/TestIndex.cpp
@@ -77,6 +77,10 @@
   return sym(Name, index::SymbolKind::Namespace, "@N@\\0");
 }
 
+Symbol conceptSym(llvm::StringRef Name) {
+  return sym(Name, index::SymbolKind::Concept, "@CT@\\0");
+}
+
 SymbolSlab generateSymbols(std::vector<std::string> QualifiedNames) {
   SymbolSlab::Builder Slab;
   for (llvm::StringRef QName : QualifiedNames)
Index: clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
+++ clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
@@ -59,6 +59,7 @@
 MATCHER_P(templateArgs, TemplArgs, "") {
   return arg.TemplateSpecializationArgs == TemplArgs;
 }
+MATCHER_P(hasKind, Kind, "") { return arg.SymInfo.Kind == Kind; }
 MATCHER_P(declURI, P, "") {
   return StringRef(arg.CanonicalDeclaration.FileURI) == P;
 }
@@ -1962,6 +1963,17 @@
   EXPECT_THAT(Symbols, IsEmpty());
 }
 
+TEST_F(SymbolCollectorTest, Concepts) {
+  const char *Header = R"cpp(
+    template <class T>
+    concept A = sizeof(T) <= 8;
+  )cpp";
+  runSymbolCollector("", Header, {"-std=c++20"});
+  EXPECT_THAT(Symbols,
+              UnorderedElementsAre(AllOf(
+                  qName("A"), hasKind(clang::index::SymbolKind::Concept))));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -3565,6 +3565,38 @@
               IsEmpty());
 }
 
+TEST(CompletionTest, Concepts) {
+  Annotations Code(R"cpp(
+    template<class T>
+    concept A = sizeof(T) <= 8;
+
+    template<$tparam^A U>
+    int foo();
+
+    template<class T>
+    concept b = $other^A<T> && $other^sizeof(T) % 2 == 0 || $other^A<T> && sizeof(T) == 1;
+
+    $other^A<T> auto i = 19;
+  )cpp");
+  TestTU TU;
+  TU.Code = Code.code().str();
+  TU.ExtraArgs = {"-std=c++20"};
+
+  std::vector<Symbol> Syms = {conceptSym("same_as")};
+  for (auto P : Code.points("tparam")) {
+    ASSERT_THAT(completions(TU, P, Syms).Completions,
+                AllOf(Contains(named("A")), Contains(named("same_as")),
+                      Contains(named("class")), Contains(named("typename"))))
+        << "Completing template parameter at position " << P;
+  }
+
+  for (auto P : Code.points("other")) {
+    EXPECT_THAT(completions(TU, P, Syms).Completions,
+                AllOf(Contains(named("A")), Contains(named("same_as"))))
+        << "Completing 'requires' expression at position " << P;
+  }
+}
+
 TEST(SignatureHelp, DocFormat) {
   Annotations Code(R"cpp(
     // Comment `with` markup.
Index: clang-tools-extra/clangd/index/SymbolCollector.cpp
===================================================================
--- clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -88,6 +88,7 @@
   case SK::Function:
   case SK::Variable:
   case SK::EnumConstant:
+  case SK::Concept:
     return true;
   default:
     return false;
Index: clang-tools-extra/clangd/Quality.cpp
===================================================================
--- clang-tools-extra/clangd/Quality.cpp
+++ clang-tools-extra/clangd/Quality.cpp
@@ -122,6 +122,7 @@
   case index::SymbolKind::TypeAlias:
   case index::SymbolKind::TemplateTypeParm:
   case index::SymbolKind::TemplateTemplateParm:
+  case index::SymbolKind::Concept:
     return SymbolQualitySignals::Type;
   case index::SymbolKind::Function:
   case index::SymbolKind::ClassMethod:
Index: clang-tools-extra/clangd/Protocol.cpp
===================================================================
--- clang-tools-extra/clangd/Protocol.cpp
+++ clang-tools-extra/clangd/Protocol.cpp
@@ -301,6 +301,8 @@
   case index::SymbolKind::TemplateTemplateParm:
   case index::SymbolKind::TemplateTypeParm:
     return SymbolKind::TypeParameter;
+  case index::SymbolKind::Concept:
+    return SymbolKind::Interface;
   }
   llvm_unreachable("invalid symbol kind");
 }
Index: clang-tools-extra/clangd/CodeComplete.cpp
===================================================================
--- clang-tools-extra/clangd/CodeComplete.cpp
+++ clang-tools-extra/clangd/CodeComplete.cpp
@@ -129,6 +129,8 @@
   case SK::TemplateTypeParm:
   case SK::TemplateTemplateParm:
     return CompletionItemKind::TypeParameter;
+  case SK::Concept:
+    return CompletionItemKind::Interface;
   }
   llvm_unreachable("Unhandled clang::index::SymbolKind.");
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to