Author: alexfh Date: Tue Apr 9 11:15:19 2013 New Revision: 179099 URL: http://llvm.org/viewvc/llvm-project?rev=179099&view=rev Log: Again macros without trailing semicolons: don't care about declaration context.
Summary: Some codebases use these kinds of macros in functions, e.g. Chromium's IPC_BEGIN_MESSAGE_MAP, IPC_BEGIN_MESSAGE_HANDLER, etc. Reviewers: djasper, klimek Reviewed By: klimek CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D645 Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=179099&r1=179098&r2=179099&view=diff ============================================================================== --- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original) +++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Tue Apr 9 11:15:19 2013 @@ -260,6 +260,33 @@ void UnwrappedLineParser::parsePPUnknown addUnwrappedLine(); } +// Here we blacklist certain tokens that are not usually the first token in an +// unwrapped line. This is used in attempt to distinguish macro calls without +// trailing semicolons from other constructs split to several lines. +bool tokenCanStartNewLine(clang::Token Tok) { + // Semicolon can be a null-statement, l_square can be a start of a macro or + // a C++11 attribute, but this doesn't seem to be common. + return Tok.isNot(tok::semi) && Tok.isNot(tok::l_brace) && + Tok.isNot(tok::l_square) && + // Tokens that can only be used as binary operators and a part of + // overloaded operator names. + Tok.isNot(tok::period) && Tok.isNot(tok::periodstar) && + Tok.isNot(tok::arrow) && Tok.isNot(tok::arrowstar) && + Tok.isNot(tok::less) && Tok.isNot(tok::greater) && + Tok.isNot(tok::slash) && Tok.isNot(tok::percent) && + Tok.isNot(tok::lessless) && Tok.isNot(tok::greatergreater) && + Tok.isNot(tok::equal) && Tok.isNot(tok::plusequal) && + Tok.isNot(tok::minusequal) && Tok.isNot(tok::starequal) && + Tok.isNot(tok::slashequal) && Tok.isNot(tok::percentequal) && + Tok.isNot(tok::ampequal) && Tok.isNot(tok::pipeequal) && + Tok.isNot(tok::caretequal) && Tok.isNot(tok::greatergreaterequal) && + Tok.isNot(tok::lesslessequal) && + // Colon is used in labels, base class lists, initializer lists, + // range-based for loops, ternary operator, but should never be the + // first token in an unwrapped line. + Tok.isNot(tok::colon); +} + void UnwrappedLineParser::parseStructuralElement() { assert(!FormatTok.Tok.is(tok::l_brace)); switch (FormatTok.Tok.getKind()) { @@ -386,11 +413,11 @@ void UnwrappedLineParser::parseStructura parseLabel(); return; } - // Recognize function-like macro usages without trailing semicolon in - // declaration context. + // Recognize function-like macro usages without trailing semicolon. if (FormatTok.Tok.is(tok::l_paren)) { parseParens(); - if (Line->MustBeDeclaration && FormatTok.HasUnescapedNewline) { + if (FormatTok.HasUnescapedNewline && + tokenCanStartNewLine(FormatTok.Tok)) { addUnwrappedLine(); return; } Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=179099&r1=179098&r2=179099&view=diff ============================================================================== --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Tue Apr 9 11:15:19 2013 @@ -1353,6 +1353,99 @@ TEST_F(FormatTest, MacroCallsWithoutTrai " class X {};\n" " INITIALIZE_PASS_END(ScopDetection, \"polly-detect\")\n" " int *createScopDetectionPass() { return 0; }")); + // FIXME: We could probably treat IPC_BEGIN_MESSAGE_MAP/IPC_END_MESSAGE_MAP as + // braces, so that inner block is indented one level more. + EXPECT_EQ("int q() {\n" + " IPC_BEGIN_MESSAGE_MAP(WebKitTestController, message)\n" + " IPC_MESSAGE_HANDLER(xxx, qqq)\n" + " IPC_END_MESSAGE_MAP()\n" + "}", + format("int q() {\n" + " IPC_BEGIN_MESSAGE_MAP(WebKitTestController, message)\n" + " IPC_MESSAGE_HANDLER(xxx, qqq)\n" + " IPC_END_MESSAGE_MAP()\n" + "}")); + EXPECT_EQ("int q() {\n" + " f(x);\n" + " f(x) {}\n" + " f(x)->g();\n" + " f(x)->*g();\n" + " f(x).g();\n" + " f(x) = x;\n" + " f(x) += x;\n" + " f(x) -= x;\n" + " f(x) *= x;\n" + " f(x) /= x;\n" + " f(x) %= x;\n" + " f(x) &= x;\n" + " f(x) |= x;\n" + " f(x) ^= x;\n" + " f(x) >>= x;\n" + " f(x) <<= x;\n" + " f(x)[y].z();\n" + " LOG(INFO) << x;\n" + " ifstream(x) >> x;\n" + "}\n", + format("int q() {\n" + " f(x)\n;\n" + " f(x)\n {}\n" + " f(x)\n->g();\n" + " f(x)\n->*g();\n" + " f(x)\n.g();\n" + " f(x)\n = x;\n" + " f(x)\n += x;\n" + " f(x)\n -= x;\n" + " f(x)\n *= x;\n" + " f(x)\n /= x;\n" + " f(x)\n %= x;\n" + " f(x)\n &= x;\n" + " f(x)\n |= x;\n" + " f(x)\n ^= x;\n" + " f(x)\n >>= x;\n" + " f(x)\n <<= x;\n" + " f(x)\n[y].z();\n" + " LOG(INFO)\n << x;\n" + " ifstream(x)\n >> x;\n" + "}\n")); + EXPECT_EQ("int q() {\n" + " f(x)\n" + " if (1) {\n" + " }\n" + " f(x)\n" + " while (1) {\n" + " }\n" + " f(x)\n" + " g(x);\n" + " f(x)\n" + " try {\n" + " q();\n" + " }\n" + " catch (...) {\n" + " }\n" + "}\n", + format("int q() {\n" + "f(x)\n" + "if (1) {}\n" + "f(x)\n" + "while (1) {}\n" + "f(x)\n" + "g(x);\n" + "f(x)\n" + "try { q(); } catch (...) {}\n" + "}\n")); + EXPECT_EQ("class A {\n" + " A() : t(0) {}\n" + " A(X x)\n" // FIXME: function-level try blocks are broken. + " try : t(0) {\n" + " }\n" + " catch (...) {\n" + " }\n" + "};", + format("class A {\n" + " A()\n : t(0) {}\n" + " A(X x)\n" + " try : t(0) {} catch (...) {}\n" + "};")); } TEST_F(FormatTest, IndentPreprocessorDirectivesAtZero) { _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
