clang 20.0.0git
MacroCallReconstructor.cpp
Go to the documentation of this file.
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"
20#include "llvm/ADT/DenseSet.h"
21#include "llvm/Support/Debug.h"
22#include <cassert>
23
24#define DEBUG_TYPE "format-reconstruct"
25
26namespace clang {
27namespace 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.
31template <typename T>
32void 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
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
53 assert(State != Finalized);
54 LLVM_DEBUG(llvm::dbgs() << "MCR: new line...\n");
56 unsigned Level) { add(Token, Parent, First, Level); });
57 assert(InProgress || finished());
58}
59
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.
73void 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.
131void 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.
193FormatToken *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.
207void 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(
258void 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.
304bool 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.
318void 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
367void 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.
388bool 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
465void 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
499void 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
506UnwrappedLine
507MacroCallReconstructor::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
549void 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
567MacroCallReconstructor::ReconstructedLine &
568MacroCallReconstructor::parentLine() {
569 return **std::prev(std::prev(ActiveReconstructedLines.end()));
570}
571
572MacroCallReconstructor::ReconstructedLine *
573MacroCallReconstructor::currentLine() {
574 return ActiveReconstructedLines.back();
575}
576
577MacroCallReconstructor::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
NodeId Parent
Definition: ASTDiff.cpp:191
StringRef P
static char ID
Definition: Arena.cpp:183
Expr * E
This file contains the main building blocks of macro support in clang-format.
Defines the clang::TokenKind enum and support functions.
This file contains the declaration of the UnwrappedLineParser, which turns a stream of tokens into Un...
Token - This structure provides full information about a lexed token.
Definition: Token.h:36
MacroCallReconstructor(unsigned Level, const llvm::DenseMap< FormatToken *, std::unique_ptr< UnwrappedLine > > &ActiveExpansions)
Create an Reconstructor whose resulting UnwrappedLine will start at Level, using the map from name id...
void addLine(const UnwrappedLine &Line)
For the given Line, match all occurences of tokens expanded from a macro to unwrapped lines in the sp...
UnwrappedLine takeResult() &&
Retrieve the formatted UnwrappedLine containing the orginal macro calls, formatted according to the e...
bool finished() const
Check whether at the current state there is no open macro expansion that needs to be processed to fin...
Definition: Macros.h:196
@ MR_Hidden
The token was expanded from a macro definition, and is not visible as part of the macro call.
Definition: FormatToken.h:235
void forEachToken(const UnwrappedLine &Line, const T &Call, FormatToken *Parent=nullptr)
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
const FunctionProtoType * T
void finalize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
A wrapper around a Token storing information about the whitespace characters preceding it.
Definition: FormatToken.h:292
StringRef TokenText
The raw text of the token.
Definition: FormatToken.h:312
An unwrapped line is a sequence of Token, that we would like to put on a single line if there was no ...