forked from OSchip/llvm-project
clang-format: Format extern "C" blocks like namespace blocks.
namespace blocks act as if KeepEmptyLinesAtTheStartOfBlocks is always true, and aren't collapsed to a single line even if they would fit. Do the same for extern "C" blocks. Before, extern "C" { void ExternCFunction(); } was collapsed into `extern "C" { void ExternCFunction(); }`. Now it stays like it was. Fixes http://crbug.com/432640 and part of PR21419. llvm-svn: 221897
This commit is contained in:
parent
17072ef348
commit
34272657de
|
@ -574,6 +574,13 @@ std::string configurationAsText(const FormatStyle &Style) {
|
|||
|
||||
namespace {
|
||||
|
||||
bool startsExternCBlock(const AnnotatedLine &Line) {
|
||||
const FormatToken *Next = Line.First->getNextNonComment();
|
||||
const FormatToken *NextNext = Next ? Next->getNextNonComment() : nullptr;
|
||||
return Line.First->is(tok::kw_extern) && Next && Next->isStringLiteral() &&
|
||||
NextNext && NextNext->is(tok::l_brace);
|
||||
}
|
||||
|
||||
class NoColumnLimitFormatter {
|
||||
public:
|
||||
NoColumnLimitFormatter(ContinuationIndenter *Indenter) : Indenter(Indenter) {}
|
||||
|
@ -785,7 +792,8 @@ private:
|
|||
Tok->SpacesRequiredBefore = 0;
|
||||
Tok->CanBreakBefore = true;
|
||||
return 1;
|
||||
} else if (Limit != 0 && Line.First->isNot(tok::kw_namespace)) {
|
||||
} else if (Limit != 0 && Line.First->isNot(tok::kw_namespace) &&
|
||||
!startsExternCBlock(Line)) {
|
||||
// We don't merge short records.
|
||||
if (Line.First->isOneOf(tok::kw_class, tok::kw_union, tok::kw_struct))
|
||||
return 0;
|
||||
|
@ -1069,7 +1077,8 @@ private:
|
|||
// Remove empty lines after "{".
|
||||
if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine &&
|
||||
PreviousLine->Last->is(tok::l_brace) &&
|
||||
PreviousLine->First->isNot(tok::kw_namespace))
|
||||
PreviousLine->First->isNot(tok::kw_namespace) &&
|
||||
!startsExternCBlock(*PreviousLine))
|
||||
Newlines = 1;
|
||||
|
||||
// Insert extra new line before access specifiers.
|
||||
|
|
|
@ -187,7 +187,7 @@ TEST_F(FormatTest, RemovesEmptyLines) {
|
|||
"\n"
|
||||
"};"));
|
||||
|
||||
// Don't remove empty lines at the start of namespaces.
|
||||
// Don't remove empty lines at the start of namespaces or extern "C" blocks.
|
||||
EXPECT_EQ("namespace N {\n"
|
||||
"\n"
|
||||
"int i;\n"
|
||||
|
@ -197,6 +197,29 @@ TEST_F(FormatTest, RemovesEmptyLines) {
|
|||
"int i;\n"
|
||||
"}",
|
||||
getGoogleStyle()));
|
||||
EXPECT_EQ("extern /**/ \"C\" /**/ {\n"
|
||||
"\n"
|
||||
"int i;\n"
|
||||
"}",
|
||||
format("extern /**/ \"C\" /**/ {\n"
|
||||
"\n"
|
||||
"int i;\n"
|
||||
"}",
|
||||
getGoogleStyle()));
|
||||
|
||||
// ...but do keep inlining and removing empty lines for non-block extern "C"
|
||||
// functions.
|
||||
verifyFormat("extern \"C\" int f() { return 42; }", getGoogleStyle());
|
||||
EXPECT_EQ("extern \"C\" int f() {\n"
|
||||
" int i = 42;\n"
|
||||
" return i;\n"
|
||||
"}",
|
||||
format("extern \"C\" int f() {\n"
|
||||
"\n"
|
||||
" int i = 42;\n"
|
||||
" return i;\n"
|
||||
"}",
|
||||
getGoogleStyle()));
|
||||
|
||||
// Remove empty lines at the beginning and end of blocks.
|
||||
EXPECT_EQ("void f() {\n"
|
||||
|
|
Loading…
Reference in New Issue