[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-05 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,254 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Test template usage goes to next line too:
+  verifyFormat("void foo() {\n"
+   "  myFunc<\n"
+   "  T\n"
+   "  >();\n"
+   "}",
+   "void foo() {\n"
+   "  myFunc<\n"
+   "  T>();\n"
+   "}",
+   Style);
+
+  // Now test that it handles the cases when the column limit forces wrapping.
+  Style.ColumnLimit = 40;
+  // Breaks when the name is looong. Note that these names are exactly 1
+  // character too long for the ColumnLimit.
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Barrr\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+  // BlockIndent style is used when the ColumnLimit allows it:
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);

owenca wrote:

> However, these other two I don't think are tested anymore?
> 
> ```c++
>   verifyFormat("template "  typename Barr>\n"
>"void foo() {}",
>   

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-05 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,254 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Test template usage goes to next line too:
+  verifyFormat("void foo() {\n"
+   "  myFunc<\n"
+   "  T\n"
+   "  >();\n"
+   "}",
+   "void foo() {\n"
+   "  myFunc<\n"
+   "  T>();\n"
+   "}",
+   Style);
+
+  // Now test that it handles the cases when the column limit forces wrapping.
+  Style.ColumnLimit = 40;
+  // Breaks when the name is looong. Note that these names are exactly 1
+  // character too long for the ColumnLimit.
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Barrr\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+  // BlockIndent style is used when the ColumnLimit allows it:
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);

owenca wrote:

IIRC we agreed that these 3 test cases are redundant? 

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https:

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-05 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,254 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Test template usage goes to next line too:
+  verifyFormat("void foo() {\n"
+   "  myFunc<\n"
+   "  T\n"
+   "  >();\n"
+   "}",
+   "void foo() {\n"
+   "  myFunc<\n"
+   "  T>();\n"
+   "}",
+   Style);
+
+  // Now test that it handles the cases when the column limit forces wrapping.
+  Style.ColumnLimit = 40;
+  // Breaks when the name is looong. Note that these names are exactly 1
+  // character too long for the ColumnLimit.
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Barrr\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+  // BlockIndent style is used when the ColumnLimit allows it:
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // Additionally, long names should be split in one step:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Barrr\n"
+   ">\n"
+   "void foo() {}",
+   

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-05 Thread Owen Pan via cfe-commits


@@ -304,6 +304,10 @@ bool ContinuationIndenter::canBreak(const LineState 
&State) {
Current.closesBlockOrBlockTypeList(Style))) 
{
 return false;
   }
+  if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
+  !CurrentState.BreakBeforeClosingAngle) {
+return false;
+  }

owenca wrote:

```suggestion
  if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser))
return CurrentState.BreakBeforeClosingAngle;
```
And move this to line 362 below for ease of maintenance.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;\n",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;\n",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambda = [](T t) {};\n"
+   "}",
+   Style);
+

leijurv wrote:

Gotch

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;\n",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;\n",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambda = [](T t) {};\n"
+   "}",
+   Style);
+

owenca wrote:

That s

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread via cfe-commits

leijurv wrote:

Ah, it resolved itself as of 
https://github.com/leijurv/llvm-project/commit/b6219e250b80114c9b93a7762db7c3e0cbd84260

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread via cfe-commits

https://github.com/leijurv edited 
https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);

leijurv wrote:

I was unaware of that! That explains a lot of redundancies that I now agree 
with you about. Removed: 
https://github.com/leijurv/llvm-project/commit/b6219e250b80114c9b93a7762db7c3e0cbd84260

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 01/19] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].La

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread via cfe-commits

leijurv wrote:

GitHub is having issues it appears - the commit 
https://github.com/leijurv/llvm-project/commit/e1eaba9b05b00adf44628e2ceb1b3374fec902cb
 is certainly pushed, and I even tried pushing an empty commit on top to kick 
github into working, 
https://github.com/leijurv/llvm-project/commit/7d456ca2457dc7d7d2403562386097880bedaa34
 but still this PR is in a glitched state that doesn't show those commits...

https://github.com/user-attachments/assets/9b48ee20-9da8-434c-8986-9445f143f2b9";
 />


https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);

leijurv wrote:

I apologize, it appears that in my commit 
https://github.com/leijurv/llvm-project/commit/e1eaba9b05b00adf44628e2ceb1b3374fec902cb
 I missed removing this one, bit of a coincidence (I swear it wasn't on 
purpose). I have just now triple checked to ensure that all your other comments 
were indeed addressed, I believe I only missed this one.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);

owenca wrote:

As I explained, they are already tested by "the test cases at lines 11272 and 
11280 below" as the two-argument version of `verifyFormat()` first checks that 
the input is formatted to the expected output and then ensures that the 
expected output doesn't change when being formatted. In other words, 
`verifyFormat(Output, Input)` also does `verifyNoChange(Output)`.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);

owenca wrote:

You can add them back if you prefer.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;\n",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;\n",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambda = [](T t) {};\n"
+   "}",
+   Style);
+
+  // Test template usage goes to next

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;\n",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;\n",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambda = [](T t) {};\n"
+   "}",
+   Style);
+
+  // Test template usage goes to next

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;\n",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;\n",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambda = [](T t) {};\n"
+   "}",
+   Style);
+
+  // Test template usage goes to next

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;\n",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;\n",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambda = [](T t) {};\n"
+   "}",
+   Style);
+

owenca wrote:

Delete

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;\n",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;\n",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambda = [](T t) {};\n"
+   "}",
+   Style);
+
+  // Test template usage goes to next

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;\n",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;\n",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambda = [](T t) {};\n"
+   "}",
+   Style);
+
+  // Test template usage goes to next

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;\n",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;\n",

owenca wrote:

```suggestion
  "T1>>;",
```

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;\n",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;\n",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambda = [](T t) {};\n"
+   "}",
+   Style);
+
+  // Test template usage goes to next

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);

owenca wrote:

Delete. Current behavior.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;\n",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;\n",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambda = [](T t) {};\n"
+   "}",
+   Style);
+
+  // Test template usage goes to next

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;\n",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;\n",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambda = [](T t) {};\n"
+   "}",
+   Style);
+
+  // Test template usage goes to next

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;\n",
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1>>;\n",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambda = [](T t) {};\n"
+   "}",
+   Style);
+
+  // Test template usage goes to next

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);

owenca wrote:

Delete. Redundant to the test cases at lines 11272 and 11280 below as 
`verifyFormat(Output, Input)` also checks the stability of `Output`.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);

owenca wrote:

Delete. Current behavior.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-04 Thread Owen Pan via cfe-commits


@@ -11224,6 +11224,328 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getLLVMStyle();
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = true;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from https://github.com/llvm/llvm-project/issues/80049:
+  verifyFormat(
+  "using type = std::remove_cv_t<\n"
+  "add_common_cv_reference<\n"
+  "std::common_type_t, std::decay_t>,\n"
+  "T0,\n"
+  "T1\n"
+  ">\n"
+  ">;\n",

owenca wrote:

```suggestion
  ">;",
```

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-02 Thread via cfe-commits


@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from issue #80049:
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambd

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-02 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 01/16] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca1..84ab1b0a2eff615 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386f..867d4b5d8c3f184 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c404..bffd964f6aa8aa0 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551c..4c783623afc535e 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size()

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-02 Thread via cfe-commits


@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from issue #80049:
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambd

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-02 Thread Owen Pan via cfe-commits


@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from issue #80049:
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambd

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-02 Thread via cfe-commits


@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from issue #80049:
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambd

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-02-02 Thread Owen Pan via cfe-commits


@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from issue #80049:
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambd

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-31 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 01/15] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].La

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-31 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 01/14] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].La

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-31 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 01/13] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].La

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-29 Thread via cfe-commits


@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from issue #80049:
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambd

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-29 Thread Gedare Bloom via cfe-commits


@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from issue #80049:
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambd

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-28 Thread via cfe-commits


@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from issue #80049:
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambd

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-27 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 01/13] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].La

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-27 Thread via cfe-commits

https://github.com/leijurv edited 
https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-27 Thread via cfe-commits

https://github.com/leijurv edited 
https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-27 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 01/13] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].La

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-27 Thread via cfe-commits


@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from issue #80049:
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambd

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-27 Thread via cfe-commits


@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from issue #80049:
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambd

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-27 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 01/13] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].La

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-21 Thread Owen Pan via cfe-commits


@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from issue #80049:
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}",

owenca wrote:

```suggestion
  // Test from https://github.com/llvm/llvm-project/issues/80049:
  verifyFormat(
  "using type = std::remove_cv_t<\n"
  "add_common_cv_reference<\n"
  "std::common_type_t, std::decay_t>,\n"
  "T0,\n"
  "T1\n"
  ">\n"
  ">;",
  "using type = std::remove_cv_t<\n"
  "add_common_cv_reference<\n"
  "std::common_type_t, std::decay_t>,\n"
  "T0,\n"
  "T1>>;",
```

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-21 Thread Owen Pan via cfe-commits


@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from issue #80049:
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambd

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-21 Thread Owen Pan via cfe-commits


@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateCloser is turned off, the line break that it adds
+  // shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+
+  Style.BreakBeforeTemplateCloser = FormatStyle::BBTCS_BlockIndent;
+  // BreakBeforeTemplateCloser should NOT force template declarations onto
+  // multiple lines.
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template \n"
+   "void foo() {}",
+   Style);
+  // It should allow a line break, even when the typename is short.
+  // verifyNoChange is needed because the default behavior is one line.
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from issue #80049:
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambd

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-21 Thread Owen Pan via cfe-commits


@@ -11220,6 +11220,333 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateCloser) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);

owenca wrote:

```suggestion
  FormatStyle Style = getLLVMStyle();
  EXPECT_EQ(Style.BreakBeforeTemplateCloser, FormatStyle::BBTCS_Never);
```

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-19 Thread via cfe-commits

leijurv wrote:

Thank you for the review owenca, those are very reasonable changes, 
particularly on the conditions where the BreakBeforeClosingAngle gets set/used!

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-19 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 01/12] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].La

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-19 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 01/11] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].La

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-18 Thread Owen Pan via cfe-commits


@@ -280,6 +281,13 @@ struct ParenState {
   /// was a newline after the beginning left paren.
   bool BreakBeforeClosingParen : 1;
 
+  /// Whether a newline needs to be inserted before the block's closing
+  /// angle < >.
+  ///
+  /// We only want to insert a newline before the closing angle if there also
+  /// was a newline after the beginning left angle.

owenca wrote:

```suggestion
  /// Whether a newline needs to be inserted before a closing angle `>`.
```

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-18 Thread Owen Pan via cfe-commits


@@ -1371,6 +1378,11 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].LastSpace;
   }
+  if (Current.is(TT_TemplateCloser) &&
+  Style.BreakBeforeTemplateCloser != FormatStyle::BBTCS_Never &&
+  State.Stack.size() > 1) {

owenca wrote:

```suggestion
  if (Style.BreakBeforeTemplateCloser == FormatStyle::BBTCS_BlockIndent &&
  Current.is(TT_TemplateCloser) && State.Stack.size() > 1) {
```

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-18 Thread Owen Pan via cfe-commits


@@ -1235,6 +1239,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;

owenca wrote:

```suggestion
  if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener)) {
CurrentState.BreakBeforeClosingAngle =
Style.BreakBeforeTemplateCloser == FormatStyle::BBTCS_BlockIndent;
  }
```

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-18 Thread Owen Pan via cfe-commits


@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle && Current.is(TT_TemplateCloser) &&
+  Style.BreakBeforeTemplateCloser == FormatStyle::BBTCS_BlockIndent) {
+return true;
+  }

owenca wrote:

```suggestion
  if (CurrentState.BreakBeforeClosingAngle && Current.is(TT_TemplateCloser))
return true;
```
See below.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-16 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 01/11] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].La

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-13 Thread via cfe-commits

https://github.com/leijurv edited 
https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-13 Thread via cfe-commits


@@ -2252,6 +2252,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>

leijurv wrote:

No, I don't intend the `>` to be forced onto its own line. For instance, see 
this test case:

```
  verifyFormat("void foo() {\n"
   "  myFunc<\n"
   "  Lng\n"
   "  >();\n"
   "}",
   Style);
```

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-13 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 01/10] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].La

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-13 Thread via cfe-commits

leijurv wrote:

Oh gosh, that's embarrassing. It looks like I was so focused on the column 
limit that I didn't cover cases where the column limit doesn't break the 
template fully. In other words, I would just type "Fooo" 
and force it onto the next line, without noticing that a slightly shorter 
Foo would have different behavior, I apologize.

In your example, I see that `BreakBeforeTemplateCloser: Multiline, ColumnLimit: 
17` gives me:

```
template <
class A,
class B
>
class C {
  void f() {}
};
```

But `BreakBeforeTemplateCloser: Multiline, ColumnLimit: 18` gives me:

```
template 
class C {
  void f() {}
};
```

It looks to me like the problem is that when writing this code originally, I 
searched through the codebase for `FormatStyle::BAS_BlockIndent` and tried to 
replicate it. This causes the behavior here, where the `>` only goes onto the 
next line if there was a break after the matching `<`.

In other words, it seems **I was wrong** when I said `I didn't really have an 
intent in mind between your described options of BlockIndent vs Multiline but 
yes, I suppose what I have here is Multiline.` Actually, it seems like what I 
have here is BlockIndent.

So, thankfully I think I can fix this just by **renaming my option from 
Multiline to BlockIndent**, per your comment 
[here](https://github.com/llvm/llvm-project/pull/118046#discussion_r1912382882).

Additionally I have **added more tests** to cover this case where the first 
parameter can fit within the ColumnLimit on the same line as the `template <`.

https://github.com/llvm/llvm-project/pull/118046/commits/09528826ffc9f7b783d043c4447419cfd9a6ff38

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-13 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 1/9] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].Last

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-13 Thread via cfe-commits

https://github.com/mydeveloperday approved this pull request.

This looks good to me but please wait for @owenca to approve

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-13 Thread Owen Pan via cfe-commits


@@ -2252,6 +2252,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>

owenca wrote:

I was asking whether you intended to also break _after_ the `>`, effectively 
forcing it to be on its own line.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-13 Thread Owen Pan via cfe-commits

owenca wrote:

Why doesn't it break before the `>` for the example (a.cc) below?
```cpp
template 
class C {
  void f() {}
};
```
Command line:
```
clang-format -style='{BreakBeforeTemplateCloser: Multiline, ColumnLimit: 26}' 
a.cc
```

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-12 Thread via cfe-commits


@@ -2252,6 +2252,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>

leijurv wrote:

I'm doing `BreakBeforeTemplateCloser` because of [your comment 
here](https://github.com/llvm/llvm-project/pull/118046#discussion_r1912369946)

I've changed it to an enum in this commit: 
https://github.com/llvm/llvm-project/pull/118046/commits/9277a685c7a0199fff20677759d663254de9189f
 👍 

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-12 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 1/8] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].Last

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-12 Thread Owen Pan via cfe-commits


@@ -2252,6 +2252,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>

owenca wrote:

> Would `Always` look like:
> 
> ```
> template >
> ```

Yes, except that there is a space between `template` and `<` by `LLVM` default.

> So, should I change this from a true/false to an enum of Multiline/Never?

Yes. I haven't looked at your implementation yet, but are you doing 
`BreakBeforeTemplateCloser` or `TemplateCloserOnItsOwnLine`?

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread via cfe-commits

https://github.com/leijurv edited 
https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread via cfe-commits

https://github.com/leijurv edited 
https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread via cfe-commits


@@ -2252,6 +2252,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>

leijurv wrote:

Would `Always` look like:

```
template
```

For the overall indentation / line breaking of the various typenames, I left 
that untouched. All that stuff went way above my head. I didn't really have an 
intent in mind between your described options of BlockIndent vs Multiline but 
yes, I suppose what I have here is Multiline.

So, should I change this from a true/false to an enum of Multiline/Never?

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread Owen Pan via cfe-commits


@@ -2252,6 +2252,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>

owenca wrote:

> In my mind that's a bit of a different option. You can see in your examples 
> that you're assuming that the `>` goes on the next line, but that's what this 
> PR is trying to add support for.

`Always` would break before a template closer unconditionally.

> Like, your enum (which is totally reasonable) would switch between:
> 
> ```
> template <
> typename Foo, typename Bar,
> typename Baz
> >
> ```
> 
> versus
> 
> ```
> templatetypename Baz
> >
> ```
> 
> But what I'm currently trying to add support for is:
> 
> ```
> template <
> typename Foo, typename Bar,
> typename Baz
> >
> 
> templatetypename Baz
> >
> ```
> 
> versus
> 
> ```
> template <
> typename Foo, typename Bar,
> typename Baz>
> 
> templatetypename Baz>
> ```

I don't recall that you had a test case for the last pattern, but it seems that 
your current implementation is `Multiline`, which would break before the 
template closer if the template doesn't fit on one line regardless whether 
there is a break after the template opener (`BlockIndent`).

To clarify:
- BlockIndent
```
template <
typename Foo, typename Bar,
typename Baz
>

template 
```
- Multiline
```
template <
typename Foo, typename Bar,
typename Baz
>

template 
```

> So I believe that should be another patch.

Like I said, I'm ok with some of the enumerated values being implemented in 
another patch.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread via cfe-commits

leijurv wrote:

I apologize for forgetting `clang-format-check-format`

You're right that I had still missed some more cases of `verifyNoChange`. I've 
changed those now in 
https://github.com/llvm/llvm-project/pull/118046/commits/130428887e534cc3bfdfeec5846df2fd1e939667.
 The last two remaining `verifyNoChange` can't be changed to `verifyFormat`.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 1/7] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].Last

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 1/6] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].Last

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread via cfe-commits


@@ -2252,6 +2252,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>

leijurv wrote:

In my mind that's a bit of a different option. You can see in your examples 
that you're assuming that the `>` goes on the next line, but that's what this 
PR is trying to add support for.

Like, your enum (which is totally reasonable) would switch between:

```
template <
typename Foo, typename Bar,
typename Baz
>
```

versus

```
template 
```

But what I'm currently trying to add support for is:

```
template <
typename Foo, typename Bar,
typename Baz
>

template 
```

versus

```
template <
typename Foo, typename Bar,
typename Baz>

template 
```

So I believe that should be another patch.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread Owen Pan via cfe-commits

https://github.com/owenca edited 
https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread Owen Pan via cfe-commits


@@ -6,6 +6,275 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateClose) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  // Begin with tests covering the case where there is no constraint on the 
column limit.
+  Style.ColumnLimit = 0;
+  // When BreakBeforeTemplateClose is turned off, the line break that it adds 
shall be removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+  Style.BreakBeforeTemplateClose = true;
+  // BreakBeforeTemplateClose should NOT force template declarations onto 
multiple lines.
+  // Use verifyNoChange since ColumnLimit = 0.
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // It should allow a line break, even when the typename is short:
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  // It should add a line break before > if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // When within an indent scope, the > should be placed accordingly:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // Test from issue #80049:
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}",
+  Style);
+
+  // Test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // With no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+  // Or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}",
+   Style);
+
+  // Note that this is the same line (no \n):
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []("
+   "Long t) {};\n"
+   "}",
+   Style);
+
+  // Test template usage goes to nex

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread Owen Pan via cfe-commits


@@ -2252,6 +2252,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;

owenca wrote:

```suggestion
  bool BreakBeforeTemplateCloser;
```

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread Owen Pan via cfe-commits


@@ -2252,6 +2252,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>

owenca wrote:

We should make it an `enum` in order to handle more cases (now or in another 
patch), e.g.:
- Always
- BlockIndent
```
template <
typename Foo, typename Bar,
typename Baz
>
```
- Leave
- Multiline
```
template 
```
- Never

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread Owen Pan via cfe-commits

https://github.com/owenca commented:

You can run `ninja clang-format-check-format` to make sure your patch is 
correctly formatted before pushing.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread Owen Pan via cfe-commits

owenca wrote:

> > I think this should be covered by BlockIndent
> 
> My understanding from looking at past PRs to clang-format was that backwards 
> compatibility was a top requirement. If I changed the behavior of BlockIndent 
> to put the `>` on the next line, that would change a lot of existing 
> behavior/codebases/tests.

The default behavior of `AlignAfterOpenBracket` is `Align` for `LLVM` style, 
and the breaking for template angles seems to have the same default behavior. 
Unfortunately, `WebKit` style has `DontAlign` as its default. So let's keep 
this new option separate.

> > Call verifyFormat instead of verifyNoChange whenever possible.
> 
> I understand, but, I am testing the case where ColumnLimit = 0. When I call 
> `verifyFormat` it removes all the newlines. So I was unable to test the 
> behavior in the unconstrained column limit case. Note how I test that you can 
> have a `\n` after the `template<`, or not, and this option doesn't force it 
> either way.
> 
> In the later part of the tests, starting when I change the ColumnLimit to 40, 
> note that all of the tests are `verifyFormat` and I don't use 
> `verifyNoChange` anymore.

I got that as I said "whenever possible".

> I have removed a few `verifyNoChange` in my last commit.

There are still a couple of `verifyNoChange` that can be replaced with 
`verifyFormat` for your `ColumnLimit = 0` test cases, though.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff db88071a8b24ad9302659ee88383eea69a732f11 
19bc40e7d824804ebcd9839cb2155a704d368e36 --extensions cpp,h -- 
clang/include/clang/Format/Format.h clang/lib/Format/ContinuationIndenter.cpp 
clang/lib/Format/ContinuationIndenter.h clang/lib/Format/Format.cpp 
clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/ConfigParseTest.cpp 
clang/unittests/Format/FormatTest.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index cd968fc719..03581fde1c 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -8,9 +8,11 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
 
 TEST_F(FormatTest, BreakBeforeTemplateClose) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
-  // Begin with tests covering the case where there is no constraint on the 
column limit.
+  // Begin with tests covering the case where there is no constraint on the
+  // column limit.
   Style.ColumnLimit = 0;
-  // When BreakBeforeTemplateClose is turned off, the line break that it adds 
shall be removed:
+  // When BreakBeforeTemplateClose is turned off, the line break that it adds
+  // shall be removed:
   verifyFormat("template <\n"
"typename Foo,\n"
"typename Bar>\n"
@@ -11132,8 +11134,8 @@ TEST_F(FormatTest, BreakBeforeTemplateClose) {
"void foo() {}",
Style);
   Style.BreakBeforeTemplateClose = true;
-  // BreakBeforeTemplateClose should NOT force template declarations onto 
multiple lines.
-  // Use verifyNoChange since ColumnLimit = 0.
+  // BreakBeforeTemplateClose should NOT force template declarations onto
+  // multiple lines. Use verifyNoChange since ColumnLimit = 0.
   verifyNoChange("template \n"
  "void foo() {}",
  Style);

``




https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread via cfe-commits

leijurv wrote:

Thank you for the review @owenca 

> I think this should be covered by BlockIndent

My understanding from looking at past PRs to clang-format was that backwards 
compatibility was a top requirement. If I changed the behavior of BlockIndent 
to put the `>` on the next line, that would change a lot of existing 
behavior/codebases/tests.

> Call verifyFormat instead of verifyNoChange whenever possible.

I understand, but, I am testing the case where ColumnLimit = 0. When I call 
`verifyFormat` it removes all the newlines. So I was unable to test the 
behavior in the unconstrained column limit case. Note how I test that you can 
have a `\n` after the `template<`, or not, and this option doesn't force it 
either way.

In the later part of the tests, starting when I change the ColumnLimit to 40, 
note that all of the tests are `verifyFormat` and I don't use `verifyNoChange` 
anymore.

I have removed a few `verifyNoChange` in my last commit.

> Don't end a test case with a newline.
> Capitalize the first word of a comment and end the comment with a . (or : if 
> appropriate).

Sure! Did so in this commit 
https://github.com/llvm/llvm-project/pull/118046/commits/19bc40e7d824804ebcd9839cb2155a704d368e36

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-11 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 1/5] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].Last

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-10 Thread Owen Pan via cfe-commits

https://github.com/owenca commented:

About the test cases:
- Call `verifyFormat` instead of `verifyNoChange` whenever possible.
- Don't end a test case with a newline. (Search for `\n",` and `\n")`.)
- Capitalize the first word of a comment and end the comment with a `.` (or `:` 
if appropriate).

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-10 Thread Owen Pan via cfe-commits

owenca wrote:

> > Maybe we should make it a sub-option for `BlockIndent`. I'm seeing a 
> > possible need for having control over other kinds of block indented 
> > structures such as Lambdas. I suspect the way this option has been 
> > implemented it interacts with the alignment options anyway. This would be a 
> > question probably for @owenca
> 
> I thought about it some more and I don't think it would be a good idea. 
> Having a separate option seems a bit easier to handle, and allows mixing and 
> matching by users.

I think this should be covered by 
[`BlockIndent`](https://clang.llvm.org/docs/ClangFormatStyleOptions.html#alignafteropenbracket),
 which already covers both parentheses and braces. Let's hear what 
@mydeveloperday has to say.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-09 Thread via cfe-commits

leijurv wrote:

Thank you! It looks like I don't have permissions to merge, if you have them, 
could you?

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-09 Thread Björn Schäpers via cfe-commits

https://github.com/HazardyKnusperkeks approved this pull request.


https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-06 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 1/4] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].Last

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-04 Thread via cfe-commits

leijurv wrote:

Ping :pray: 

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2025-01-01 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 1/4] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].Last

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2024-12-30 Thread via cfe-commits

https://github.com/leijurv updated 
https://github.com/llvm/llvm-project/pull/118046

>From 1caf823165b16f6701993d586df51d5cdbf0885e Mon Sep 17 00:00:00 2001
From: Leijurv 
Date: Fri, 29 Nov 2024 21:54:36 -0600
Subject: [PATCH 1/4] [clang-format] Add BreakBeforeTemplateClose option

---
 clang/docs/ClangFormatStyleOptions.rst |  21 
 clang/docs/ReleaseNotes.rst|   1 +
 clang/include/clang/Format/Format.h|  20 
 clang/lib/Format/ContinuationIndenter.cpp  |  11 ++
 clang/lib/Format/ContinuationIndenter.h|  26 ++--
 clang/lib/Format/Format.cpp|   2 +
 clang/lib/Format/TokenAnnotator.cpp|   2 +-
 clang/unittests/Format/ConfigParseTest.cpp |   1 +
 clang/unittests/Format/FormatTest.cpp  | 131 +
 9 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4be448171699ca..84ab1b0a2eff61 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3416,6 +3416,27 @@ the configuration (without a prefix: ``Auto``).
 
 
 
+.. _BreakBeforeTemplateClose:
+
+**BreakBeforeTemplateClose** (``Boolean``) :versionbadge:`clang-format 20` 
:ref:`¶ `
+  If ``true``, a line break will be placed before the ``>`` in a multiline
+  template declaration.
+
+  .. code-block:: c++
+
+ true:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz
+ >
+
+ false:
+ template <
+ typename Foo,
+ typename Bar,
+ typename Baz>
+
 .. _BreakBeforeTernaryOperators:
 
 **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..867d4b5d8c3f18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -976,6 +976,7 @@ clang-format
   ``Never``, and ``true`` to ``Always``.
 - Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
 - Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style.
+- Adds ``BreakBeforeTemplateClose`` option.
 
 libclang
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 6383934afa2c40..bffd964f6aa8aa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2248,6 +2248,25 @@ struct FormatStyle {
   /// \version 16
   BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
 
+  /// If ``true``, a line break will be placed before the ``>`` in a multiline
+  /// template declaration.
+  /// \code
+  ///true:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz
+  ///>
+  ///
+  ///false:
+  ///template <
+  ///typename Foo,
+  ///typename Bar,
+  ///typename Baz>
+  /// \endcode
+  /// \version 20
+  bool BreakBeforeTemplateClose;
+
   /// If ``true``, ternary operators will be placed after line breaks.
   /// \code
   ///true:
@@ -5184,6 +5203,7 @@ struct FormatStyle {
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations 
&&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
+   BreakBeforeTemplateClose == R.BreakBeforeTemplateClose &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index aed86c1fb99551..4c783623afc535 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -406,6 +406,10 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
 return true;
+  if (CurrentState.BreakBeforeClosingAngle &&
+  Current.ClosesTemplateDeclaration && Style.BreakBeforeTemplateClose) {
+return true;
+  }
   if (Style.Language == FormatStyle::LK_ObjC &&
   Style.ObjCBreakBeforeNestedBlockParam &&
   Current.ObjCSelectorNameParts > 1 &&
@@ -1234,6 +1238,9 @@ unsigned 
ContinuationIndenter::addTokenOnNewLine(LineState &State,
 Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent;
   }
 
+  if (PreviousNonComment && PreviousNonComment->is(tok::less))
+CurrentState.BreakBeforeClosingAngle = true;
+
   if (CurrentState.AvoidBinPacking) {
 // If we are breaking after '(', '{', '<', or this is the break after a ':'
 // to start a member initializer list in a constructor, this should not
@@ -1370,6 +1377,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const 
LineState &State) {
   State.Stack.size() > 1) {
 return State.Stack[State.Stack.size() - 2].Last

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2024-12-25 Thread via cfe-commits


@@ -11077,6 +11077,281 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateClose) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  Style.ColumnLimit = 0;
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar>\n"
+ "void foo() {}",
+ Style);
+  // when BreakBeforeTemplateClose is off, this line break is removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+  Style.BreakBeforeTemplateClose = true;
+  // BreakBeforeTemplateClose should NOT force multiline templates
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // it should allow a line break:
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  // it should add a line break if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // when within an indent scope, the > should be placed appropriately:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // test from issue #80049
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}\n",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}\n",
+  Style);
+
+  // test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}\n",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}\n",
+   Style);
+  // with no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}\n",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}\n",
+   Style);
+  // or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}\n",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}\n",
+   Style);
+
+  // same line with no column limit
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []("
+   "Long t) {};\n"
+   "}\n",
+   Sty

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2024-12-25 Thread via cfe-commits


@@ -11077,6 +11077,281 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateClose) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  Style.ColumnLimit = 0;
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar>\n"
+ "void foo() {}",
+ Style);
+  // when BreakBeforeTemplateClose is off, this line break is removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+  Style.BreakBeforeTemplateClose = true;
+  // BreakBeforeTemplateClose should NOT force multiline templates
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // it should allow a line break:
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  // it should add a line break if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // when within an indent scope, the > should be placed appropriately:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // test from issue #80049
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}\n",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}\n",
+  Style);
+
+  // test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}\n",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}\n",
+   Style);
+  // with no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}\n",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}\n",
+   Style);
+  // or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}\n",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}\n",
+   Style);
+
+  // same line with no column limit
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []("
+   "Long t) {};\n"
+   "}\n",
+   Sty

[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2024-12-25 Thread Björn Schäpers via cfe-commits


@@ -11077,6 +11077,221 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateClose) {

HazardyKnusperkeks wrote:

Sorry missed that, didn't look for the lambda case.

https://github.com/llvm/llvm-project/pull/118046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Add BreakBeforeTemplateClose option (PR #118046)

2024-12-25 Thread Björn Schäpers via cfe-commits


@@ -11077,6 +11077,281 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
   Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateClose) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  Style.ColumnLimit = 0;
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar>\n"
+ "void foo() {}",
+ Style);
+  // when BreakBeforeTemplateClose is off, this line break is removed:
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   Style);
+  Style.BreakBeforeTemplateClose = true;
+  // BreakBeforeTemplateClose should NOT force multiline templates
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template \n"
+ "void foo() {}",
+ Style);
+  // it should allow a line break:
+  verifyNoChange("template <\n"
+ "typename Foo\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  verifyNoChange("template <\n"
+ "typename Foo,\n"
+ "typename Bar\n"
+ ">\n"
+ "void foo() {}",
+ Style);
+  // it should add a line break if not already present:
+  verifyFormat("template <\n"
+   "typename Foo\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo>\n"
+   "void foo() {}",
+   Style);
+  verifyFormat("template <\n"
+   "typename Foo,\n"
+   "typename Bar\n"
+   ">\n"
+   "void foo() {}",
+   "template <\n"
+   "typename Foo,\n"
+   "typename Bar>\n"
+   "void foo() {}",
+   Style);
+  // when within an indent scope, the > should be placed appropriately:
+  verifyFormat("struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar\n"
+   "  >\n"
+   "  void foo() {}\n"
+   "};",
+   "struct Baz {\n"
+   "  template <\n"
+   "  typename Foo,\n"
+   "  typename Bar>\n"
+   "  void foo() {}\n"
+   "};",
+   Style);
+
+  // test from issue #80049
+  verifyFormat(
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1\n"
+  "  >\n"
+  "  >;\n"
+  "}\n",
+  "void foo() {\n"
+  "  using type = std::remove_cv_t<\n"
+  "  add_common_cv_reference<\n"
+  "  std::common_type_t, std::decay_t>,\n"
+  "  T0,\n"
+  "  T1>>;\n"
+  "}\n",
+  Style);
+
+  // test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}\n",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T>(T t){\n"
+   "  };\n"
+   "}\n",
+   Style);
+  // with no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T, typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}\n",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T, typename Foo>(T t){\n"
+   "  };\n"
+   "}\n",
+   Style);
+  // or on different lines:
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []<\n"
+   "typename T,\n"
+   "typename Foo\n"
+   ">(T t) {\n"
+   "  };\n"
+   "}\n",
+   "void foo() {\n"
+   "  auto lambda = []<\n"
+   "  typename T,\n"
+   "  typename Foo>(T t){\n"
+   "  };\n"
+   "}\n",
+   Style);
+
+  // same line with no column limit
+  verifyFormat("void foo() {\n"
+   "  auto lambda = []("
+   "Long t) {};\n"
+   "}\n",
+   Sty

  1   2   >