From: Manuel Klimek Date: Tue, 15 Jan 2013 15:50:27 +0000 (+0000) Subject: Fix formatting of preprocessor directives (incluces, warnings & errors). X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=407a31afffc936291d719665b9edb72532c0ed3b;p=clang Fix formatting of preprocessor directives (incluces, warnings & errors). Treat tokens inside <> for includes and everything from the second token of a warning / error on as an implicit string literal, e.g. do not change its whitespace at all. Now correctly formats: #include < path with space > #error Leave all white!!!!! space* alone! Note that for #error and #warning we still format the space up to the first token of the text, so: # error Text will become #error Text git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172536 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index c40aa5387c..a6b9e2031d 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -34,7 +34,7 @@ enum TokenType { TT_CastRParen, TT_ConditionalExpr, TT_CtorInitializerColon, - TT_IncludePath, + TT_ImplicitStringLiteral, TT_LineComment, TT_ObjCBlockLParen, TT_ObjCDecl, @@ -374,6 +374,11 @@ private: assert(State.Stack.size()); unsigned ParenLevel = State.Stack.size() - 1; + if (Current.Type == TT_ImplicitStringLiteral) { + moveStateToNextToken(State); + return; + } + if (Newline) { unsigned WhitespaceStartColumn = State.Column; if (Current.is(tok::r_brace)) { @@ -862,8 +867,27 @@ public: } void parseIncludeDirective() { + next(); + if (CurrentToken != NULL && CurrentToken->is(tok::less)) { + next(); + while (CurrentToken != NULL) { + CurrentToken->Type = TT_ImplicitStringLiteral; + next(); + } + } else { + while (CurrentToken != NULL) { + next(); + } + } + } + + void parseWarningOrError() { + next(); + // We still want to format the whitespace left of the first token of the + // warning or error. + next(); while (CurrentToken != NULL) { - CurrentToken->Type = TT_IncludePath; + CurrentToken->Type = TT_ImplicitStringLiteral; next(); } } @@ -882,6 +906,10 @@ public: case tok::pp_import: parseIncludeDirective(); break; + case tok::pp_error: + case tok::pp_warning: + parseWarningOrError(); + break; default: break; } @@ -1213,8 +1241,6 @@ private: if (Tok.Parent->is(tok::comma)) return true; - if (Tok.Type == TT_IncludePath) - return Tok.is(tok::less) || Tok.is(tok::string_literal); if (Tok.Type == TT_CtorInitializerColon || Tok.Type == TT_ObjCBlockLParen) return true; if (Tok.Type == TT_OverloadedOperator) @@ -1264,8 +1290,6 @@ private: // Don't break at ':' if identifier before it can beak. return false; } - if (Right.Type == TT_IncludePath) - return false; if (Right.is(tok::colon) && Right.Type == TT_ObjCMethodExpr) return false; if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr) diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index c6f1c8e4ec..eb00d017ff 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -1184,7 +1184,8 @@ TEST_F(FormatTest, HandlesIncludeDirectives) { "#include \"a/b/string\"\n" "#include \"string.h\"\n" "#include \"string.h\"\n" - "#include "); + "#include \n" + "#include < path with space >\n"); verifyFormat("#import "); verifyFormat("#import "); @@ -1334,6 +1335,13 @@ TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) { " f();\n"); } +TEST_F(FormatTest, DoNotInterfereWithErrorAndWarning) { + verifyFormat("#error Leave all white!!!!! space* alone!\n"); + verifyFormat("#warning Leave all white!!!!! space* alone!\n"); + EXPECT_EQ("#error 1", format(" # error 1")); + EXPECT_EQ("#warning 1", format(" # warning 1")); +} + // FIXME: This breaks the order of the unwrapped lines: // TEST_F(FormatTest, OrderUnwrappedLines) { // verifyFormat("{\n"