Author: mydeveloperday Date: 2020-05-20T07:44:36+01:00 New Revision: cc918e90c048c6c9a59ed08e7b2a2f92b4ac8140
URL: https://github.com/llvm/llvm-project/commit/cc918e90c048c6c9a59ed08e7b2a2f92b4ac8140 DIFF: https://github.com/llvm/llvm-project/commit/cc918e90c048c6c9a59ed08e7b2a2f92b4ac8140.diff LOG: [clang-format] [PR33890] Add support for Microsoft C++/CLI non standard for each looping extension Summary: https://bugs.llvm.org/show_bug.cgi?id=33890 This revision allow the microsoft `for each(.... in ...` nonstandard C++ extension which can be used in C++/CLI to be handled as a ForEach macro. This prevents the breaking between the for and each onto a new line Reviewed By: JakeMerdichAMD Subscribers: cfe-commits Tags: #clang, #clang-format Differential Revision: https://reviews.llvm.org/D80228 Added: Modified: clang/lib/Format/FormatTokenLexer.cpp clang/lib/Format/FormatTokenLexer.h clang/unittests/Format/FormatTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index 249d3ac39c3e..b6cbebdcbe7f 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -74,6 +74,8 @@ void FormatTokenLexer::tryMergePreviousTokens() { return; if (tryMergeLessLess()) return; + if (tryMergeForEach()) + return; if (Style.isCSharp()) { if (tryMergeCSharpKeywordVariables()) @@ -359,6 +361,28 @@ bool FormatTokenLexer::tryTransformCSharpForEach() { return true; } +bool FormatTokenLexer::tryMergeForEach() { + if (Tokens.size() < 2) + return false; + auto &For = *(Tokens.end() - 2); + auto &Each = *(Tokens.end() - 1); + if (!For->is(tok::kw_for)) + return false; + if (!Each->is(tok::identifier)) + return false; + if (Each->TokenText != "each") + return false; + + For->setType(TT_ForEachMacro); + For->Tok.setKind(tok::kw_for); + + For->TokenText = StringRef(For->TokenText.begin(), + Each->TokenText.end() - For->TokenText.begin()); + For->ColumnWidth += Each->ColumnWidth; + Tokens.erase(Tokens.end() - 1); + return true; +} + bool FormatTokenLexer::tryMergeLessLess() { // Merge X,less,less,Y into X,lessless,Y unless X or Y is less. if (Tokens.size() < 3) diff --git a/clang/lib/Format/FormatTokenLexer.h b/clang/lib/Format/FormatTokenLexer.h index 192e26a10d4a..be11020270a3 100644 --- a/clang/lib/Format/FormatTokenLexer.h +++ b/clang/lib/Format/FormatTokenLexer.h @@ -55,6 +55,7 @@ class FormatTokenLexer { bool tryMergeCSharpDoubleQuestion(); bool tryMergeCSharpNullConditional(); bool tryTransformCSharpForEach(); + bool tryMergeForEach(); bool tryMergeTokens(ArrayRef<tok::TokenKind> Kinds, TokenType NewType); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 9f1b88bf6a6f..dada02e5841c 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -994,6 +994,9 @@ TEST_F(FormatTest, ForEachLoops) { "#define Q_FOREACH (x, y)\n" "#define BOOST_FOREACH (x, y)\n" "#define UNKNOWN_FOREACH (x, y)\n"); + + // handle microsoft non standard extension + verifyFormat("for each (char c in x->MyStringProperty)"); } TEST_F(FormatTest, FormatsWhileLoop) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits