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>
forEachToken(const UnwrappedLine & Line,const T & Call,FormatToken * Parent=nullptr)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);
37 First = false;
38 for (const auto &Child : N.Children) {
39 forEachToken(Child, Call, N.Tok);
40 }
41 }
42 }
43
MacroCallReconstructor(unsigned Level,const llvm::DenseMap<FormatToken *,std::unique_ptr<UnwrappedLine>> & ActiveExpansions)44 MacroCallReconstructor::MacroCallReconstructor(
45 unsigned Level,
46 const llvm::DenseMap<FormatToken *, std::unique_ptr<UnwrappedLine>>
47 &ActiveExpansions)
48 : Level(Level), IdToReconstructed(ActiveExpansions) {
49 Result.Tokens.push_back(std::make_unique<LineNode>());
50 ActiveReconstructedLines.push_back(&Result);
51 }
52
addLine(const UnwrappedLine & Line)53 void MacroCallReconstructor::addLine(const UnwrappedLine &Line) {
54 assert(State != Finalized);
55 LLVM_DEBUG(llvm::dbgs() << "MCR: new line...\n");
56 forEachToken(Line, [&](FormatToken *Token, FormatToken *Parent, bool First) {
57 add(Token, Parent, First);
58 });
59 assert(InProgress || finished());
60 }
61
takeResult()62 UnwrappedLine MacroCallReconstructor::takeResult() && {
63 finalize();
64 assert(Result.Tokens.size() == 1 && Result.Tokens.front()->Children.size() == 1);
65 UnwrappedLine Final =
66 createUnwrappedLine(*Result.Tokens.front()->Children.front(), Level);
67 assert(!Final.Tokens.empty());
68 return Final;
69 }
70
71 // Reconstruct the position of the next \p Token, given its parent \p
72 // ExpandedParent in the incoming unwrapped line. \p First specifies whether it
73 // is the first token in a given unwrapped line.
add(FormatToken * Token,FormatToken * ExpandedParent,bool First)74 void MacroCallReconstructor::add(FormatToken *Token,
75 FormatToken *ExpandedParent, bool First) {
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);
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.
prepareParent(FormatToken * ExpandedParent,bool NewLine)131 void MacroCallReconstructor::prepareParent(FormatToken *ExpandedParent,
132 bool NewLine) {
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>());
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.
getParentInResult(FormatToken * Parent)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 }
200 // If we use a different token than the parent in the expanded token stream
201 // as parent, mark it as a special parent, so the formatting code knows it
202 // needs to have its children formatted.
203 Parent->MacroParent = true;
204 return Parent;
205 }
206
207 // Reconstruct a \p Token that was expanded from a macro call.
reconstruct(FormatToken * Token)208 void MacroCallReconstructor::reconstruct(FormatToken *Token) {
209 assert(Token->MacroCtx);
210 // A single token can be the only result of a macro call:
211 // Given: #define ID(x, y) ;
212 // And the call: ID(<some>, <tokens>)
213 // ';' in the expanded stream will reconstruct all of ID(<some>, <tokens>).
214 if (Token->MacroCtx->StartOfExpansion) {
215 startReconstruction(Token);
216 // If the order of tokens in the expanded token stream is not the
217 // same as the order of tokens in the reconstructed stream, we need
218 // to reconstruct tokens that arrive later in the stream.
219 if (Token->MacroCtx->Role != MR_Hidden) {
220 reconstructActiveCallUntil(Token);
221 }
222 }
223 assert(!ActiveExpansions.empty());
224 if (ActiveExpansions.back().SpelledI != ActiveExpansions.back().SpelledE) {
225 assert(ActiveExpansions.size() == Token->MacroCtx->ExpandedFrom.size());
226 if (Token->MacroCtx->Role != MR_Hidden) {
227 // The current token in the reconstructed token stream must be the token
228 // we're looking for - we either arrive here after startReconstruction,
229 // which initiates the stream to the first token, or after
230 // continueReconstructionUntil skipped until the expected token in the
231 // reconstructed stream at the start of add(...).
232 assert(ActiveExpansions.back().SpelledI->Tok == Token);
233 processNextReconstructed();
234 } else if (!currentLine()->Tokens.empty()) {
235 // Map all hidden tokens to the last visible token in the output.
236 // If the hidden token is a parent, we'll use the last visible
237 // token as the parent of the hidden token's children.
238 SpelledParentToReconstructedParent[Token] =
239 currentLine()->Tokens.back()->Tok;
240 } else {
241 for (auto I = ActiveReconstructedLines.rbegin(),
242 E = ActiveReconstructedLines.rend();
243 I != E; ++I) {
244 if (!(*I)->Tokens.empty()) {
245 SpelledParentToReconstructedParent[Token] = (*I)->Tokens.back()->Tok;
246 break;
247 }
248 }
249 }
250 }
251 if (Token->MacroCtx->EndOfExpansion)
252 endReconstruction(Token);
253 }
254
255 // Given a \p Token that starts an expansion, reconstruct the beginning of the
256 // macro call.
257 // For example, given: #define ID(x) x
258 // And the call: ID(int a)
259 // Reconstructs: ID(
startReconstruction(FormatToken * Token)260 void MacroCallReconstructor::startReconstruction(FormatToken *Token) {
261 assert(Token->MacroCtx);
262 assert(!Token->MacroCtx->ExpandedFrom.empty());
263 assert(ActiveExpansions.size() <= Token->MacroCtx->ExpandedFrom.size());
264 #ifndef NDEBUG
265 // Check that the token's reconstruction stack matches our current
266 // reconstruction stack.
267 for (size_t I = 0; I < ActiveExpansions.size(); ++I) {
268 assert(ActiveExpansions[I].ID ==
269 Token->MacroCtx
270 ->ExpandedFrom[Token->MacroCtx->ExpandedFrom.size() - 1 - I]);
271 }
272 #endif
273 // Start reconstruction for all calls for which this token is the first token
274 // generated by the call.
275 // Note that the token's expanded from stack is inside-to-outside, and the
276 // expansions for which this token is not the first are the outermost ones.
277 ArrayRef<FormatToken *> StartedMacros =
278 makeArrayRef(Token->MacroCtx->ExpandedFrom)
279 .drop_back(ActiveExpansions.size());
280 assert(StartedMacros.size() == Token->MacroCtx->StartOfExpansion);
281 // We reconstruct macro calls outside-to-inside.
282 for (FormatToken *ID : llvm::reverse(StartedMacros)) {
283 // We found a macro call to be reconstructed; the next time our
284 // reconstruction stack is empty we know we finished an reconstruction.
285 #ifndef NDEBUG
286 State = InProgress;
287 #endif
288 // Put the reconstructed macro call's token into our reconstruction stack.
289 auto IU = IdToReconstructed.find(ID);
290 assert(IU != IdToReconstructed.end());
291 ActiveExpansions.push_back(
292 {ID, IU->second->Tokens.begin(), IU->second->Tokens.end()});
293 // Process the macro call's identifier.
294 processNextReconstructed();
295 if (ActiveExpansions.back().SpelledI == ActiveExpansions.back().SpelledE)
296 continue;
297 if (ActiveExpansions.back().SpelledI->Tok->is(tok::l_paren)) {
298 // Process the optional opening parenthesis.
299 processNextReconstructed();
300 }
301 }
302 }
303
304 // Add all tokens in the reconstruction stream to the output until we find the
305 // given \p Token.
reconstructActiveCallUntil(FormatToken * Token)306 bool MacroCallReconstructor::reconstructActiveCallUntil(FormatToken *Token) {
307 assert(!ActiveExpansions.empty());
308 bool PassedMacroComma = false;
309 // FIXME: If Token was already expanded earlier, due to
310 // a change in order, we will not find it, but need to
311 // skip it.
312 while (ActiveExpansions.back().SpelledI != ActiveExpansions.back().SpelledE &&
313 ActiveExpansions.back().SpelledI->Tok != Token) {
314 PassedMacroComma = processNextReconstructed() || PassedMacroComma;
315 }
316 return PassedMacroComma;
317 }
318
319 // End all reconstructions for which \p Token is the final token.
endReconstruction(FormatToken * Token)320 void MacroCallReconstructor::endReconstruction(FormatToken *Token) {
321 assert(Token->MacroCtx &&
322 (ActiveExpansions.size() >= Token->MacroCtx->EndOfExpansion));
323 for (size_t I = 0; I < Token->MacroCtx->EndOfExpansion; ++I) {
324 #ifndef NDEBUG
325 // Check all remaining tokens but the final closing parenthesis and optional
326 // trailing comment were already reconstructed at an inner expansion level.
327 for (auto T = ActiveExpansions.back().SpelledI;
328 T != ActiveExpansions.back().SpelledE; ++T) {
329 FormatToken *Token = T->Tok;
330 bool ClosingParen = (std::next(T) == ActiveExpansions.back().SpelledE ||
331 std::next(T)->Tok->isTrailingComment()) &&
332 !Token->MacroCtx && Token->is(tok::r_paren);
333 bool TrailingComment = Token->isTrailingComment();
334 bool PreviousLevel =
335 Token->MacroCtx &&
336 (ActiveExpansions.size() < Token->MacroCtx->ExpandedFrom.size());
337 if (!ClosingParen && !TrailingComment && !PreviousLevel) {
338 llvm::dbgs() << "At token: " << Token->TokenText << "\n";
339 }
340 // In addition to the following cases, we can also run into this
341 // when a macro call had more arguments than expected; in that case,
342 // the comma and the remaining tokens in the macro call will potentially
343 // end up in the line when we finish the expansion.
344 // FIXME: Add the information which arguments are unused, and assert
345 // one of the cases below plus reconstructed macro argument tokens.
346 // assert(ClosingParen || TrailingComment || PreviousLevel);
347 }
348 #endif
349 // Handle the remaining open tokens:
350 // - expand the closing parenthesis, if it exists, including an optional
351 // trailing comment
352 // - handle tokens that were already reconstructed at an inner expansion
353 // level
354 // - handle tokens when a macro call had more than the expected number of
355 // arguments, i.e. when #define M(x) is called as M(a, b, c) we'll end
356 // up with the sequence ", b, c)" being open at the end of the
357 // reconstruction; we want to gracefully handle that case
358 //
359 // FIXME: See the above debug-check for what we will need to do to be
360 // able to assert this.
361 for (auto T = ActiveExpansions.back().SpelledI;
362 T != ActiveExpansions.back().SpelledE; ++T) {
363 processNextReconstructed();
364 }
365 ActiveExpansions.pop_back();
366 }
367 }
368
debugParentMap() const369 void MacroCallReconstructor::debugParentMap() const {
370 llvm::DenseSet<FormatToken *> Values;
371 for (const auto &P : SpelledParentToReconstructedParent)
372 Values.insert(P.second);
373
374 for (const auto &P : SpelledParentToReconstructedParent) {
375 if (Values.contains(P.first))
376 continue;
377 llvm::dbgs() << (P.first ? P.first->TokenText : "<null>");
378 for (auto I = SpelledParentToReconstructedParent.find(P.first),
379 E = SpelledParentToReconstructedParent.end();
380 I != E; I = SpelledParentToReconstructedParent.find(I->second)) {
381 llvm::dbgs() << " -> " << (I->second ? I->second->TokenText : "<null>");
382 }
383 llvm::dbgs() << "\n";
384 }
385 }
386
387 // If visible, add the next token of the reconstructed token sequence to the
388 // output. Returns whether reconstruction passed a comma that is part of a
389 // macro call.
processNextReconstructed()390 bool MacroCallReconstructor::processNextReconstructed() {
391 FormatToken *Token = ActiveExpansions.back().SpelledI->Tok;
392 ++ActiveExpansions.back().SpelledI;
393 if (Token->MacroCtx) {
394 // Skip tokens that are not part of the macro call.
395 if (Token->MacroCtx->Role == MR_Hidden) {
396 return false;
397 }
398 // Skip tokens we already expanded during an inner reconstruction.
399 // For example, given: #define ID(x) {x}
400 // And the call: ID(ID(f))
401 // We get two reconstructions:
402 // ID(f) -> {f}
403 // ID({f}) -> {{f}}
404 // We reconstruct f during the first reconstruction, and skip it during the
405 // second reconstruction.
406 if (ActiveExpansions.size() < Token->MacroCtx->ExpandedFrom.size()) {
407 return false;
408 }
409 }
410 // Tokens that do not have a macro context are tokens in that are part of the
411 // macro call that have not taken part in expansion.
412 if (!Token->MacroCtx) {
413 // Put the parentheses and commas of a macro call into the same line;
414 // if the arguments produce new unwrapped lines, they will become children
415 // of the corresponding opening parenthesis or comma tokens in the
416 // reconstructed call.
417 if (Token->is(tok::l_paren)) {
418 MacroCallStructure.push_back(MacroCallState(
419 currentLine(), parentLine().Tokens.back()->Tok, Token));
420 // All tokens that are children of the previous line's last token in the
421 // reconstructed token stream will now be children of the l_paren token.
422 // For example, for the line containing the macro calls:
423 // auto x = ID({ID(2)});
424 // We will build up a map <null> -> ( -> ( with the first and second
425 // l_paren of the macro call respectively. New lines that come in with a
426 // <null> parent will then become children of the l_paren token of the
427 // currently innermost macro call.
428 SpelledParentToReconstructedParent[MacroCallStructure.back()
429 .ParentLastToken] = Token;
430 appendToken(Token);
431 prepareParent(Token, /*NewLine=*/true);
432 Token->MacroParent = true;
433 return false;
434 }
435 if (!MacroCallStructure.empty()) {
436 if (Token->is(tok::comma)) {
437 // Make new lines inside the next argument children of the comma token.
438 SpelledParentToReconstructedParent
439 [MacroCallStructure.back().Line->Tokens.back()->Tok] = Token;
440 Token->MacroParent = true;
441 appendToken(Token, MacroCallStructure.back().Line);
442 prepareParent(Token, /*NewLine=*/true);
443 return true;
444 }
445 if (Token->is(tok::r_paren)) {
446 appendToken(Token, MacroCallStructure.back().Line);
447 SpelledParentToReconstructedParent.erase(
448 MacroCallStructure.back().ParentLastToken);
449 MacroCallStructure.pop_back();
450 return false;
451 }
452 }
453 }
454 // Note that any tokens that are tagged with MR_None have been passed as
455 // arguments to the macro that have not been expanded, for example:
456 // Given: #define ID(X) x
457 // When calling: ID(a, b)
458 // 'b' will be part of the reconstructed token stream, but tagged MR_None.
459 // Given that erroring out in this case would be disruptive, we continue
460 // pushing the (unformatted) token.
461 // FIXME: This can lead to unfortunate formatting decisions - give the user
462 // a hint that their macro definition is broken.
463 appendToken(Token);
464 return false;
465 }
466
finalize()467 void MacroCallReconstructor::finalize() {
468 #ifndef NDEBUG
469 assert(State != Finalized && finished());
470 State = Finalized;
471 #endif
472
473 // We created corresponding unwrapped lines for each incoming line as children
474 // the the toplevel null token.
475 assert(Result.Tokens.size() == 1 && !Result.Tokens.front()->Children.empty());
476 LLVM_DEBUG({
477 llvm::dbgs() << "Finalizing reconstructed lines:\n";
478 debug(Result, 0);
479 });
480
481 // The first line becomes the top level line in the resulting unwrapped line.
482 LineNode &Top = *Result.Tokens.front();
483 auto *I = Top.Children.begin();
484 // Every subsequent line will become a child of the last token in the previous
485 // line, which is the token prior to the first token in the line.
486 LineNode *Last = (*I)->Tokens.back().get();
487 ++I;
488 for (auto *E = Top.Children.end(); I != E; ++I) {
489 assert(Last->Children.empty());
490 Last->Children.push_back(std::move(*I));
491
492 // Mark the previous line's last token as generated by a macro expansion
493 // so the formatting algorithm can take that into account.
494 Last->Tok->MacroParent = true;
495
496 Last = Last->Children.back()->Tokens.back().get();
497 }
498 Top.Children.resize(1);
499 }
500
appendToken(FormatToken * Token,ReconstructedLine * L)501 void MacroCallReconstructor::appendToken(FormatToken *Token,
502 ReconstructedLine *L) {
503 L = L ? L : currentLine();
504 LLVM_DEBUG(llvm::dbgs() << "-> " << Token->TokenText << "\n");
505 L->Tokens.push_back(std::make_unique<LineNode>(Token));
506 }
507
508 UnwrappedLine
createUnwrappedLine(const ReconstructedLine & Line,int Level)509 MacroCallReconstructor::createUnwrappedLine(const ReconstructedLine &Line,
510 int Level) {
511 UnwrappedLine Result;
512 Result.Level = Level;
513 for (const auto &N : Line.Tokens) {
514 Result.Tokens.push_back(N->Tok);
515 UnwrappedLineNode &Current = Result.Tokens.back();
516 for (const auto &Child : N->Children) {
517 if (Child->Tokens.empty())
518 continue;
519 Current.Children.push_back(createUnwrappedLine(*Child, Level + 1));
520 }
521 if (Current.Children.size() == 1 &&
522 Current.Tok->isOneOf(tok::l_paren, tok::comma)) {
523 Result.Tokens.splice(Result.Tokens.end(),
524 Current.Children.front().Tokens);
525 Current.Children.clear();
526 }
527 }
528 return Result;
529 }
530
debug(const ReconstructedLine & Line,int Level)531 void MacroCallReconstructor::debug(const ReconstructedLine &Line, int Level) {
532 for (int i = 0; i < Level; ++i)
533 llvm::dbgs() << " ";
534 for (const auto &N : Line.Tokens) {
535 if (!N)
536 continue;
537 if (N->Tok)
538 llvm::dbgs() << N->Tok->TokenText << " ";
539 for (const auto &Child : N->Children) {
540 llvm::dbgs() << "\n";
541 debug(*Child, Level + 1);
542 for (int i = 0; i < Level; ++i)
543 llvm::dbgs() << " ";
544 }
545 }
546 llvm::dbgs() << "\n";
547 }
548
549 MacroCallReconstructor::ReconstructedLine &
parentLine()550 MacroCallReconstructor::parentLine() {
551 return **std::prev(std::prev(ActiveReconstructedLines.end()));
552 }
553
554 MacroCallReconstructor::ReconstructedLine *
currentLine()555 MacroCallReconstructor::currentLine() {
556 return ActiveReconstructedLines.back();
557 }
558
MacroCallState(MacroCallReconstructor::ReconstructedLine * Line,FormatToken * ParentLastToken,FormatToken * MacroCallLParen)559 MacroCallReconstructor::MacroCallState::MacroCallState(
560 MacroCallReconstructor::ReconstructedLine *Line,
561 FormatToken *ParentLastToken, FormatToken *MacroCallLParen)
562 : Line(Line), ParentLastToken(ParentLastToken),
563 MacroCallLParen(MacroCallLParen) {
564 LLVM_DEBUG(
565 llvm::dbgs() << "ParentLastToken: "
566 << (ParentLastToken ? ParentLastToken->TokenText : "<null>")
567 << "\n");
568
569 assert(MacroCallLParen->is(tok::l_paren));
570 }
571
572 } // namespace format
573 } // namespace clang
574