modocache created this revision.
modocache added reviewers: rsmith, sammccall, Typz, klimek.
Herald added a subscriber: EricWF.
Herald added a project: clang.
In a previous change, https://reviews.llvm.org/D65043, I allowed users to
explicitly opt-in to formatting according to the C++20 standard. Should
a user choose to do so, the formatter would treat coroutine keywords
such as `co_yield` as keywords, whereas under the C++11 standard they
would be treated as identifiers.
However, this excludes a use case in which, for example, a user's codebase
is written using the C++17 standard, but with an explicit opt-in to
`-fcoroutines-ts`. This commit adds an option to clang-format to allow
formatting under an arbitrary standard, but with `co_yield` and friends
treated as keywords.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D65044
Files:
clang/docs/ClangFormatStyleOptions.rst
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/unittests/Format/FormatTest.cpp
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -13810,13 +13810,17 @@
TEST_F(FormatTest, Coroutines) {
FormatStyle Cpp20 = getLLVMStyle();
Cpp20.Standard = FormatStyle::LS_Cpp20;
+ FormatStyle Coro = getLLVMStyle();
+ Coro.CoroutinesTS = true;
verifyFormat("co_yield++ i;");
verifyFormat("co_yield ++i;", Cpp20);
+ verifyFormat("co_yield ++i;", Coro);
verifyFormat("co_await[]() { co_return; }\n"
"();");
verifyFormat("co_await []() { co_return; }();", Cpp20);
+ verifyFormat("co_await []() { co_return; }();", Coro);
}
} // end namespace
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -434,6 +434,7 @@
IO.mapOptional("ConstructorInitializerIndentWidth",
Style.ConstructorInitializerIndentWidth);
IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth);
+IO.mapOptional("CoroutinesTS", Style.CoroutinesTS);
IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment);
IO.mapOptional("DisableFormat", Style.DisableFormat);
@@ -701,6 +702,7 @@
LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
LLVMStyle.ConstructorInitializerIndentWidth = 4;
LLVMStyle.ContinuationIndentWidth = 4;
+ LLVMStyle.CoroutinesTS = false;
LLVMStyle.Cpp11BracedListStyle = true;
LLVMStyle.DerivePointerAlignment = false;
LLVMStyle.ExperimentalAutoDetectBinPacking = false;
@@ -2378,6 +2380,8 @@
LangOpts.ObjC = 1;
LangOpts.MicrosoftExt = 1;// To get kw___try, kw___finally.
LangOpts.DeclSpecKeyword = 1; // To get __declspec.
+ if (!LangOpts.CPlusPlus2a)
+LangOpts.Coroutines = Style.CoroutinesTS;
return LangOpts;
}
Index: clang/include/clang/Format/Format.h
===
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -,6 +,21 @@
/// \endcode
unsigned ContinuationIndentWidth;
+ /// If ``true``, C++ Coroutines TS keywords will be treated as keywords, not
+ /// identifiers, regardless of the language standard specified for formatting.
+ /// If ``false``, their formatting depends on the standard selected.
+ /// \code
+ ///true, C++11:
+ ///co_yield ++i;
+ ///
+ ///false, C++11:
+ ///co_yield++ i;
+ ///
+ ///both true and false, C++20:
+ ///co_yield ++i;
+ /// \endcode
+ bool CoroutinesTS;
+
/// If ``true``, format braced lists as best suited for C++11 braced
/// lists.
///
@@ -1949,6 +1964,7 @@
ConstructorInitializerIndentWidth ==
R.ConstructorInitializerIndentWidth &&
ContinuationIndentWidth == R.ContinuationIndentWidth &&
+ CoroutinesTS == R.CoroutinesTS &&
Cpp11BracedListStyle == R.Cpp11BracedListStyle &&
DerivePointerAlignment == R.DerivePointerAlignment &&
DisableFormat == R.DisableFormat &&
Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -1315,6 +1315,22 @@
longFunction( // Again a long comment
arg);
+**CoroutinesTS** (``bool``)
+ If ``true``, C++ Coroutines TS keywords will be treated as keywords, not
+ identifiers, regardless of the language standard specified for formatting.
+ If ``false``, their formatting depends on the standard selected.
+
+ .. code-block:: c++
+
+ true, C++11:
+ co_yield ++i;
+
+ false, C++11:
+ co_yield++ i;
+
+ both true and false, C++20:
+ co_yield ++i;
+