forked from OSchip/llvm-project
[clang-format] Break an unwrapped line at a K&R C parameter decl
Break an unwrapped line before the first parameter declaration in a K&R C function definition. This fixes PR51074. Differential Revision: https://reviews.llvm.org/D106112
This commit is contained in:
parent
87039c048c
commit
9da70ab3d4
|
@ -431,7 +431,7 @@ void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
|
|||
}
|
||||
LLVM_FALLTHROUGH;
|
||||
default:
|
||||
parseStructuralElement();
|
||||
parseStructuralElement(/*IsTopLevel=*/true);
|
||||
break;
|
||||
}
|
||||
} while (!eof());
|
||||
|
@ -994,6 +994,33 @@ static bool isJSDeclOrStmt(const AdditionalKeywords &Keywords,
|
|||
Keywords.kw_import, tok::kw_export);
|
||||
}
|
||||
|
||||
// This function checks whether a token starts the first parameter declaration
|
||||
// in a K&R C (aka C78) function definition, e.g.:
|
||||
// int f(a, b)
|
||||
// short a, b;
|
||||
// {
|
||||
// return a + b;
|
||||
// }
|
||||
static bool isC78ParameterDecl(const FormatToken *Tok) {
|
||||
if (!Tok)
|
||||
return false;
|
||||
|
||||
if (!Tok->isOneOf(tok::kw_int, tok::kw_char, tok::kw_float, tok::kw_double,
|
||||
tok::kw_struct, tok::kw_union, tok::kw_long, tok::kw_short,
|
||||
tok::kw_unsigned, tok::kw_register, tok::identifier))
|
||||
return false;
|
||||
|
||||
Tok = Tok->Previous;
|
||||
if (!Tok || Tok->isNot(tok::r_paren))
|
||||
return false;
|
||||
|
||||
Tok = Tok->Previous;
|
||||
if (!Tok || Tok->isNot(tok::identifier))
|
||||
return false;
|
||||
|
||||
return Tok->Previous && Tok->Previous->isOneOf(tok::l_paren, tok::comma);
|
||||
}
|
||||
|
||||
// readTokenWithJavaScriptASI reads the next token and terminates the current
|
||||
// line if JavaScript Automatic Semicolon Insertion must
|
||||
// happen between the current token and the next token.
|
||||
|
@ -1041,7 +1068,7 @@ void UnwrappedLineParser::readTokenWithJavaScriptASI() {
|
|||
return addUnwrappedLine();
|
||||
}
|
||||
|
||||
void UnwrappedLineParser::parseStructuralElement() {
|
||||
void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) {
|
||||
assert(!FormatTok->is(tok::l_brace));
|
||||
if (Style.Language == FormatStyle::LK_TableGen &&
|
||||
FormatTok->is(tok::pp_include)) {
|
||||
|
@ -1343,6 +1370,18 @@ void UnwrappedLineParser::parseStructuralElement() {
|
|||
return;
|
||||
case tok::l_paren:
|
||||
parseParens();
|
||||
// Break the unwrapped line if a K&R C function definition has a parameter
|
||||
// declaration.
|
||||
if (!IsTopLevel || !Style.isCpp())
|
||||
break;
|
||||
if (!Previous || Previous->isNot(tok::identifier))
|
||||
break;
|
||||
if (Previous->Previous && Previous->Previous->is(tok::at))
|
||||
break;
|
||||
if (isC78ParameterDecl(FormatTok)) {
|
||||
addUnwrappedLine();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case tok::kw_operator:
|
||||
nextToken();
|
||||
|
|
|
@ -97,7 +97,7 @@ private:
|
|||
void parsePPEndIf();
|
||||
void parsePPUnknown();
|
||||
void readTokenWithJavaScriptASI();
|
||||
void parseStructuralElement();
|
||||
void parseStructuralElement(bool IsTopLevel = false);
|
||||
bool tryToParseBracedList();
|
||||
bool parseBracedList(bool ContinueOnSemicolons = false, bool IsEnum = false,
|
||||
tok::TokenKind ClosingBraceKind = tok::r_brace);
|
||||
|
|
|
@ -8216,7 +8216,16 @@ TEST_F(FormatTest, ReturnTypeBreakingStyle) {
|
|||
"f(i)\n"
|
||||
"{\n"
|
||||
" return i + 1;\n"
|
||||
"}\n",
|
||||
"}",
|
||||
Style);
|
||||
verifyFormat("int f(a, b, c);\n" // No break here.
|
||||
"int\n" // Break here.
|
||||
"f(a, b, c)\n" // Break here.
|
||||
"short a, b;\n"
|
||||
"float c;\n"
|
||||
"{\n"
|
||||
" return a + b < c;\n"
|
||||
"}",
|
||||
Style);
|
||||
|
||||
Style = getGNUStyle();
|
||||
|
@ -9423,7 +9432,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
|
|||
verifyFormat("vector<A(uint64_t) * attr> v;", TypeMacros); // multiplication
|
||||
|
||||
FormatStyle CustomQualifier = getLLVMStyle();
|
||||
// Add indentifers that should not be parsed as a qualifier by default.
|
||||
// Add identifiers that should not be parsed as a qualifier by default.
|
||||
CustomQualifier.AttributeMacros.push_back("__my_qualifier");
|
||||
CustomQualifier.AttributeMacros.push_back("_My_qualifier");
|
||||
CustomQualifier.AttributeMacros.push_back("my_other_qualifier");
|
||||
|
|
Loading…
Reference in New Issue