forked from OSchip/llvm-project
clang-format: Improve heuristics to detect function declarations/definitions.
Specifically understand ellipses in parameter lists and treat trailing reference qualifiers and the "{" as signals. llvm-svn: 266599
This commit is contained in:
parent
8222151a7e
commit
c3ff0cd8a2
|
@ -1553,7 +1553,8 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) {
|
|||
|
||||
// This function heuristically determines whether 'Current' starts the name of a
|
||||
// function declaration.
|
||||
static bool isFunctionDeclarationName(const FormatToken &Current) {
|
||||
static bool isFunctionDeclarationName(const FormatToken &Current,
|
||||
const AnnotatedLine &Line) {
|
||||
auto skipOperatorName = [](const FormatToken* Next) -> const FormatToken* {
|
||||
for (; Next; Next = Next->Next) {
|
||||
if (Next->is(TT_OverloadedOperatorLParen))
|
||||
|
@ -1573,6 +1574,7 @@ static bool isFunctionDeclarationName(const FormatToken &Current) {
|
|||
return nullptr;
|
||||
};
|
||||
|
||||
// Find parentheses of parameter list.
|
||||
const FormatToken *Next = Current.Next;
|
||||
if (Current.is(tok::kw_operator)) {
|
||||
if (Current.Previous && Current.Previous->is(tok::coloncolon))
|
||||
|
@ -1602,14 +1604,22 @@ static bool isFunctionDeclarationName(const FormatToken &Current) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!Next || !Next->is(tok::l_paren))
|
||||
// Check whether parameter list can be long to a function declaration.
|
||||
if (!Next || !Next->is(tok::l_paren) || !Next->MatchingParen)
|
||||
return false;
|
||||
// If the lines ends with "{", this is likely an function definition.
|
||||
if (Line.Last->is(tok::l_brace))
|
||||
return true;
|
||||
if (Next->Next == Next->MatchingParen)
|
||||
return true; // Empty parentheses.
|
||||
// If there is an &/&& after the r_paren, this is likely a function.
|
||||
if (Next->MatchingParen->Next &&
|
||||
Next->MatchingParen->Next->is(TT_PointerOrReference))
|
||||
return true;
|
||||
for (const FormatToken *Tok = Next->Next; Tok && Tok != Next->MatchingParen;
|
||||
Tok = Tok->Next) {
|
||||
if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() ||
|
||||
Tok->isOneOf(TT_PointerOrReference, TT_StartOfName))
|
||||
Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis))
|
||||
return true;
|
||||
if (Tok->isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) ||
|
||||
Tok->Tok.isLiteral())
|
||||
|
@ -1655,7 +1665,7 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) {
|
|||
FormatToken *Current = Line.First->Next;
|
||||
bool InFunctionDecl = Line.MightBeFunctionDecl;
|
||||
while (Current) {
|
||||
if (isFunctionDeclarationName(*Current))
|
||||
if (isFunctionDeclarationName(*Current, Line))
|
||||
Current->Type = TT_FunctionDeclarationName;
|
||||
if (Current->is(TT_LineComment)) {
|
||||
if (Current->Previous->BlockKind == BK_BracedInit &&
|
||||
|
|
|
@ -5621,6 +5621,10 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) {
|
|||
AlignLeft);
|
||||
verifyFormat("Deleted& operator=(const Deleted&) &;", AlignLeft);
|
||||
verifyFormat("SomeType MemberFunction(const Deleted&) &;", AlignLeft);
|
||||
verifyFormat("auto Function(T t) & -> void {}", AlignLeft);
|
||||
verifyFormat("auto Function(T... t) & -> void {}", AlignLeft);
|
||||
verifyFormat("auto Function(T) & -> void {}", AlignLeft);
|
||||
verifyFormat("auto Function(T) & -> void;", AlignLeft);
|
||||
|
||||
FormatStyle Spaces = getLLVMStyle();
|
||||
Spaces.SpacesInCStyleCastParentheses = true;
|
||||
|
@ -6119,6 +6123,10 @@ TEST_F(FormatTest, BreaksLongDeclarations) {
|
|||
"LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
|
||||
verifyFormat("decltype(LoooooooooooooooooooooooooooooooooooooooongName)\n"
|
||||
"LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
|
||||
verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n"
|
||||
"LooooooooooooooooooooooooooongFunctionDeclaration(T... t);");
|
||||
verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n"
|
||||
"LooooooooooooooooooooooooooongFunctionDeclaration(T /*t*/) {}");
|
||||
FormatStyle Indented = getLLVMStyle();
|
||||
Indented.IndentWrappedFunctionNames = true;
|
||||
verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n"
|
||||
|
|
Loading…
Reference in New Issue