sammccall created this revision.
sammccall added a reviewer: usaxena95.
Herald added subscribers: cfe-commits, kadircet, arphaman.
Herald added a project: clang.
sammccall requested review of this revision.
Herald added subscribers: MaskRay, ilya-biryukov.

auto must be used for the code to parse.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D89700

Files:
  clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp


Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -572,6 +572,8 @@
             R"cpp(const char * x = "test";)cpp");
 
   EXPECT_UNAVAILABLE("dec^ltype(au^to) x = 10;");
+  // expanding types in structured bindings is syntactically invalid.
+  EXPECT_UNAVAILABLE("const ^auto &[x,y] = (int[]){1,2};");
 
   // FIXME: Auto-completion in a template requires disabling delayed template
   // parsing.
Index: clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp
===================================================================
--- clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp
+++ clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp
@@ -53,13 +53,24 @@
 
 std::string ExpandAutoType::title() const { return "Expand auto type"; }
 
+// Structured bindings must use auto, e.g. `const auto& [a,b,c] = ...;`.
+// Return whether N (an AutoTypeLoc) is such an auto that must not be expanded.
+bool isStructuredBindingType(const SelectionTree::Node *N) {
+  // Walk up the TypeLoc chain, because auto may be qualified.
+  while (N && N->ASTNode.get<TypeLoc>())
+    N = N->Parent;
+  // The relevant type is the only direct type child of a Decomposition.
+  return N && N->ASTNode.get<DecompositionDecl>();
+}
+
 bool ExpandAutoType::prepare(const Selection& Inputs) {
   CachedLocation = llvm::None;
   if (auto *Node = Inputs.ASTSelection.commonAncestor()) {
     if (auto *TypeNode = Node->ASTNode.get<TypeLoc>()) {
       if (const AutoTypeLoc Result = TypeNode->getAs<AutoTypeLoc>()) {
         // Code in apply() does handle 'decltype(auto)' yet.
-        if (!Result.getTypePtr()->isDecltypeAuto())
+        if (!Result.getTypePtr()->isDecltypeAuto() &&
+            !isStructuredBindingType(Node))
           CachedLocation = Result;
       }
     }


Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -572,6 +572,8 @@
             R"cpp(const char * x = "test";)cpp");
 
   EXPECT_UNAVAILABLE("dec^ltype(au^to) x = 10;");
+  // expanding types in structured bindings is syntactically invalid.
+  EXPECT_UNAVAILABLE("const ^auto &[x,y] = (int[]){1,2};");
 
   // FIXME: Auto-completion in a template requires disabling delayed template
   // parsing.
Index: clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp
===================================================================
--- clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp
+++ clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp
@@ -53,13 +53,24 @@
 
 std::string ExpandAutoType::title() const { return "Expand auto type"; }
 
+// Structured bindings must use auto, e.g. `const auto& [a,b,c] = ...;`.
+// Return whether N (an AutoTypeLoc) is such an auto that must not be expanded.
+bool isStructuredBindingType(const SelectionTree::Node *N) {
+  // Walk up the TypeLoc chain, because auto may be qualified.
+  while (N && N->ASTNode.get<TypeLoc>())
+    N = N->Parent;
+  // The relevant type is the only direct type child of a Decomposition.
+  return N && N->ASTNode.get<DecompositionDecl>();
+}
+
 bool ExpandAutoType::prepare(const Selection& Inputs) {
   CachedLocation = llvm::None;
   if (auto *Node = Inputs.ASTSelection.commonAncestor()) {
     if (auto *TypeNode = Node->ASTNode.get<TypeLoc>()) {
       if (const AutoTypeLoc Result = TypeNode->getAs<AutoTypeLoc>()) {
         // Code in apply() does handle 'decltype(auto)' yet.
-        if (!Result.getTypePtr()->isDecltypeAuto())
+        if (!Result.getTypePtr()->isDecltypeAuto() &&
+            !isStructuredBindingType(Node))
           CachedLocation = Result;
       }
     }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to