From 308232c0aef773d24693f9e456dc3bc983934f7f Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Mon, 21 Jan 2013 19:17:52 +0000 Subject: [PATCH] Fixes various problems around enum parsing. Very similar to what we do for record definitions: - tighten down what is an enum definition, so that we don't mistake a function for an enum - allow common idioms around declarations (we'll want to handle that more centrally in the future) We now correctly format: enum X f() { a(); return 42; } git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173075 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Format/UnwrappedLineParser.cpp | 73 +++++++++++++++++------------- unittests/Format/FormatTest.cpp | 4 ++ 2 files changed, 46 insertions(+), 31 deletions(-) diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index c054ef6c82..2d6c5cf070 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -329,7 +329,7 @@ void UnwrappedLineParser::parseStructuralElement() { switch (FormatTok.Tok.getKind()) { case tok::kw_enum: parseEnum(); - return; + break; case tok::kw_struct: case tok::kw_union: case tok::kw_class: @@ -580,39 +580,50 @@ void UnwrappedLineParser::parseAccessSpecifier() { } void UnwrappedLineParser::parseEnum() { - bool HasContents = false; - do { - switch (FormatTok.Tok.getKind()) { - case tok::l_brace: - nextToken(); - addUnwrappedLine(); - ++Line->Level; - parseComments(); - break; - case tok::l_paren: + nextToken(); + if (FormatTok.Tok.is(tok::identifier) || + FormatTok.Tok.is(tok::kw___attribute) || + FormatTok.Tok.is(tok::kw___declspec)) { + nextToken(); + // We can have macros or attributes in between 'enum' and the enum name. + if (FormatTok.Tok.is(tok::l_paren)) { parseParens(); - break; - case tok::comma: + } + if (FormatTok.Tok.is(tok::identifier)) nextToken(); - addUnwrappedLine(); - parseComments(); - break; - case tok::r_brace: - if (HasContents) + } + if (FormatTok.Tok.is(tok::l_brace)) { + nextToken(); + addUnwrappedLine(); + ++Line->Level; + do { + switch (FormatTok.Tok.getKind()) { + case tok::comment: + // FIXME: Handle comments centrally, instead of special casing + // them everywhere. + parseComments(); + break; + case tok::l_paren: + parseParens(); + break; + case tok::r_brace: addUnwrappedLine(); - --Line->Level; - nextToken(); - break; - case tok::semi: - nextToken(); - addUnwrappedLine(); - return; - default: - HasContents = true; - nextToken(); - break; - } - } while (!eof()); + nextToken(); + --Line->Level; + return; + case tok::comma: + nextToken(); + addUnwrappedLine(); + break; + default: + nextToken(); + break; + } + } while (!eof()); + } + // We fall through to parsing a structural element afterwards, so that in + // enum A {} n, m; + // "} n, m;" will end up in one unwrapped line. } void UnwrappedLineParser::parseRecord() { diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index bda3196b02..c9b255ce41 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -499,6 +499,10 @@ TEST_F(FormatTest, FormatsEnum) { "};"); verifyFormat("enum {\n" "};"); + verifyFormat("enum X E {\n} d;"); + verifyFormat("enum __attribute__((...)) E {\n} d;"); + verifyFormat("enum __declspec__((...)) E {\n} d;"); + verifyFormat("enum X f() {\n a();\n return 42;\n}"); } TEST_F(FormatTest, FormatsBitfields) { -- 2.40.0