summaryrefslogtreecommitdiffstats
path: root/lib/Format/UnwrappedLineParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Format/UnwrappedLineParser.cpp')
-rw-r--r--lib/Format/UnwrappedLineParser.cpp106
1 files changed, 84 insertions, 22 deletions
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index 3cd3c8f9cd..7acf33a968 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -1,9 +1,8 @@
//===--- UnwrappedLineParser.cpp - Format C++ code ------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
@@ -173,10 +172,16 @@ class CompoundStatementIndenter {
public:
CompoundStatementIndenter(UnwrappedLineParser *Parser,
const FormatStyle &Style, unsigned &LineLevel)
+ : CompoundStatementIndenter(Parser, LineLevel,
+ Style.BraceWrapping.AfterControlStatement,
+ Style.BraceWrapping.IndentBraces) {
+ }
+ CompoundStatementIndenter(UnwrappedLineParser *Parser, unsigned &LineLevel,
+ bool WrapBrace, bool IndentBrace)
: LineLevel(LineLevel), OldLineLevel(LineLevel) {
- if (Style.BraceWrapping.AfterControlStatement)
+ if (WrapBrace)
Parser->addUnwrappedLine();
- if (Style.BraceWrapping.IndentBraces)
+ if (IndentBrace)
++LineLevel;
}
~CompoundStatementIndenter() { LineLevel = OldLineLevel; }
@@ -482,7 +487,7 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
break;
case tok::identifier:
if (!Tok->is(TT_StatementMacro))
- break;
+ break;
LLVM_FALLTHROUGH;
case tok::at:
case tok::semi:
@@ -656,6 +661,7 @@ void UnwrappedLineParser::parseChildBlock() {
void UnwrappedLineParser::parsePPDirective() {
assert(FormatTok->Tok.is(tok::hash) && "'#' expected");
ScopedMacroState MacroState(*Line, Tokens, FormatTok);
+
nextToken();
if (!FormatTok->Tok.getIdentifierInfo()) {
@@ -799,7 +805,7 @@ void UnwrappedLineParser::parsePPEndIf() {
void UnwrappedLineParser::parsePPDefine() {
nextToken();
- if (FormatTok->Tok.getKind() != tok::identifier) {
+ if (!FormatTok->Tok.getIdentifierInfo()) {
IncludeGuard = IG_Rejected;
IncludeGuardToken = nullptr;
parsePPUnknown();
@@ -824,7 +830,7 @@ void UnwrappedLineParser::parsePPDefine() {
FormatTok->WhitespaceRange.getEnd()) {
parseParens();
}
- if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash)
+ if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
Line->Level += PPBranchLevel + 1;
addUnwrappedLine();
++Line->Level;
@@ -841,7 +847,7 @@ void UnwrappedLineParser::parsePPUnknown() {
do {
nextToken();
} while (!eof());
- if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash)
+ if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
Line->Level += PPBranchLevel + 1;
addUnwrappedLine();
}
@@ -1000,7 +1006,7 @@ void UnwrappedLineParser::parseStructuralElement() {
case tok::kw_protected:
case tok::kw_private:
if (Style.Language == FormatStyle::LK_Java ||
- Style.Language == FormatStyle::LK_JavaScript)
+ Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp())
nextToken();
else
parseAccessSpecifier();
@@ -1167,8 +1173,8 @@ void UnwrappedLineParser::parseStructuralElement() {
case tok::objc_synchronized:
nextToken();
if (FormatTok->Tok.is(tok::l_paren))
- // Skip synchronization object
- parseParens();
+ // Skip synchronization object
+ parseParens();
if (FormatTok->Tok.is(tok::l_brace)) {
if (Style.BraceWrapping.AfterControlStatement)
addUnwrappedLine();
@@ -1214,9 +1220,9 @@ void UnwrappedLineParser::parseStructuralElement() {
// parseRecord falls through and does not yet add an unwrapped line as a
// record declaration or definition can start a structural element.
parseRecord();
- // This does not apply for Java and JavaScript.
+ // This does not apply for Java, JavaScript and C#.
if (Style.Language == FormatStyle::LK_Java ||
- Style.Language == FormatStyle::LK_JavaScript) {
+ Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) {
if (FormatTok->is(tok::semi))
nextToken();
addUnwrappedLine();
@@ -1329,10 +1335,15 @@ void UnwrappedLineParser::parseStructuralElement() {
// See if the following token should start a new unwrapped line.
StringRef Text = FormatTok->TokenText;
nextToken();
- if (Line->Tokens.size() == 1 &&
- // JS doesn't have macros, and within classes colons indicate fields,
- // not labels.
- Style.Language != FormatStyle::LK_JavaScript) {
+
+ // JS doesn't have macros, and within classes colons indicate fields, not
+ // labels.
+ if (Style.Language == FormatStyle::LK_JavaScript)
+ break;
+
+ TokenCount = Line->Tokens.size();
+ if (TokenCount == 1 ||
+ (TokenCount == 2 && Line->Tokens.front().Tok->is(tok::comment))) {
if (FormatTok->Tok.is(tok::colon) && !Line->MustBeDeclaration) {
Line->Tokens.begin()->Tok->MustBreakBefore = true;
parseLabel();
@@ -1402,6 +1413,8 @@ bool UnwrappedLineParser::tryToParseLambda() {
if (!tryToParseLambdaIntroducer())
return false;
+ bool SeenArrow = false;
+
while (FormatTok->isNot(tok::l_brace)) {
if (FormatTok->isSimpleTypeSpecifier()) {
nextToken();
@@ -1423,16 +1436,57 @@ bool UnwrappedLineParser::tryToParseLambda() {
case tok::numeric_constant:
case tok::coloncolon:
case tok::kw_mutable:
+ case tok::kw_noexcept:
nextToken();
break;
+ // Specialization of a template with an integer parameter can contain
+ // arithmetic, logical, comparison and ternary operators.
+ //
+ // FIXME: This also accepts sequences of operators that are not in the scope
+ // of a template argument list.
+ //
+ // In a C++ lambda a template type can only occur after an arrow. We use
+ // this as an heuristic to distinguish between Objective-C expressions
+ // followed by an `a->b` expression, such as:
+ // ([obj func:arg] + a->b)
+ // Otherwise the code below would parse as a lambda.
+ case tok::plus:
+ case tok::minus:
+ case tok::exclaim:
+ case tok::tilde:
+ case tok::slash:
+ case tok::percent:
+ case tok::lessless:
+ case tok::pipe:
+ case tok::pipepipe:
+ case tok::ampamp:
+ case tok::caret:
+ case tok::equalequal:
+ case tok::exclaimequal:
+ case tok::greaterequal:
+ case tok::lessequal:
+ case tok::question:
+ case tok::colon:
+ case tok::kw_true:
+ case tok::kw_false:
+ if (SeenArrow) {
+ nextToken();
+ break;
+ }
+ return true;
case tok::arrow:
+ // This might or might not actually be a lambda arrow (this could be an
+ // ObjC method invocation followed by a dereferencing arrow). We might
+ // reset this back to TT_Unknown in TokenAnnotator.
FormatTok->Type = TT_LambdaArrow;
+ SeenArrow = true;
nextToken();
break;
default:
return true;
}
}
+ FormatTok->Type = TT_LambdaLBrace;
LSquare.Type = TT_LambdaLSquare;
parseChildBlock();
return true;
@@ -1907,7 +1961,9 @@ void UnwrappedLineParser::parseLabel() {
if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
--Line->Level;
if (CommentsBeforeNextToken.empty() && FormatTok->Tok.is(tok::l_brace)) {
- CompoundStatementIndenter Indenter(this, Style, Line->Level);
+ CompoundStatementIndenter Indenter(this, Line->Level,
+ Style.BraceWrapping.AfterCaseLabel,
+ Style.BraceWrapping.IndentBraces);
parseBlock(/*MustBeDeclaration=*/false);
if (FormatTok->Tok.is(tok::kw_break)) {
if (Style.BraceWrapping.AfterControlStatement)
@@ -1976,6 +2032,10 @@ bool UnwrappedLineParser::parseEnum() {
FormatTok->isOneOf(tok::colon, tok::question))
return false;
+ // In protobuf, "enum" can be used as a field name.
+ if (Style.Language == FormatStyle::LK_Proto && FormatTok->is(tok::equal))
+ return false;
+
// Eat up enum class ...
if (FormatTok->Tok.is(tok::kw_class) || FormatTok->Tok.is(tok::kw_struct))
nextToken();
@@ -2347,8 +2407,7 @@ void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
}
}
-void UnwrappedLineParser::parseStatementMacro()
-{
+void UnwrappedLineParser::parseStatementMacro() {
nextToken();
if (FormatTok->is(tok::l_paren))
parseParens();
@@ -2631,6 +2690,9 @@ void UnwrappedLineParser::readToken(int LevelDifference) {
// Comments stored before the preprocessor directive need to be output
// before the preprocessor directive, at the same level as the
// preprocessor directive, as we consider them to apply to the directive.
+ if (Style.IndentPPDirectives == FormatStyle::PPDIS_BeforeHash &&
+ PPBranchLevel > 0)
+ Line->Level += PPBranchLevel;
flushComments(isOnNewLine(*FormatTok));
parsePPDirective();
}