[PATCH] D84136: [clangd] Fix visitation of ConceptSpecializationExpr in constrained-parameter

Nathan Ridge via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 20 00:09:37 PDT 2020


nridge created this revision.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay, ilya-biryukov.
Herald added a project: clang.

There were two problems here:

- RecursiveASTVisitor did not traverse TypeConstraint::ImmediatelyDeclaredConstraint
- ConceptSpecializationExpr::getEndLoc() returned an invalid location in case of a constrained-parameter with no explicit arguments


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84136

Files:
  clang-tools-extra/clangd/unittests/FindTargetTests.cpp
  clang/include/clang/AST/ExprConcepts.h
  clang/include/clang/AST/RecursiveASTVisitor.h


Index: clang/include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- clang/include/clang/AST/RecursiveASTVisitor.h
+++ clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1839,8 +1839,10 @@
   // D is the "T" in something like "template<typename T> class vector;"
   if (D->getTypeForDecl())
     TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
-  if (const auto *TC = D->getTypeConstraint())
+  if (const auto *TC = D->getTypeConstraint()) {
+    TRY_TO(TraverseStmt(TC->getImmediatelyDeclaredConstraint()));
     TRY_TO(TraverseConceptReference(*TC));
+  }
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
     TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
 })
Index: clang/include/clang/AST/ExprConcepts.h
===================================================================
--- clang/include/clang/AST/ExprConcepts.h
+++ clang/include/clang/AST/ExprConcepts.h
@@ -126,7 +126,11 @@
   }
 
   SourceLocation getEndLoc() const LLVM_READONLY {
-    return ArgsAsWritten->RAngleLoc;
+    // If the ConceptSpecializationExpr is the ImmediatelyDeclaredConstraint
+    // of a TypeConstraint written syntactically as a constrained-parameter,
+    // there may not be a template argument list.
+    return ArgsAsWritten->RAngleLoc.isValid() ? ArgsAsWritten->RAngleLoc
+                                              : ConceptName.getEndLoc();
   }
 
   // Iterators
Index: clang-tools-extra/clangd/unittests/FindTargetTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -407,6 +407,34 @@
       // FIXME: Should we truncate the pretty-printed form of a concept decl
       // somewhere?
       {"template <typename T> concept Fooable = requires (T t) { t.foo(); };"});
+
+  // constrained-parameter
+  Code = R"cpp(
+    template <typename T>
+    concept Fooable = true;
+
+    template <[[Fooable]] T>
+    void bar(T t);
+  )cpp";
+  Flags.push_back("-std=c++20");
+  EXPECT_DECLS("ConceptSpecializationExpr",
+               // FIXME: Should we truncate the pretty-printed form of a concept
+               // decl somewhere?
+               {"template <typename T> concept Fooable = true;"});
+
+  // partial-concept-id
+  Code = R"cpp(
+    template <typename T, typename U>
+    concept Fooable = true;
+
+    template <[[Fooable]]<int> T>
+    void bar(T t);
+  )cpp";
+  Flags.push_back("-std=c++20");
+  EXPECT_DECLS("ConceptSpecializationExpr",
+               // FIXME: Should we truncate the pretty-printed form of a concept
+               // decl somewhere?
+               {"template <typename T, typename U> concept Fooable = true;"});
 }
 
 TEST_F(TargetDeclTest, FunctionTemplate) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D84136.279135.patch
Type: text/x-patch
Size: 2846 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200720/bc9887aa/attachment.bin>


More information about the cfe-commits mailing list