Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit ae76f7f

Browse files
committed
Support formatting of preprocessor branches.
We now correctly format: void SomeFunction(int param1, #ifdef X NoTemplate param2, #else template < #ifdef A MyType<Some> > #else Type1, Type2> #endif param2, #endif param3) { f(); } git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192503 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 812a32f commit ae76f7f

11 files changed

+265
-68
lines changed

Diff for: lib/Format/ContinuationIndenter.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline,
221221

222222
void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
223223
unsigned ExtraSpaces) {
224-
const FormatToken &Current = *State.NextToken;
224+
FormatToken &Current = *State.NextToken;
225225
const FormatToken &Previous = *State.NextToken->Previous;
226226
if (Current.is(tok::equal) &&
227227
(State.Line->First->is(tok::kw_for) || State.ParenLevel == 0) &&
@@ -301,7 +301,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
301301

302302
unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
303303
bool DryRun) {
304-
const FormatToken &Current = *State.NextToken;
304+
FormatToken &Current = *State.NextToken;
305305
const FormatToken &Previous = *State.NextToken->Previous;
306306
// If we are continuing an expression, we want to indent an extra 4 spaces.
307307
unsigned ContinuationIndent =

Diff for: lib/Format/ContinuationIndenter.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ struct LineState {
250250
unsigned Column;
251251

252252
/// \brief The token that needs to be next formatted.
253-
const FormatToken *NextToken;
253+
FormatToken *NextToken;
254254

255255
/// \brief \c true if this line contains a continued for-loop section.
256256
bool LineContainsContinuedForLoopSection;

Diff for: lib/Format/Format.cpp

+55-17
Original file line numberDiff line numberDiff line change
@@ -447,14 +447,19 @@ class UnwrappedLineFormatter {
447447
// State already examined with lower penalty.
448448
continue;
449449

450-
addNextStateToQueue(Penalty, Node, /*NewLine=*/false);
451-
addNextStateToQueue(Penalty, Node, /*NewLine=*/true);
450+
FormatDecision LastFormat = Node->State.NextToken->Decision;
451+
if (LastFormat == FD_Unformatted || LastFormat == FD_Continue)
452+
addNextStateToQueue(Penalty, Node, /*NewLine=*/false);
453+
if (LastFormat == FD_Unformatted || LastFormat == FD_Break)
454+
addNextStateToQueue(Penalty, Node, /*NewLine=*/true);
452455
}
453456

454-
if (Queue.empty())
457+
if (Queue.empty()) {
455458
// We were unable to find a solution, do nothing.
456459
// FIXME: Add diagnostic?
460+
DEBUG(llvm::dbgs() << "Could not find a solution.\n");
457461
return 0;
462+
}
458463

459464
// Reconstruct the solution.
460465
if (!DryRun)
@@ -815,29 +820,54 @@ class Formatter : public UnwrappedLineConsumer {
815820
const std::vector<CharSourceRange> &Ranges)
816821
: Style(Style), Lex(Lex), SourceMgr(SourceMgr),
817822
Whitespaces(SourceMgr, Style, inputUsesCRLF(Lex.getBuffer())),
818-
Ranges(Ranges), Encoding(encoding::detectEncoding(Lex.getBuffer())) {
823+
Ranges(Ranges), UnwrappedLines(1),
824+
Encoding(encoding::detectEncoding(Lex.getBuffer())) {
819825
DEBUG(llvm::dbgs() << "File encoding: "
820826
<< (Encoding == encoding::Encoding_UTF8 ? "UTF8"
821827
: "unknown")
822828
<< "\n");
823829
}
824830

825-
virtual ~Formatter() {
826-
for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
827-
delete AnnotatedLines[i];
828-
}
829-
}
830-
831831
tooling::Replacements format() {
832+
tooling::Replacements Result;
832833
FormatTokenLexer Tokens(Lex, SourceMgr, Style, Encoding);
833834

834835
UnwrappedLineParser Parser(Style, Tokens.lex(), *this);
835836
bool StructuralError = Parser.parse();
837+
assert(UnwrappedLines.rbegin()->empty());
838+
for (unsigned Run = 0, RunE = UnwrappedLines.size(); Run + 1 != RunE;
839+
++Run) {
840+
DEBUG(llvm::dbgs() << "Run " << Run << "...\n");
841+
SmallVector<AnnotatedLine *, 16> AnnotatedLines;
842+
for (unsigned i = 0, e = UnwrappedLines[Run].size(); i != e; ++i) {
843+
AnnotatedLines.push_back(new AnnotatedLine(UnwrappedLines[Run][i]));
844+
}
845+
tooling::Replacements RunResult =
846+
format(AnnotatedLines, StructuralError, Tokens);
847+
DEBUG({
848+
llvm::dbgs() << "Replacements for run " << Run << ":\n";
849+
for (tooling::Replacements::iterator I = RunResult.begin(),
850+
E = RunResult.end();
851+
I != E; ++I) {
852+
llvm::dbgs() << I->toString() << "\n";
853+
}
854+
});
855+
for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
856+
delete AnnotatedLines[i];
857+
}
858+
Result.insert(RunResult.begin(), RunResult.end());
859+
Whitespaces.reset();
860+
}
861+
return Result;
862+
}
863+
864+
tooling::Replacements format(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
865+
bool StructuralError, FormatTokenLexer &Tokens) {
836866
TokenAnnotator Annotator(Style, Tokens.getIdentTable().get("in"));
837867
for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
838868
Annotator.annotate(*AnnotatedLines[i]);
839869
}
840-
deriveLocalStyle();
870+
deriveLocalStyle(AnnotatedLines);
841871
for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
842872
Annotator.calculateFormattingInformation(*AnnotatedLines[i]);
843873
}
@@ -920,8 +950,7 @@ class Formatter : public UnwrappedLineConsumer {
920950
} else {
921951
// Format the first token if necessary, and notify the WhitespaceManager
922952
// about the unchanged whitespace.
923-
for (const FormatToken *Tok = TheLine.First; Tok != NULL;
924-
Tok = Tok->Next) {
953+
for (FormatToken *Tok = TheLine.First; Tok != NULL; Tok = Tok->Next) {
925954
if (Tok == TheLine.First &&
926955
(Tok->NewlinesBefore > 0 || Tok->IsFirst)) {
927956
unsigned LevelIndent = Tok->OriginalColumn;
@@ -947,6 +976,9 @@ class Formatter : public UnwrappedLineConsumer {
947976
// last token.
948977
PreviousLineWasTouched = false;
949978
}
979+
for (FormatToken *Tok = TheLine.First; Tok != NULL; Tok = Tok->Next) {
980+
Tok->Finalized = true;
981+
}
950982
PreviousLine = *I;
951983
}
952984
return Whitespaces.generateReplacements();
@@ -957,7 +989,8 @@ class Formatter : public UnwrappedLineConsumer {
957989
return Text.count('\r') * 2 > Text.count('\n');
958990
}
959991

960-
void deriveLocalStyle() {
992+
void
993+
deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
961994
unsigned CountBoundToVariable = 0;
962995
unsigned CountBoundToType = 0;
963996
bool HasCpp03IncompatibleFormat = false;
@@ -1229,13 +1262,18 @@ class Formatter : public UnwrappedLineConsumer {
12291262
}
12301263

12311264
virtual void consumeUnwrappedLine(const UnwrappedLine &TheLine) {
1232-
AnnotatedLines.push_back(new AnnotatedLine(TheLine));
1265+
assert(!UnwrappedLines.empty());
1266+
UnwrappedLines.back().push_back(TheLine);
1267+
}
1268+
1269+
virtual void finishRun() {
1270+
UnwrappedLines.push_back(SmallVector<UnwrappedLine, 16>());
12331271
}
12341272

12351273
/// \brief Add a new line and the required indent before the first Token
12361274
/// of the \c UnwrappedLine if there was no structural parsing error.
12371275
/// Returns the indent level of the \c UnwrappedLine.
1238-
void formatFirstToken(const FormatToken &RootToken,
1276+
void formatFirstToken(FormatToken &RootToken,
12391277
const AnnotatedLine *PreviousLine, unsigned Indent,
12401278
bool InPPDirective) {
12411279
unsigned Newlines =
@@ -1272,7 +1310,7 @@ class Formatter : public UnwrappedLineConsumer {
12721310
SourceManager &SourceMgr;
12731311
WhitespaceManager Whitespaces;
12741312
std::vector<CharSourceRange> Ranges;
1275-
SmallVector<AnnotatedLine *, 16> AnnotatedLines;
1313+
SmallVector<SmallVector<UnwrappedLine, 16>, 2> UnwrappedLines;
12761314

12771315
encoding::Encoding Encoding;
12781316
bool BinPackInconclusiveFunctions;

Diff for: lib/Format/FormatToken.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ void CommaSeparatedList::precomputeFormattingInfos(const FormatToken *Token) {
145145
bool HasRowWithSufficientColumns = false;
146146
unsigned Column = 0;
147147
for (unsigned i = 0, e = ItemLengths.size(); i != e; ++i) {
148+
assert(i < MustBreakBeforeItem.size());
148149
if (MustBreakBeforeItem[i] || Column == Columns) {
149150
++Format.LineCount;
150151
Column = 0;

Diff for: lib/Format/FormatToken.h

+16-1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ enum ParameterPackingKind {
7676
PPK_Inconclusive
7777
};
7878

79+
enum FormatDecision {
80+
FD_Unformatted,
81+
FD_Continue,
82+
FD_Break
83+
};
84+
7985
class TokenRole;
8086
class AnnotatedLine;
8187

@@ -93,7 +99,8 @@ struct FormatToken {
9399
LongestObjCSelectorName(0), FakeRParens(0),
94100
StartsBinaryExpression(false), EndsBinaryExpression(false),
95101
LastInChainOfCalls(false), PartOfMultiVariableDeclStmt(false),
96-
MatchingParen(NULL), Previous(NULL), Next(NULL) {}
102+
MatchingParen(NULL), Previous(NULL), Next(NULL),
103+
Decision(FD_Unformatted), Finalized(false) {}
97104

98105
/// \brief The \c Token.
99106
Token Tok;
@@ -338,6 +345,14 @@ struct FormatToken {
338345

339346
SmallVector<AnnotatedLine *, 1> Children;
340347

348+
/// \brief Stores the formatting decision for the token once it was made.
349+
FormatDecision Decision;
350+
351+
/// \brief If \c true, this token has been fully formatted (indented and
352+
/// potentially re-formatted inside), and we do not allow further formatting
353+
/// changes.
354+
bool Finalized;
355+
341356
private:
342357
// Disallow copying.
343358
FormatToken(const FormatToken &) LLVM_DELETED_FUNCTION;

Diff for: lib/Format/TokenAnnotator.cpp

+15-6
Original file line numberDiff line numberDiff line change
@@ -523,11 +523,17 @@ class AnnotatingParser {
523523
if (CurrentToken != NULL)
524524
CurrentToken = CurrentToken->Next;
525525

526-
// Reset token type in case we have already looked at it and then recovered
527-
// from an error (e.g. failure to find the matching >).
528-
if (CurrentToken != NULL && CurrentToken->Type != TT_LambdaLSquare &&
529-
CurrentToken->Type != TT_ImplicitStringLiteral)
530-
CurrentToken->Type = TT_Unknown;
526+
if (CurrentToken != NULL) {
527+
// Reset token type in case we have already looked at it and then
528+
// recovered from an error (e.g. failure to find the matching >).
529+
if (CurrentToken->Type != TT_LambdaLSquare &&
530+
CurrentToken->Type != TT_ImplicitStringLiteral)
531+
CurrentToken->Type = TT_Unknown;
532+
if (CurrentToken->Role)
533+
CurrentToken->Role.reset(NULL);
534+
CurrentToken->FakeLParens.clear();
535+
CurrentToken->FakeRParens = 0;
536+
}
531537
}
532538

533539
/// \brief A struct to hold information valid in a specific context, e.g.
@@ -1482,10 +1488,13 @@ void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) {
14821488
<< " C=" << Tok->CanBreakBefore << " T=" << Tok->Type
14831489
<< " S=" << Tok->SpacesRequiredBefore
14841490
<< " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName()
1485-
<< " PPK=" << Tok->PackingKind << " FakeLParens=";
1491+
<< " L=" << Tok->TotalLength << " PPK=" << Tok->PackingKind
1492+
<< " FakeLParens=";
14861493
for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i)
14871494
llvm::errs() << Tok->FakeLParens[i] << "/";
14881495
llvm::errs() << " FakeRParens=" << Tok->FakeRParens << "\n";
1496+
if (Tok->Next == NULL)
1497+
assert(Tok == Line.Last);
14891498
Tok = Tok->Next;
14901499
}
14911500
llvm::errs() << "----\n";

0 commit comments

Comments
 (0)