Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Format/MacroCallReconstructor.cpp
35234 views
1
//===--- MacroCallReconstructor.cpp - Format C++ code -----------*- C++ -*-===//
2
//
3
// The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
///
10
/// \file
11
/// This file contains the implementation of MacroCallReconstructor, which fits
12
/// an reconstructed macro call to a parsed set of UnwrappedLines.
13
///
14
//===----------------------------------------------------------------------===//
15
16
#include "Macros.h"
17
18
#include "UnwrappedLineParser.h"
19
#include "clang/Basic/TokenKinds.h"
20
#include "llvm/ADT/DenseSet.h"
21
#include "llvm/Support/Debug.h"
22
#include <cassert>
23
24
#define DEBUG_TYPE "format-reconstruct"
25
26
namespace clang {
27
namespace format {
28
29
// Call \p Call for each token in the unwrapped line given, passing
30
// the token, its parent and whether it is the first token in the line.
31
template <typename T>
32
void forEachToken(const UnwrappedLine &Line, const T &Call,
33
FormatToken *Parent = nullptr) {
34
bool First = true;
35
for (const auto &N : Line.Tokens) {
36
Call(N.Tok, Parent, First, Line.Level);
37
First = false;
38
for (const auto &Child : N.Children)
39
forEachToken(Child, Call, N.Tok);
40
}
41
}
42
43
MacroCallReconstructor::MacroCallReconstructor(
44
unsigned Level,
45
const llvm::DenseMap<FormatToken *, std::unique_ptr<UnwrappedLine>>
46
&ActiveExpansions)
47
: Result(Level), IdToReconstructed(ActiveExpansions) {
48
Result.Tokens.push_back(std::make_unique<LineNode>());
49
ActiveReconstructedLines.push_back(&Result);
50
}
51
52
void MacroCallReconstructor::addLine(const UnwrappedLine &Line) {
53
assert(State != Finalized);
54
LLVM_DEBUG(llvm::dbgs() << "MCR: new line...\n");
55
forEachToken(Line, [&](FormatToken *Token, FormatToken *Parent, bool First,
56
unsigned Level) { add(Token, Parent, First, Level); });
57
assert(InProgress || finished());
58
}
59
60
UnwrappedLine MacroCallReconstructor::takeResult() && {
61
finalize();
62
assert(Result.Tokens.size() == 1 &&
63
Result.Tokens.front()->Children.size() == 1);
64
UnwrappedLine Final = createUnwrappedLine(
65
*Result.Tokens.front()->Children.front(), Result.Level);
66
assert(!Final.Tokens.empty());
67
return Final;
68
}
69
70
// Reconstruct the position of the next \p Token, given its parent \p
71
// ExpandedParent in the incoming unwrapped line. \p First specifies whether it
72
// is the first token in a given unwrapped line.
73
void MacroCallReconstructor::add(FormatToken *Token,
74
FormatToken *ExpandedParent, bool First,
75
unsigned Level) {
76
LLVM_DEBUG(
77
llvm::dbgs() << "MCR: Token: " << Token->TokenText << ", Parent: "
78
<< (ExpandedParent ? ExpandedParent->TokenText : "<null>")
79
<< ", First: " << First << "\n");
80
// In order to be able to find the correct parent in the reconstructed token
81
// stream, we need to continue the last open reconstruction until we find the
82
// given token if it is part of the reconstructed token stream.
83
//
84
// Note that hidden tokens can be part of the reconstructed stream in nested
85
// macro calls.
86
// For example, given
87
// #define C(x, y) x y
88
// #define B(x) {x}
89
// And the call:
90
// C(a, B(b))
91
// The outer macro call will be C(a, {b}), and the hidden token '}' can be
92
// found in the reconstructed token stream of that expansion level.
93
// In the expanded token stream
94
// a {b}
95
// 'b' is a child of '{'. We need to continue the open expansion of the ','
96
// in the call of 'C' in order to correctly set the ',' as the parent of '{',
97
// so we later set the spelled token 'b' as a child of the ','.
98
if (!ActiveExpansions.empty() && Token->MacroCtx &&
99
(Token->MacroCtx->Role != MR_Hidden ||
100
ActiveExpansions.size() != Token->MacroCtx->ExpandedFrom.size())) {
101
if (/*PassedMacroComma = */ reconstructActiveCallUntil(Token))
102
First = true;
103
}
104
105
prepareParent(ExpandedParent, First, Level);
106
107
if (Token->MacroCtx) {
108
// If this token was generated by a macro call, add the reconstructed
109
// equivalent of the token.
110
reconstruct(Token);
111
} else {
112
// Otherwise, we add it to the current line.
113
appendToken(Token);
114
}
115
}
116
117
// Adjusts the stack of active reconstructed lines so we're ready to push
118
// tokens. The tokens to be pushed are children of ExpandedParent in the
119
// expanded code.
120
//
121
// This may entail:
122
// - creating a new line, if the parent is on the active line
123
// - popping active lines, if the parent is further up the stack
124
//
125
// Postcondition:
126
// ActiveReconstructedLines.back() is the line that has \p ExpandedParent or its
127
// reconstructed replacement token as a parent (when possible) - that is, the
128
// last token in \c ActiveReconstructedLines[ActiveReconstructedLines.size()-2]
129
// is the parent of ActiveReconstructedLines.back() in the reconstructed
130
// unwrapped line.
131
void MacroCallReconstructor::prepareParent(FormatToken *ExpandedParent,
132
bool NewLine, unsigned Level) {
133
LLVM_DEBUG({
134
llvm::dbgs() << "ParentMap:\n";
135
debugParentMap();
136
});
137
// We want to find the parent in the new unwrapped line, where the expanded
138
// parent might have been replaced during reconstruction.
139
FormatToken *Parent = getParentInResult(ExpandedParent);
140
LLVM_DEBUG(llvm::dbgs() << "MCR: New parent: "
141
<< (Parent ? Parent->TokenText : "<null>") << "\n");
142
143
FormatToken *OpenMacroParent = nullptr;
144
if (!MacroCallStructure.empty()) {
145
// Inside a macro expansion, it is possible to lose track of the correct
146
// parent - either because it is already popped, for example because it was
147
// in a different macro argument (e.g. M({, })), or when we work on invalid
148
// code.
149
// Thus, we use the innermost macro call's parent as the parent at which
150
// we stop; this allows us to stay within the macro expansion and keeps
151
// any problems confined to the extent of the macro call.
152
OpenMacroParent =
153
getParentInResult(MacroCallStructure.back().MacroCallLParen);
154
LLVM_DEBUG(llvm::dbgs()
155
<< "MacroCallLParen: "
156
<< MacroCallStructure.back().MacroCallLParen->TokenText
157
<< ", OpenMacroParent: "
158
<< (OpenMacroParent ? OpenMacroParent->TokenText : "<null>")
159
<< "\n");
160
}
161
if (NewLine ||
162
(!ActiveReconstructedLines.back()->Tokens.empty() &&
163
Parent == ActiveReconstructedLines.back()->Tokens.back()->Tok)) {
164
// If we are at the first token in a new line, we want to also
165
// create a new line in the resulting reconstructed unwrapped line.
166
while (ActiveReconstructedLines.back()->Tokens.empty() ||
167
(Parent != ActiveReconstructedLines.back()->Tokens.back()->Tok &&
168
ActiveReconstructedLines.back()->Tokens.back()->Tok !=
169
OpenMacroParent)) {
170
ActiveReconstructedLines.pop_back();
171
assert(!ActiveReconstructedLines.empty());
172
}
173
assert(!ActiveReconstructedLines.empty());
174
ActiveReconstructedLines.back()->Tokens.back()->Children.push_back(
175
std::make_unique<ReconstructedLine>(Level));
176
ActiveReconstructedLines.push_back(
177
&*ActiveReconstructedLines.back()->Tokens.back()->Children.back());
178
} else if (parentLine().Tokens.back()->Tok != Parent) {
179
// If we're not the first token in a new line, pop lines until we find
180
// the child of \c Parent in the stack.
181
while (Parent != parentLine().Tokens.back()->Tok &&
182
parentLine().Tokens.back()->Tok &&
183
parentLine().Tokens.back()->Tok != OpenMacroParent) {
184
ActiveReconstructedLines.pop_back();
185
assert(!ActiveReconstructedLines.empty());
186
}
187
}
188
assert(!ActiveReconstructedLines.empty());
189
}
190
191
// For a given \p Parent in the incoming expanded token stream, find the
192
// corresponding parent in the output.
193
FormatToken *MacroCallReconstructor::getParentInResult(FormatToken *Parent) {
194
FormatToken *Mapped = SpelledParentToReconstructedParent.lookup(Parent);
195
if (!Mapped)
196
return Parent;
197
for (; Mapped; Mapped = SpelledParentToReconstructedParent.lookup(Parent))
198
Parent = Mapped;
199
// If we use a different token than the parent in the expanded token stream
200
// as parent, mark it as a special parent, so the formatting code knows it
201
// needs to have its children formatted.
202
Parent->MacroParent = true;
203
return Parent;
204
}
205
206
// Reconstruct a \p Token that was expanded from a macro call.
207
void MacroCallReconstructor::reconstruct(FormatToken *Token) {
208
assert(Token->MacroCtx);
209
// A single token can be the only result of a macro call:
210
// Given: #define ID(x, y) ;
211
// And the call: ID(<some>, <tokens>)
212
// ';' in the expanded stream will reconstruct all of ID(<some>, <tokens>).
213
if (Token->MacroCtx->StartOfExpansion) {
214
startReconstruction(Token);
215
// If the order of tokens in the expanded token stream is not the
216
// same as the order of tokens in the reconstructed stream, we need
217
// to reconstruct tokens that arrive later in the stream.
218
if (Token->MacroCtx->Role != MR_Hidden)
219
reconstructActiveCallUntil(Token);
220
}
221
assert(!ActiveExpansions.empty());
222
if (ActiveExpansions.back().SpelledI != ActiveExpansions.back().SpelledE) {
223
assert(ActiveExpansions.size() == Token->MacroCtx->ExpandedFrom.size());
224
if (Token->MacroCtx->Role != MR_Hidden) {
225
// The current token in the reconstructed token stream must be the token
226
// we're looking for - we either arrive here after startReconstruction,
227
// which initiates the stream to the first token, or after
228
// continueReconstructionUntil skipped until the expected token in the
229
// reconstructed stream at the start of add(...).
230
assert(ActiveExpansions.back().SpelledI->Tok == Token);
231
processNextReconstructed();
232
} else if (!currentLine()->Tokens.empty()) {
233
// Map all hidden tokens to the last visible token in the output.
234
// If the hidden token is a parent, we'll use the last visible
235
// token as the parent of the hidden token's children.
236
SpelledParentToReconstructedParent[Token] =
237
currentLine()->Tokens.back()->Tok;
238
} else {
239
for (auto I = ActiveReconstructedLines.rbegin(),
240
E = ActiveReconstructedLines.rend();
241
I != E; ++I) {
242
if (!(*I)->Tokens.empty()) {
243
SpelledParentToReconstructedParent[Token] = (*I)->Tokens.back()->Tok;
244
break;
245
}
246
}
247
}
248
}
249
if (Token->MacroCtx->EndOfExpansion)
250
endReconstruction(Token);
251
}
252
253
// Given a \p Token that starts an expansion, reconstruct the beginning of the
254
// macro call.
255
// For example, given: #define ID(x) x
256
// And the call: ID(int a)
257
// Reconstructs: ID(
258
void MacroCallReconstructor::startReconstruction(FormatToken *Token) {
259
assert(Token->MacroCtx);
260
assert(!Token->MacroCtx->ExpandedFrom.empty());
261
assert(ActiveExpansions.size() <= Token->MacroCtx->ExpandedFrom.size());
262
#ifndef NDEBUG
263
// Check that the token's reconstruction stack matches our current
264
// reconstruction stack.
265
for (size_t I = 0; I < ActiveExpansions.size(); ++I) {
266
assert(ActiveExpansions[I].ID ==
267
Token->MacroCtx
268
->ExpandedFrom[Token->MacroCtx->ExpandedFrom.size() - 1 - I]);
269
}
270
#endif
271
// Start reconstruction for all calls for which this token is the first token
272
// generated by the call.
273
// Note that the token's expanded from stack is inside-to-outside, and the
274
// expansions for which this token is not the first are the outermost ones.
275
ArrayRef<FormatToken *> StartedMacros =
276
ArrayRef(Token->MacroCtx->ExpandedFrom)
277
.drop_back(ActiveExpansions.size());
278
assert(StartedMacros.size() == Token->MacroCtx->StartOfExpansion);
279
// We reconstruct macro calls outside-to-inside.
280
for (FormatToken *ID : llvm::reverse(StartedMacros)) {
281
// We found a macro call to be reconstructed; the next time our
282
// reconstruction stack is empty we know we finished an reconstruction.
283
#ifndef NDEBUG
284
State = InProgress;
285
#endif
286
// Put the reconstructed macro call's token into our reconstruction stack.
287
auto IU = IdToReconstructed.find(ID);
288
assert(IU != IdToReconstructed.end());
289
ActiveExpansions.push_back(
290
{ID, IU->second->Tokens.begin(), IU->second->Tokens.end()});
291
// Process the macro call's identifier.
292
processNextReconstructed();
293
if (ActiveExpansions.back().SpelledI == ActiveExpansions.back().SpelledE)
294
continue;
295
if (ActiveExpansions.back().SpelledI->Tok->is(tok::l_paren)) {
296
// Process the optional opening parenthesis.
297
processNextReconstructed();
298
}
299
}
300
}
301
302
// Add all tokens in the reconstruction stream to the output until we find the
303
// given \p Token.
304
bool MacroCallReconstructor::reconstructActiveCallUntil(FormatToken *Token) {
305
assert(!ActiveExpansions.empty());
306
bool PassedMacroComma = false;
307
// FIXME: If Token was already expanded earlier, due to
308
// a change in order, we will not find it, but need to
309
// skip it.
310
while (ActiveExpansions.back().SpelledI != ActiveExpansions.back().SpelledE &&
311
ActiveExpansions.back().SpelledI->Tok != Token) {
312
PassedMacroComma = processNextReconstructed() || PassedMacroComma;
313
}
314
return PassedMacroComma;
315
}
316
317
// End all reconstructions for which \p Token is the final token.
318
void MacroCallReconstructor::endReconstruction(FormatToken *Token) {
319
assert(Token->MacroCtx &&
320
(ActiveExpansions.size() >= Token->MacroCtx->EndOfExpansion));
321
for (size_t I = 0; I < Token->MacroCtx->EndOfExpansion; ++I) {
322
LLVM_DEBUG([&] {
323
// Check all remaining tokens but the final closing parenthesis and
324
// optional trailing comment were already reconstructed at an inner
325
// expansion level.
326
for (auto T = ActiveExpansions.back().SpelledI;
327
T != ActiveExpansions.back().SpelledE; ++T) {
328
FormatToken *Token = T->Tok;
329
bool ClosingParen = (std::next(T) == ActiveExpansions.back().SpelledE ||
330
std::next(T)->Tok->isTrailingComment()) &&
331
!Token->MacroCtx && Token->is(tok::r_paren);
332
bool TrailingComment = Token->isTrailingComment();
333
bool PreviousLevel =
334
Token->MacroCtx &&
335
(ActiveExpansions.size() < Token->MacroCtx->ExpandedFrom.size());
336
if (!ClosingParen && !TrailingComment && !PreviousLevel)
337
llvm::dbgs() << "At token: " << Token->TokenText << "\n";
338
// In addition to the following cases, we can also run into this
339
// when a macro call had more arguments than expected; in that case,
340
// the comma and the remaining tokens in the macro call will
341
// potentially end up in the line when we finish the expansion.
342
// FIXME: Add the information which arguments are unused, and assert
343
// one of the cases below plus reconstructed macro argument tokens.
344
// assert(ClosingParen || TrailingComment || PreviousLevel);
345
}
346
}());
347
// Handle the remaining open tokens:
348
// - expand the closing parenthesis, if it exists, including an optional
349
// trailing comment
350
// - handle tokens that were already reconstructed at an inner expansion
351
// level
352
// - handle tokens when a macro call had more than the expected number of
353
// arguments, i.e. when #define M(x) is called as M(a, b, c) we'll end
354
// up with the sequence ", b, c)" being open at the end of the
355
// reconstruction; we want to gracefully handle that case
356
//
357
// FIXME: See the above debug-check for what we will need to do to be
358
// able to assert this.
359
for (auto T = ActiveExpansions.back().SpelledI;
360
T != ActiveExpansions.back().SpelledE; ++T) {
361
processNextReconstructed();
362
}
363
ActiveExpansions.pop_back();
364
}
365
}
366
367
void MacroCallReconstructor::debugParentMap() const {
368
llvm::DenseSet<FormatToken *> Values;
369
for (const auto &P : SpelledParentToReconstructedParent)
370
Values.insert(P.second);
371
372
for (const auto &P : SpelledParentToReconstructedParent) {
373
if (Values.contains(P.first))
374
continue;
375
llvm::dbgs() << (P.first ? P.first->TokenText : "<null>");
376
for (auto I = SpelledParentToReconstructedParent.find(P.first),
377
E = SpelledParentToReconstructedParent.end();
378
I != E; I = SpelledParentToReconstructedParent.find(I->second)) {
379
llvm::dbgs() << " -> " << (I->second ? I->second->TokenText : "<null>");
380
}
381
llvm::dbgs() << "\n";
382
}
383
}
384
385
// If visible, add the next token of the reconstructed token sequence to the
386
// output. Returns whether reconstruction passed a comma that is part of a
387
// macro call.
388
bool MacroCallReconstructor::processNextReconstructed() {
389
FormatToken *Token = ActiveExpansions.back().SpelledI->Tok;
390
++ActiveExpansions.back().SpelledI;
391
if (Token->MacroCtx) {
392
// Skip tokens that are not part of the macro call.
393
if (Token->MacroCtx->Role == MR_Hidden)
394
return false;
395
// Skip tokens we already expanded during an inner reconstruction.
396
// For example, given: #define ID(x) {x}
397
// And the call: ID(ID(f))
398
// We get two reconstructions:
399
// ID(f) -> {f}
400
// ID({f}) -> {{f}}
401
// We reconstruct f during the first reconstruction, and skip it during the
402
// second reconstruction.
403
if (ActiveExpansions.size() < Token->MacroCtx->ExpandedFrom.size())
404
return false;
405
}
406
// Tokens that do not have a macro context are tokens in that are part of the
407
// macro call that have not taken part in expansion.
408
if (!Token->MacroCtx) {
409
// Put the parentheses and commas of a macro call into the same line;
410
// if the arguments produce new unwrapped lines, they will become children
411
// of the corresponding opening parenthesis or comma tokens in the
412
// reconstructed call.
413
if (Token->is(tok::l_paren)) {
414
MacroCallStructure.push_back(MacroCallState(
415
currentLine(), parentLine().Tokens.back()->Tok, Token));
416
// All tokens that are children of the previous line's last token in the
417
// reconstructed token stream will now be children of the l_paren token.
418
// For example, for the line containing the macro calls:
419
// auto x = ID({ID(2)});
420
// We will build up a map <null> -> ( -> ( with the first and second
421
// l_paren of the macro call respectively. New lines that come in with a
422
// <null> parent will then become children of the l_paren token of the
423
// currently innermost macro call.
424
SpelledParentToReconstructedParent[MacroCallStructure.back()
425
.ParentLastToken] = Token;
426
appendToken(Token);
427
prepareParent(Token, /*NewLine=*/true,
428
MacroCallStructure.back().Line->Level);
429
Token->MacroParent = true;
430
return false;
431
}
432
if (!MacroCallStructure.empty()) {
433
if (Token->is(tok::comma)) {
434
// Make new lines inside the next argument children of the comma token.
435
SpelledParentToReconstructedParent
436
[MacroCallStructure.back().Line->Tokens.back()->Tok] = Token;
437
Token->MacroParent = true;
438
appendToken(Token, MacroCallStructure.back().Line);
439
prepareParent(Token, /*NewLine=*/true,
440
MacroCallStructure.back().Line->Level);
441
return true;
442
}
443
if (Token->is(tok::r_paren)) {
444
appendToken(Token, MacroCallStructure.back().Line);
445
SpelledParentToReconstructedParent.erase(
446
MacroCallStructure.back().ParentLastToken);
447
MacroCallStructure.pop_back();
448
return false;
449
}
450
}
451
}
452
// Note that any tokens that are tagged with MR_None have been passed as
453
// arguments to the macro that have not been expanded, for example:
454
// Given: #define ID(X) x
455
// When calling: ID(a, b)
456
// 'b' will be part of the reconstructed token stream, but tagged MR_None.
457
// Given that erroring out in this case would be disruptive, we continue
458
// pushing the (unformatted) token.
459
// FIXME: This can lead to unfortunate formatting decisions - give the user
460
// a hint that their macro definition is broken.
461
appendToken(Token);
462
return false;
463
}
464
465
void MacroCallReconstructor::finalize() {
466
#ifndef NDEBUG
467
assert(State != Finalized && finished());
468
State = Finalized;
469
#endif
470
471
// We created corresponding unwrapped lines for each incoming line as children
472
// the the toplevel null token.
473
assert(Result.Tokens.size() == 1 && !Result.Tokens.front()->Children.empty());
474
LLVM_DEBUG({
475
llvm::dbgs() << "Finalizing reconstructed lines:\n";
476
debug(Result, 0);
477
});
478
479
// The first line becomes the top level line in the resulting unwrapped line.
480
LineNode &Top = *Result.Tokens.front();
481
auto *I = Top.Children.begin();
482
// Every subsequent line will become a child of the last token in the previous
483
// line, which is the token prior to the first token in the line.
484
LineNode *Last = (*I)->Tokens.back().get();
485
++I;
486
for (auto *E = Top.Children.end(); I != E; ++I) {
487
assert(Last->Children.empty());
488
Last->Children.push_back(std::move(*I));
489
490
// Mark the previous line's last token as generated by a macro expansion
491
// so the formatting algorithm can take that into account.
492
Last->Tok->MacroParent = true;
493
494
Last = Last->Children.back()->Tokens.back().get();
495
}
496
Top.Children.resize(1);
497
}
498
499
void MacroCallReconstructor::appendToken(FormatToken *Token,
500
ReconstructedLine *L) {
501
L = L ? L : currentLine();
502
LLVM_DEBUG(llvm::dbgs() << "-> " << Token->TokenText << "\n");
503
L->Tokens.push_back(std::make_unique<LineNode>(Token));
504
}
505
506
UnwrappedLine
507
MacroCallReconstructor::createUnwrappedLine(const ReconstructedLine &Line,
508
int Level) {
509
UnwrappedLine Result;
510
Result.Level = Level;
511
for (const auto &N : Line.Tokens) {
512
Result.Tokens.push_back(N->Tok);
513
UnwrappedLineNode &Current = Result.Tokens.back();
514
auto NumChildren =
515
std::count_if(N->Children.begin(), N->Children.end(),
516
[](const auto &Child) { return !Child->Tokens.empty(); });
517
if (NumChildren == 1 && Current.Tok->isOneOf(tok::l_paren, tok::comma)) {
518
// If we only have one child, and the child is due to a macro expansion
519
// (either attached to a left parenthesis or comma), merge the child into
520
// the current line to prevent forced breaks for macro arguments.
521
auto *Child = std::find_if(
522
N->Children.begin(), N->Children.end(),
523
[](const auto &Child) { return !Child->Tokens.empty(); });
524
auto Line = createUnwrappedLine(**Child, Level);
525
Result.Tokens.splice(Result.Tokens.end(), Line.Tokens);
526
} else if (NumChildren > 0) {
527
// When there are multiple children with different indent, make sure that
528
// we indent them:
529
// 1. One level below the current line's level.
530
// 2. At the correct level relative to each other.
531
unsigned MinChildLevel =
532
std::min_element(N->Children.begin(), N->Children.end(),
533
[](const auto &E1, const auto &E2) {
534
return E1->Level < E2->Level;
535
})
536
->get()
537
->Level;
538
for (const auto &Child : N->Children) {
539
if (Child->Tokens.empty())
540
continue;
541
Current.Children.push_back(createUnwrappedLine(
542
*Child, Level + 1 + (Child->Level - MinChildLevel)));
543
}
544
}
545
}
546
return Result;
547
}
548
549
void MacroCallReconstructor::debug(const ReconstructedLine &Line, int Level) {
550
for (int i = 0; i < Level; ++i)
551
llvm::dbgs() << " ";
552
for (const auto &N : Line.Tokens) {
553
if (!N)
554
continue;
555
if (N->Tok)
556
llvm::dbgs() << N->Tok->TokenText << " ";
557
for (const auto &Child : N->Children) {
558
llvm::dbgs() << "\n";
559
debug(*Child, Level + 1);
560
for (int i = 0; i < Level; ++i)
561
llvm::dbgs() << " ";
562
}
563
}
564
llvm::dbgs() << "\n";
565
}
566
567
MacroCallReconstructor::ReconstructedLine &
568
MacroCallReconstructor::parentLine() {
569
return **std::prev(std::prev(ActiveReconstructedLines.end()));
570
}
571
572
MacroCallReconstructor::ReconstructedLine *
573
MacroCallReconstructor::currentLine() {
574
return ActiveReconstructedLines.back();
575
}
576
577
MacroCallReconstructor::MacroCallState::MacroCallState(
578
MacroCallReconstructor::ReconstructedLine *Line,
579
FormatToken *ParentLastToken, FormatToken *MacroCallLParen)
580
: Line(Line), ParentLastToken(ParentLastToken),
581
MacroCallLParen(MacroCallLParen) {
582
LLVM_DEBUG(
583
llvm::dbgs() << "ParentLastToken: "
584
<< (ParentLastToken ? ParentLastToken->TokenText : "<null>")
585
<< "\n");
586
587
assert(MacroCallLParen->is(tok::l_paren));
588
}
589
590
} // namespace format
591
} // namespace clang
592
593