This revision was automatically updated to reflect the committed changes.
Closed by commit rG8f1156a7d004: [clang-format] Fix an ObjC regression
introduced with new [[likely]]… (authored by MyDeveloperDay).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D80547/new/
https://reviews.llvm.org/D80547
Files:
clang/lib/Format/UnwrappedLineParser.cpp
clang/lib/Format/UnwrappedLineParser.h
clang/unittests/Format/FormatTest.cpp
clang/unittests/Format/FormatTestObjC.cpp
Index: clang/unittests/Format/FormatTestObjC.cpp
===================================================================
--- clang/unittests/Format/FormatTestObjC.cpp
+++ clang/unittests/Format/FormatTestObjC.cpp
@@ -1434,6 +1434,25 @@
" }]");
}
+TEST_F(FormatTestObjC, IfNotUnlikely) {
+ Style = getGoogleStyle(FormatStyle::LK_ObjC);
+
+ verifyFormat("if (argc < 5) [obj func:arg];");
+ verifyFormat("if (argc < 5) [[obj1 method1:arg1] method2:arg2];");
+ verifyFormat("if (argc < 5) [[foo bar] baz:i[0]];");
+ verifyFormat("if (argc < 5) [[foo bar] baz:i[0]][1];");
+
+ verifyFormat("if (argc < 5)\n"
+ " [obj func:arg];\n"
+ "else\n"
+ " [obj func:arg2];");
+
+ verifyFormat("if (argc < 5) [[unlikely]]\n"
+ " [obj func:arg];\n"
+ "else [[likely]]\n"
+ " [obj func:arg2];");
+}
+
} // end namespace
} // end namespace format
} // end namespace clang
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -16513,6 +16513,11 @@
" return 42;\n"
"}\n",
Style);
+
+ verifyFormat("if (argc > 5) [[gnu::unused]] {\n"
+ " return 29;\n"
+ "}",
+ Style);
}
TEST_F(FormatTest, LLVMDefaultStyle) {
Index: clang/lib/Format/UnwrappedLineParser.h
===================================================================
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -134,6 +134,7 @@
bool tryToParseLambdaIntroducer();
bool tryToParsePropertyAccessor();
void tryToParseJSFunction();
+ bool tryToParseSimpleAttribute();
void addUnwrappedLine();
bool eof() const;
// LevelDifference is the difference of levels after and before the current
Index: clang/lib/Format/UnwrappedLineParser.cpp
===================================================================
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1962,7 +1962,7 @@
if (FormatTok->Tok.is(tok::l_paren))
parseParens();
// handle [[likely]] / [[unlikely]]
- if (FormatTok->is(tok::l_square))
+ if (FormatTok->is(tok::l_square) && tryToParseSimpleAttribute())
parseSquare();
bool NeedsUnwrappedLine = false;
if (FormatTok->Tok.is(tok::l_brace)) {
@@ -1981,7 +1981,7 @@
if (FormatTok->Tok.is(tok::kw_else)) {
nextToken();
// handle [[likely]] / [[unlikely]]
- if (FormatTok->is(tok::l_square))
+ if (FormatTok->Tok.is(tok::l_square) && tryToParseSimpleAttribute())
parseSquare();
if (FormatTok->Tok.is(tok::l_brace)) {
CompoundStatementIndenter Indenter(this, Style, Line->Level);
@@ -2343,6 +2343,51 @@
// "} n, m;" will end up in one unwrapped line.
}
+namespace {
+// A class used to set and restore the Token position when peeking
+// ahead in the token source.
+class ScopedTokenPosition {
+ unsigned StoredPosition;
+ FormatTokenSource *Tokens;
+
+public:
+ ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
+ assert(Tokens && "Tokens expected to not be null");
+ StoredPosition = Tokens->getPosition();
+ }
+
+ ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
+};
+} // namespace
+
+// Look to see if we have [[ by looking ahead, if
+// its not then rewind to the original position.
+bool UnwrappedLineParser::tryToParseSimpleAttribute() {
+ ScopedTokenPosition AutoPosition(Tokens);
+ FormatToken *Tok = Tokens->getNextToken();
+ // We already read the first [ check for the second.
+ if (Tok && !Tok->is(tok::l_square)) {
+ return false;
+ }
+ // Double check that the attribute is just something
+ // fairly simple.
+ while (Tok) {
+ if (Tok->is(tok::r_square)) {
+ break;
+ }
+ Tok = Tokens->getNextToken();
+ }
+ Tok = Tokens->getNextToken();
+ if (Tok && !Tok->is(tok::r_square)) {
+ return false;
+ }
+ Tok = Tokens->getNextToken();
+ if (Tok && Tok->is(tok::semi)) {
+ return false;
+ }
+ return true;
+}
+
void UnwrappedLineParser::parseJavaEnumBody() {
// Determine whether the enum is simple, i.e. does not have a semicolon or
// constants with class bodies. Simple enums can be formatted like braced
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits