MyDeveloperDay updated this revision to Diff 266204. MyDeveloperDay added a comment.
Handle more complex nested ObjC calls Rename function to tryParseSimpleAttributes (not supporting full capability as yet) Use RAII object to reset the TokenPosition utilize the fact that Objective calls shouldn't end with "]]" I think... this should allow Attributes at least of the form `[[identifier::identifier]]` I feel if this isn't a good enough perhaps we also check for the `;` after the second `]` 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,23 @@ " }]"); } +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)\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,47 @@ // "} 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 AutoTokenPosition { + unsigned StoredPosition; + FormatTokenSource *Tokens; + +public: + AutoTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) { + assert(Tokens && "Tokens expected to not be null"); + StoredPosition = Tokens->getPosition(); + } + + ~AutoTokenPosition() { 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() { + AutoTokenPosition 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; + } + 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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits