modocache updated this revision to Diff 213360.
modocache added a comment.

Thanks for the reviews, @sammccall, @Quuxplusone, and @MyDeveloperDay. I added 
C++14 and C++17 options. In an earlier comment I mentioned splitting this work 
up into a series of commits, but it ended up being a smaller set of changes 
than I thought, so I'll just update this diff with all of the changes. What do 
you all think?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D65043

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -3794,10 +3794,13 @@
       "if (aaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaa(\n"
       "        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) {\n"
       "}");
+
+  FormatStyle Cpp2a = getLLVMStyle();
+  Cpp2a.Standard = FormatStyle::LS_Cpp2a;
   verifyFormat(
       "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
       "        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) <=> 5) {\n"
-      "}");
+      "}", Cpp2a);
   // Even explicit parentheses stress the precedence enough to make the
   // additional break unnecessary.
   verifyFormat("if ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n"
@@ -3820,7 +3823,7 @@
   verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n"
                "        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa <=>\n"
                "    5) {\n"
-               "}");
+               "}", Cpp2a);
 
   FormatStyle OnePerLine = getLLVMStyle();
   OnePerLine.BinPackParameters = false;
@@ -11830,8 +11833,14 @@
   Style.Standard = FormatStyle::LS_Auto;
   CHECK_PARSE("Standard: Cpp03", Standard, FormatStyle::LS_Cpp03);
   CHECK_PARSE("Standard: Cpp11", Standard, FormatStyle::LS_Cpp11);
+  CHECK_PARSE("Standard: Cpp14", Standard, FormatStyle::LS_Cpp14);
+  CHECK_PARSE("Standard: Cpp17", Standard, FormatStyle::LS_Cpp17);
+  CHECK_PARSE("Standard: Cpp2a", Standard, FormatStyle::LS_Cpp2a);
   CHECK_PARSE("Standard: C++03", Standard, FormatStyle::LS_Cpp03);
   CHECK_PARSE("Standard: C++11", Standard, FormatStyle::LS_Cpp11);
+  CHECK_PARSE("Standard: C++14", Standard, FormatStyle::LS_Cpp14);
+  CHECK_PARSE("Standard: C++17", Standard, FormatStyle::LS_Cpp17);
+  CHECK_PARSE("Standard: C++2a", Standard, FormatStyle::LS_Cpp2a);
   CHECK_PARSE("Standard: Auto", Standard, FormatStyle::LS_Auto);
 
   Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
@@ -13761,6 +13770,19 @@
   verifyFormat("auto const &[ a, b ] = f();", Spaces);
 }
 
+TEST_F(FormatTest, Coroutines) {
+  FormatStyle Cpp2a = getLLVMStyle();
+  Cpp2a.Standard = FormatStyle::LS_Cpp2a;
+
+  // 'co_yield' is treated as an identifier in standards below C++2a, and so
+  // the increment is interpreted as a postfix on that identifier.
+  // In C++2a, it is interpreted as a prefix increment on 'i'.
+  verifyFormat("co_yield++ i;");
+  verifyFormat("co_yield ++i;", Cpp2a);
+
+  verifyFormat("co_await []() { co_return; }();", Cpp2a);
+}
+
 TEST_F(FormatTest, FileAndCode) {
   EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.cc", ""));
   EXPECT_EQ(FormatStyle::LK_ObjC, guessLanguage("foo.m", ""));
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2860,7 +2860,7 @@
         (Style.Language == FormatStyle::LK_Proto && Left.is(TT_DictLiteral)))
       return !Style.Cpp11BracedListStyle;
     return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
-           (Style.Standard < FormatStyle::LS_Cpp11 || Style.SpacesInAngles);
+           (Style.Standard == FormatStyle::LS_Cpp03 || Style.SpacesInAngles);
   }
   if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
       Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
@@ -2879,7 +2879,7 @@
     return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd();
   if (Right.is(tok::coloncolon) && !Left.isOneOf(tok::l_brace, tok::comment))
     return (Left.is(TT_TemplateOpener) &&
-            Style.Standard < FormatStyle::LS_Cpp11) ||
+            Style.Standard == FormatStyle::LS_Cpp03) ||
            !(Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
                           tok::kw___super, TT_TemplateCloser,
                           TT_TemplateOpener)) ||
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -71,6 +71,12 @@
     IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03);
     IO.enumCase(Value, "Cpp11", FormatStyle::LS_Cpp11);
     IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11);
+    IO.enumCase(Value, "Cpp14", FormatStyle::LS_Cpp14);
+    IO.enumCase(Value, "C++14", FormatStyle::LS_Cpp14);
+    IO.enumCase(Value, "Cpp17", FormatStyle::LS_Cpp17);
+    IO.enumCase(Value, "C++17", FormatStyle::LS_Cpp17);
+    IO.enumCase(Value, "Cpp2a", FormatStyle::LS_Cpp2a);
+    IO.enumCase(Value, "C++2a", FormatStyle::LS_Cpp2a);
     IO.enumCase(Value, "Auto", FormatStyle::LS_Auto);
   }
 };
@@ -2370,10 +2376,15 @@
       Style.Standard == FormatStyle::LS_Auto ? FormatStyle::LS_Cpp11
                                              : Style.Standard;
   LangOpts.CPlusPlus = 1;
+  // N.B.: For many years clang-format provided the option LS_Cpp11 to mean
+  //       "a modern C++ standard" or "a standard newer than C++03". As a
+  //       result, many users may still be using LS_Cpp11, and they expect
+  //       formatting to occur as if they were using C++14 or C++17. So for
+  //       now, we enable all C++14 and C++17 features for those users.
   LangOpts.CPlusPlus11 = LexingStd >= FormatStyle::LS_Cpp11;
   LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp11;
   LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp11;
-  LangOpts.CPlusPlus2a = LexingStd >= FormatStyle::LS_Cpp11;
+  LangOpts.CPlusPlus2a = LexingStd >= FormatStyle::LS_Cpp2a;
   LangOpts.LineComment = 1;
   bool AlternativeOperators = Style.isCpp();
   LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0;
Index: clang/include/clang/Format/Format.h
===================================================================
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -1872,9 +1872,16 @@
   enum LanguageStandard {
     /// Use C++03-compatible syntax.
     LS_Cpp03,
-    /// Use features of C++11, C++14 and C++1z (e.g. ``A<A<int>>`` instead of
-    /// ``A<A<int> >``).
+    /// Use C++11-compatible syntax. For backwards-compatibility with older
+    /// versions of clang-format, this option implies C++14- and
+    /// C++17-compatible syntax as well.
     LS_Cpp11,
+    /// Use C++14-compatible syntax.
+    LS_Cpp14,
+    /// Use C++17-compatible syntax.
+    LS_Cpp17,
+    /// Use C++2a-compatible syntax.
+    LS_Cpp2a,
     /// Automatic detection based on the input.
     LS_Auto
   };
Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -2220,8 +2220,18 @@
     Use C++03-compatible syntax.
 
   * ``LS_Cpp11`` (in configuration: ``Cpp11``)
-    Use features of C++11, C++14 and C++1z (e.g. ``A<A<int>>`` instead of
-    ``A<A<int> >``).
+    Use C++11-compatible syntax. For backwards-compatibility with older
+    versions of clang-format, this option implies C++14- and C++17-compatible
+    syntax as well.
+
+  * ``LS_Cpp14`` (in configuration: ``Cpp14``)
+    Use C++14-compatible syntax.
+
+  * ``LS_Cpp17`` (in configuration: ``Cpp17``)
+    Use C++17-compatible syntax.
+
+  * ``LS_Cpp2a`` (in configuration: ``Cpp2a``)
+    Use C++2a-compatible syntax.
 
   * ``LS_Auto`` (in configuration: ``Auto``)
     Automatic detection based on the input.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to