MyDeveloperDay created this revision. MyDeveloperDay added reviewers: krasimir, JakeMerdichAMD, mitchell-stellar. MyDeveloperDay added projects: clang, clang-format.
https://bugs.llvm.org/show_bug.cgi?id=46159 Linux Kernel code using is try as a variable name (as its 'C' code they can), they interpreted as the 'try' keyword by clang-format causing odd formatting (see below) We have no specific 'C' code handling, as this code could easily be in a '.h' file so need to handle this not based on extension alone. This revision adds a FormatTokenLexer rule to identify either try blocks "try {" or function try block "try :" and if not, rename the "try" token to be an identifier static size_t get_kcore_size(int *nphdr, size_t *phdrs_len, size_t *notes_len, size_t *data_offset) { size_t try, size; struct kcore_list *m; *nphdr = 1; /* PT_NOTE */ size = 0; list_for_each_entry(m, &kclist_head, list) { try = kc_vaddr_to_offset((size_t)m->addr + m->size); if (try1 > size) size = try1; *nphdr = *nphdr + 1; } } clang-format-10 formats it as: static size_t get_kcore_size(int *nphdr, size_t *phdrs_len, size_t *notes_len, size_t *data_offset) { size_t try , size; struct kcore_list *m; *nphdr = 1; /* PT_NOTE */ size = 0; list_for_each_entry(m, &kclist_head, list) { try = kc_vaddr_to_offset((size_t)m->addr + m->size); if (try > size) size = try ; *nphdr = *nphdr + 1; } } Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D80940 Files: clang/lib/Format/FormatTokenLexer.cpp clang/lib/Format/FormatTokenLexer.h clang/unittests/Format/FormatTest.cpp Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -2664,6 +2664,18 @@ verifyIncompleteFormat("try {} catch ("); } +TEST_F(FormatTest, FormatTryAsAVariable) { + verifyFormat("int try;"); + verifyFormat("int try, size;"); + verifyFormat("try = foo();"); + verifyFormat("if (try < size) {\n return true;\n}"); + + verifyFormat("int catch;"); + verifyFormat("int catch, size;"); + verifyFormat("catch = foo();"); + verifyFormat("if (catch < size) {\n return true;\n}"); +} + TEST_F(FormatTest, FormatSEHTryCatch) { verifyFormat("__try {\n" " int a = b * c;\n" Index: clang/lib/Format/FormatTokenLexer.h =================================================================== --- clang/lib/Format/FormatTokenLexer.h +++ clang/lib/Format/FormatTokenLexer.h @@ -56,6 +56,7 @@ bool tryMergeCSharpNullConditional(); bool tryTransformCSharpForEach(); bool tryMergeForEach(); + bool tryTransformTryUsageForC(); bool tryMergeTokens(ArrayRef<tok::TokenKind> Kinds, TokenType NewType); Index: clang/lib/Format/FormatTokenLexer.cpp =================================================================== --- clang/lib/Format/FormatTokenLexer.cpp +++ clang/lib/Format/FormatTokenLexer.cpp @@ -76,6 +76,8 @@ return; if (tryMergeForEach()) return; + if (Style.isCpp() && tryTransformTryUsageForC()) + return; if (Style.isCSharp()) { if (tryMergeCSharpKeywordVariables()) @@ -383,6 +385,26 @@ return true; } +bool FormatTokenLexer::tryTransformTryUsageForC() { + if (Tokens.size() < 2) + return false; + auto &Try = *(Tokens.end() - 2); + auto &Brace = *(Tokens.end() - 1); + if (!Try->is(tok::kw_try)) + return false; + if (Brace->isOneOf(tok::l_brace, tok::colon)) + return false; + + if (Tokens.size() > 2) { + auto &At = *(Tokens.end() - 3); + if (At->is(tok::at)) + return false; + } + + Try->Tok.setKind(tok::identifier); + return true; +} + bool FormatTokenLexer::tryMergeLessLess() { // Merge X,less,less,Y into X,lessless,Y unless X or Y is less. if (Tokens.size() < 3)
Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -2664,6 +2664,18 @@ verifyIncompleteFormat("try {} catch ("); } +TEST_F(FormatTest, FormatTryAsAVariable) { + verifyFormat("int try;"); + verifyFormat("int try, size;"); + verifyFormat("try = foo();"); + verifyFormat("if (try < size) {\n return true;\n}"); + + verifyFormat("int catch;"); + verifyFormat("int catch, size;"); + verifyFormat("catch = foo();"); + verifyFormat("if (catch < size) {\n return true;\n}"); +} + TEST_F(FormatTest, FormatSEHTryCatch) { verifyFormat("__try {\n" " int a = b * c;\n" Index: clang/lib/Format/FormatTokenLexer.h =================================================================== --- clang/lib/Format/FormatTokenLexer.h +++ clang/lib/Format/FormatTokenLexer.h @@ -56,6 +56,7 @@ bool tryMergeCSharpNullConditional(); bool tryTransformCSharpForEach(); bool tryMergeForEach(); + bool tryTransformTryUsageForC(); bool tryMergeTokens(ArrayRef<tok::TokenKind> Kinds, TokenType NewType); Index: clang/lib/Format/FormatTokenLexer.cpp =================================================================== --- clang/lib/Format/FormatTokenLexer.cpp +++ clang/lib/Format/FormatTokenLexer.cpp @@ -76,6 +76,8 @@ return; if (tryMergeForEach()) return; + if (Style.isCpp() && tryTransformTryUsageForC()) + return; if (Style.isCSharp()) { if (tryMergeCSharpKeywordVariables()) @@ -383,6 +385,26 @@ return true; } +bool FormatTokenLexer::tryTransformTryUsageForC() { + if (Tokens.size() < 2) + return false; + auto &Try = *(Tokens.end() - 2); + auto &Brace = *(Tokens.end() - 1); + if (!Try->is(tok::kw_try)) + return false; + if (Brace->isOneOf(tok::l_brace, tok::colon)) + return false; + + if (Tokens.size() > 2) { + auto &At = *(Tokens.end() - 3); + if (At->is(tok::at)) + return false; + } + + Try->Tok.setKind(tok::identifier); + return true; +} + bool FormatTokenLexer::tryMergeLessLess() { // Merge X,less,less,Y into X,lessless,Y unless X or Y is less. if (Tokens.size() < 3)
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits