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 {
|
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 {
|
class NoColumnLimitFormatter {
|
||||||
public:
|
public:
|
||||||
NoColumnLimitFormatter(ContinuationIndenter *Indenter) : Indenter(Indenter) {}
|
NoColumnLimitFormatter(ContinuationIndenter *Indenter) : Indenter(Indenter) {}
|
||||||
|
@ -785,7 +792,8 @@ private:
|
||||||
Tok->SpacesRequiredBefore = 0;
|
Tok->SpacesRequiredBefore = 0;
|
||||||
Tok->CanBreakBefore = true;
|
Tok->CanBreakBefore = true;
|
||||||
return 1;
|
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.
|
// We don't merge short records.
|
||||||
if (Line.First->isOneOf(tok::kw_class, tok::kw_union, tok::kw_struct))
|
if (Line.First->isOneOf(tok::kw_class, tok::kw_union, tok::kw_struct))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1069,7 +1077,8 @@ private:
|
||||||
// Remove empty lines after "{".
|
// Remove empty lines after "{".
|
||||||
if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine &&
|
if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine &&
|
||||||
PreviousLine->Last->is(tok::l_brace) &&
|
PreviousLine->Last->is(tok::l_brace) &&
|
||||||
PreviousLine->First->isNot(tok::kw_namespace))
|
PreviousLine->First->isNot(tok::kw_namespace) &&
|
||||||
|
!startsExternCBlock(*PreviousLine))
|
||||||
Newlines = 1;
|
Newlines = 1;
|
||||||
|
|
||||||
// Insert extra new line before access specifiers.
|
// Insert extra new line before access specifiers.
|
||||||
|
|
|
@ -187,7 +187,7 @@ TEST_F(FormatTest, RemovesEmptyLines) {
|
||||||
"\n"
|
"\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"
|
EXPECT_EQ("namespace N {\n"
|
||||||
"\n"
|
"\n"
|
||||||
"int i;\n"
|
"int i;\n"
|
||||||
|
@ -197,6 +197,29 @@ TEST_F(FormatTest, RemovesEmptyLines) {
|
||||||
"int i;\n"
|
"int i;\n"
|
||||||
"}",
|
"}",
|
||||||
getGoogleStyle()));
|
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.
|
// Remove empty lines at the beginning and end of blocks.
|
||||||
EXPECT_EQ("void f() {\n"
|
EXPECT_EQ("void f() {\n"
|
||||||
|
|
Loading…
Reference in New Issue