xref: /freebsd-src/contrib/llvm-project/clang/lib/Format/Macros.h (revision 753f127f3ace09432b2baeffd71a308760641a62)
1*753f127fSDimitry Andric //===--- Macros.h - Format C++ code -----------------------------*- C++ -*-===//
2e8d8bef9SDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e8d8bef9SDimitry Andric //
7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
8e8d8bef9SDimitry Andric ///
9e8d8bef9SDimitry Andric /// \file
10e8d8bef9SDimitry Andric /// This file contains the main building blocks of macro support in
11e8d8bef9SDimitry Andric /// clang-format.
12e8d8bef9SDimitry Andric ///
13e8d8bef9SDimitry Andric /// In order to not violate the requirement that clang-format can format files
14e8d8bef9SDimitry Andric /// in isolation, clang-format's macro support uses expansions users provide
15e8d8bef9SDimitry Andric /// as part of clang-format's style configuration.
16e8d8bef9SDimitry Andric ///
17e8d8bef9SDimitry Andric /// Macro definitions are of the form "MACRO(p1, p2)=p1 + p2", but only support
18e8d8bef9SDimitry Andric /// one level of expansion (\see MacroExpander for a full description of what
19e8d8bef9SDimitry Andric /// is supported).
20e8d8bef9SDimitry Andric ///
21e8d8bef9SDimitry Andric /// As part of parsing, clang-format uses the MacroExpander to expand the
22e8d8bef9SDimitry Andric /// spelled token streams into expanded token streams when it encounters a
23e8d8bef9SDimitry Andric /// macro call. The UnwrappedLineParser continues to parse UnwrappedLines
24e8d8bef9SDimitry Andric /// from the expanded token stream.
25*753f127fSDimitry Andric /// After the expanded unwrapped lines are parsed, the MacroCallReconstructor
26*753f127fSDimitry Andric /// matches the spelled token stream into unwrapped lines that best resemble the
27*753f127fSDimitry Andric /// structure of the expanded unwrapped lines. These reconstructed unwrapped
28*753f127fSDimitry Andric /// lines are aliasing the tokens in the expanded token stream, so that token
29*753f127fSDimitry Andric /// annotations will be reused when formatting the spelled macro calls.
30e8d8bef9SDimitry Andric ///
31*753f127fSDimitry Andric /// When formatting, clang-format annotates and formats the expanded unwrapped
32*753f127fSDimitry Andric /// lines first, determining the token types. Next, it formats the spelled
33*753f127fSDimitry Andric /// unwrapped lines, keeping the token types fixed, while allowing other
34*753f127fSDimitry Andric /// formatting decisions to change.
35e8d8bef9SDimitry Andric ///
36e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
37e8d8bef9SDimitry Andric 
38e8d8bef9SDimitry Andric #ifndef CLANG_LIB_FORMAT_MACROS_H
39e8d8bef9SDimitry Andric #define CLANG_LIB_FORMAT_MACROS_H
40e8d8bef9SDimitry Andric 
41*753f127fSDimitry Andric #include <list>
42*753f127fSDimitry Andric #include <map>
43e8d8bef9SDimitry Andric #include <string>
44e8d8bef9SDimitry Andric #include <vector>
45e8d8bef9SDimitry Andric 
46e8d8bef9SDimitry Andric #include "FormatToken.h"
47e8d8bef9SDimitry Andric #include "llvm/ADT/ArrayRef.h"
48*753f127fSDimitry Andric #include "llvm/ADT/DenseMap.h"
49e8d8bef9SDimitry Andric #include "llvm/ADT/SmallVector.h"
50e8d8bef9SDimitry Andric #include "llvm/ADT/StringRef.h"
51e8d8bef9SDimitry Andric 
52e8d8bef9SDimitry Andric namespace clang {
53e8d8bef9SDimitry Andric namespace format {
54*753f127fSDimitry Andric 
55*753f127fSDimitry Andric struct UnwrappedLine;
56*753f127fSDimitry Andric struct UnwrappedLineNode;
57e8d8bef9SDimitry Andric 
58e8d8bef9SDimitry Andric /// Takes a set of macro definitions as strings and allows expanding calls to
59e8d8bef9SDimitry Andric /// those macros.
60e8d8bef9SDimitry Andric ///
61e8d8bef9SDimitry Andric /// For example:
62e8d8bef9SDimitry Andric /// Definition: A(x, y)=x + y
63e8d8bef9SDimitry Andric /// Call      : A(int a = 1, 2)
64e8d8bef9SDimitry Andric /// Expansion : int a = 1 + 2
65e8d8bef9SDimitry Andric ///
66e8d8bef9SDimitry Andric /// Expansion does not check arity of the definition.
67e8d8bef9SDimitry Andric /// If fewer arguments than expected are provided, the remaining parameters
68e8d8bef9SDimitry Andric /// are considered empty:
69e8d8bef9SDimitry Andric /// Call     : A(a)
70e8d8bef9SDimitry Andric /// Expansion: a +
71e8d8bef9SDimitry Andric /// If more arguments than expected are provided, they will be discarded.
72e8d8bef9SDimitry Andric ///
73e8d8bef9SDimitry Andric /// The expander does not support:
74e8d8bef9SDimitry Andric /// - recursive expansion
75e8d8bef9SDimitry Andric /// - stringification
76e8d8bef9SDimitry Andric /// - concatenation
77e8d8bef9SDimitry Andric /// - variadic macros
78e8d8bef9SDimitry Andric ///
79e8d8bef9SDimitry Andric /// Furthermore, only a single expansion of each macro argument is supported,
80e8d8bef9SDimitry Andric /// so that we cannot get conflicting formatting decisions from different
81e8d8bef9SDimitry Andric /// expansions.
82e8d8bef9SDimitry Andric /// Definition: A(x)=x+x
83e8d8bef9SDimitry Andric /// Call      : A(id)
84e8d8bef9SDimitry Andric /// Expansion : id+x
85e8d8bef9SDimitry Andric ///
86e8d8bef9SDimitry Andric class MacroExpander {
87e8d8bef9SDimitry Andric public:
88e8d8bef9SDimitry Andric   using ArgsList = llvm::ArrayRef<llvm::SmallVector<FormatToken *, 8>>;
89e8d8bef9SDimitry Andric 
90e8d8bef9SDimitry Andric   /// Construct a macro expander from a set of macro definitions.
91e8d8bef9SDimitry Andric   /// Macro definitions must be encoded as UTF-8.
92e8d8bef9SDimitry Andric   ///
93e8d8bef9SDimitry Andric   /// Each entry in \p Macros must conform to the following simple
94e8d8bef9SDimitry Andric   /// macro-definition language:
95e8d8bef9SDimitry Andric   /// <definition> ::= <id> <expansion> | <id> "(" <params> ")" <expansion>
96e8d8bef9SDimitry Andric   /// <params>     ::= <id-list> | ""
97e8d8bef9SDimitry Andric   /// <id-list>    ::= <id> | <id> "," <params>
98e8d8bef9SDimitry Andric   /// <expansion>  ::= "=" <tail> | <eof>
99e8d8bef9SDimitry Andric   /// <tail>       ::= <tok> <tail> | <eof>
100e8d8bef9SDimitry Andric   ///
101e8d8bef9SDimitry Andric   /// Macros that cannot be parsed will be silently discarded.
102e8d8bef9SDimitry Andric   ///
103e8d8bef9SDimitry Andric   MacroExpander(const std::vector<std::string> &Macros,
104e8d8bef9SDimitry Andric                 clang::SourceManager &SourceMgr, const FormatStyle &Style,
105e8d8bef9SDimitry Andric                 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
106e8d8bef9SDimitry Andric                 IdentifierTable &IdentTable);
107e8d8bef9SDimitry Andric   ~MacroExpander();
108e8d8bef9SDimitry Andric 
109e8d8bef9SDimitry Andric   /// Returns whether a macro \p Name is defined.
110e8d8bef9SDimitry Andric   bool defined(llvm::StringRef Name) const;
111e8d8bef9SDimitry Andric 
112e8d8bef9SDimitry Andric   /// Returns whether the macro has no arguments and should not consume
113e8d8bef9SDimitry Andric   /// subsequent parentheses.
114e8d8bef9SDimitry Andric   bool objectLike(llvm::StringRef Name) const;
115e8d8bef9SDimitry Andric 
116e8d8bef9SDimitry Andric   /// Returns the expanded stream of format tokens for \p ID, where
117e8d8bef9SDimitry Andric   /// each element in \p Args is a positional argument to the macro call.
118e8d8bef9SDimitry Andric   llvm::SmallVector<FormatToken *, 8> expand(FormatToken *ID,
119e8d8bef9SDimitry Andric                                              ArgsList Args) const;
120e8d8bef9SDimitry Andric 
121e8d8bef9SDimitry Andric private:
122e8d8bef9SDimitry Andric   struct Definition;
123e8d8bef9SDimitry Andric   class DefinitionParser;
124e8d8bef9SDimitry Andric 
125e8d8bef9SDimitry Andric   void parseDefinition(const std::string &Macro);
126e8d8bef9SDimitry Andric 
127e8d8bef9SDimitry Andric   clang::SourceManager &SourceMgr;
128e8d8bef9SDimitry Andric   const FormatStyle &Style;
129e8d8bef9SDimitry Andric   llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator;
130e8d8bef9SDimitry Andric   IdentifierTable &IdentTable;
131*753f127fSDimitry Andric   SmallVector<std::unique_ptr<llvm::MemoryBuffer>> Buffers;
132e8d8bef9SDimitry Andric   llvm::StringMap<Definition> Definitions;
133e8d8bef9SDimitry Andric };
134e8d8bef9SDimitry Andric 
135*753f127fSDimitry Andric /// Converts a sequence of UnwrappedLines containing expanded macros into a
136*753f127fSDimitry Andric /// single UnwrappedLine containing the macro calls.  This UnwrappedLine may be
137*753f127fSDimitry Andric /// broken into child lines, in a way that best conveys the structure of the
138*753f127fSDimitry Andric /// expanded code.
139*753f127fSDimitry Andric ///
140*753f127fSDimitry Andric /// In the simplest case, a spelled UnwrappedLine contains one macro, and after
141*753f127fSDimitry Andric /// expanding it we have one expanded UnwrappedLine.  In general, macro
142*753f127fSDimitry Andric /// expansions can span UnwrappedLines, and multiple macros can contribute
143*753f127fSDimitry Andric /// tokens to the same line.  We keep consuming expanded lines until:
144*753f127fSDimitry Andric /// *   all expansions that started have finished (we're not chopping any macros
145*753f127fSDimitry Andric ///     in half)
146*753f127fSDimitry Andric /// *   *and* we've reached the end of a *spelled* unwrapped line.
147*753f127fSDimitry Andric ///
148*753f127fSDimitry Andric /// A single UnwrappedLine represents this chunk of code.
149*753f127fSDimitry Andric ///
150*753f127fSDimitry Andric /// After this point, the state of the spelled/expanded stream is "in sync"
151*753f127fSDimitry Andric /// (both at the start of an UnwrappedLine, with no macros open), so the
152*753f127fSDimitry Andric /// Unexpander can be thrown away and parsing can continue.
153*753f127fSDimitry Andric ///
154*753f127fSDimitry Andric /// Given a mapping from the macro name identifier token in the macro call
155*753f127fSDimitry Andric /// to the tokens of the macro call, for example:
156*753f127fSDimitry Andric /// CLASSA -> CLASSA({public: void x();})
157*753f127fSDimitry Andric ///
158*753f127fSDimitry Andric /// When getting the formatted lines of the expansion via the \c addLine method
159*753f127fSDimitry Andric /// (each '->' specifies a call to \c addLine ):
160*753f127fSDimitry Andric /// -> class A {
161*753f127fSDimitry Andric /// -> public:
162*753f127fSDimitry Andric /// ->   void x();
163*753f127fSDimitry Andric /// -> };
164*753f127fSDimitry Andric ///
165*753f127fSDimitry Andric /// Creates the tree of unwrapped lines containing the macro call tokens so that
166*753f127fSDimitry Andric /// the macro call tokens fit the semantic structure of the expanded formatted
167*753f127fSDimitry Andric /// lines:
168*753f127fSDimitry Andric /// -> CLASSA({
169*753f127fSDimitry Andric /// -> public:
170*753f127fSDimitry Andric /// ->   void x();
171*753f127fSDimitry Andric /// -> })
172*753f127fSDimitry Andric class MacroCallReconstructor {
173*753f127fSDimitry Andric public:
174*753f127fSDimitry Andric   /// Create an Reconstructor whose resulting \p UnwrappedLine will start at
175*753f127fSDimitry Andric   /// \p Level, using the map from name identifier token to the corresponding
176*753f127fSDimitry Andric   /// tokens of the spelled macro call.
177*753f127fSDimitry Andric   MacroCallReconstructor(
178*753f127fSDimitry Andric       unsigned Level,
179*753f127fSDimitry Andric       const llvm::DenseMap<FormatToken *, std::unique_ptr<UnwrappedLine>>
180*753f127fSDimitry Andric           &ActiveExpansions);
181*753f127fSDimitry Andric 
182*753f127fSDimitry Andric   /// For the given \p Line, match all occurences of tokens expanded from a
183*753f127fSDimitry Andric   /// macro to unwrapped lines in the spelled macro call so that the resulting
184*753f127fSDimitry Andric   /// tree of unwrapped lines best resembles the structure of unwrapped lines
185*753f127fSDimitry Andric   /// passed in via \c addLine.
186*753f127fSDimitry Andric   void addLine(const UnwrappedLine &Line);
187*753f127fSDimitry Andric 
188*753f127fSDimitry Andric   /// Check whether at the current state there is no open macro expansion
189*753f127fSDimitry Andric   /// that needs to be processed to finish an macro call.
190*753f127fSDimitry Andric   /// Only when \c finished() is true, \c takeResult() can be called to retrieve
191*753f127fSDimitry Andric   /// the resulting \c UnwrappedLine.
192*753f127fSDimitry Andric   /// If there are multiple subsequent macro calls within an unwrapped line in
193*753f127fSDimitry Andric   /// the spelled token stream, the calling code may also continue to call
194*753f127fSDimitry Andric   /// \c addLine() when \c finished() is true.
195*753f127fSDimitry Andric   bool finished() const { return ActiveExpansions.empty(); }
196*753f127fSDimitry Andric 
197*753f127fSDimitry Andric   /// Retrieve the formatted \c UnwrappedLine containing the orginal
198*753f127fSDimitry Andric   /// macro calls, formatted according to the expanded token stream received
199*753f127fSDimitry Andric   /// via \c addLine().
200*753f127fSDimitry Andric   /// Generally, this line tries to have the same structure as the expanded,
201*753f127fSDimitry Andric   /// formatted unwrapped lines handed in via \c addLine(), with the exception
202*753f127fSDimitry Andric   /// that for multiple top-level lines, each subsequent line will be the
203*753f127fSDimitry Andric   /// child of the last token in its predecessor. This representation is chosen
204*753f127fSDimitry Andric   /// because it is a precondition to the formatter that we get what looks like
205*753f127fSDimitry Andric   /// a single statement in a single \c UnwrappedLine (i.e. matching parens).
206*753f127fSDimitry Andric   ///
207*753f127fSDimitry Andric   /// If a token in a macro argument is a child of a token in the expansion,
208*753f127fSDimitry Andric   /// the parent will be the corresponding token in the macro call.
209*753f127fSDimitry Andric   /// For example:
210*753f127fSDimitry Andric   ///   #define C(a, b) class C { a b
211*753f127fSDimitry Andric   ///   C(int x;, int y;)
212*753f127fSDimitry Andric   /// would expand to
213*753f127fSDimitry Andric   ///   class C { int x; int y;
214*753f127fSDimitry Andric   /// where in a formatted line "int x;" and "int y;" would both be new separate
215*753f127fSDimitry Andric   /// lines.
216*753f127fSDimitry Andric   ///
217*753f127fSDimitry Andric   /// In the result, "int x;" will be a child of the opening parenthesis in "C("
218*753f127fSDimitry Andric   /// and "int y;" will be a child of the "," token:
219*753f127fSDimitry Andric   ///   C (
220*753f127fSDimitry Andric   ///     \- int x;
221*753f127fSDimitry Andric   ///     ,
222*753f127fSDimitry Andric   ///     \- int y;
223*753f127fSDimitry Andric   ///     )
224*753f127fSDimitry Andric   UnwrappedLine takeResult() &&;
225*753f127fSDimitry Andric 
226*753f127fSDimitry Andric private:
227*753f127fSDimitry Andric   void add(FormatToken *Token, FormatToken *ExpandedParent, bool First);
228*753f127fSDimitry Andric   void prepareParent(FormatToken *ExpandedParent, bool First);
229*753f127fSDimitry Andric   FormatToken *getParentInResult(FormatToken *Parent);
230*753f127fSDimitry Andric   void reconstruct(FormatToken *Token);
231*753f127fSDimitry Andric   void startReconstruction(FormatToken *Token);
232*753f127fSDimitry Andric   bool reconstructActiveCallUntil(FormatToken *Token);
233*753f127fSDimitry Andric   void endReconstruction(FormatToken *Token);
234*753f127fSDimitry Andric   bool processNextReconstructed();
235*753f127fSDimitry Andric   void finalize();
236*753f127fSDimitry Andric 
237*753f127fSDimitry Andric   struct ReconstructedLine;
238*753f127fSDimitry Andric 
239*753f127fSDimitry Andric   void appendToken(FormatToken *Token, ReconstructedLine *L = nullptr);
240*753f127fSDimitry Andric   UnwrappedLine createUnwrappedLine(const ReconstructedLine &Line, int Level);
241*753f127fSDimitry Andric   void debug(const ReconstructedLine &Line, int Level);
242*753f127fSDimitry Andric   ReconstructedLine &parentLine();
243*753f127fSDimitry Andric   ReconstructedLine *currentLine();
244*753f127fSDimitry Andric   void debugParentMap() const;
245*753f127fSDimitry Andric 
246*753f127fSDimitry Andric #ifndef NDEBUG
247*753f127fSDimitry Andric   enum ReconstructorState {
248*753f127fSDimitry Andric     Start,      // No macro expansion was found in the input yet.
249*753f127fSDimitry Andric     InProgress, // During a macro reconstruction.
250*753f127fSDimitry Andric     Finalized,  // Past macro reconstruction, the result is finalized.
251*753f127fSDimitry Andric   };
252*753f127fSDimitry Andric   ReconstructorState State = Start;
253*753f127fSDimitry Andric #endif
254*753f127fSDimitry Andric 
255*753f127fSDimitry Andric   // Node in which we build up the resulting unwrapped line; this type is
256*753f127fSDimitry Andric   // analogous to UnwrappedLineNode.
257*753f127fSDimitry Andric   struct LineNode {
258*753f127fSDimitry Andric     LineNode() = default;
259*753f127fSDimitry Andric     LineNode(FormatToken *Tok) : Tok(Tok) {}
260*753f127fSDimitry Andric     FormatToken *Tok = nullptr;
261*753f127fSDimitry Andric     llvm::SmallVector<std::unique_ptr<ReconstructedLine>> Children;
262*753f127fSDimitry Andric   };
263*753f127fSDimitry Andric 
264*753f127fSDimitry Andric   // Line in which we build up the resulting unwrapped line.
265*753f127fSDimitry Andric   // FIXME: Investigate changing UnwrappedLine to a pointer type and using it
266*753f127fSDimitry Andric   // instead of rolling our own type.
267*753f127fSDimitry Andric   struct ReconstructedLine {
268*753f127fSDimitry Andric     llvm::SmallVector<std::unique_ptr<LineNode>> Tokens;
269*753f127fSDimitry Andric   };
270*753f127fSDimitry Andric 
271*753f127fSDimitry Andric   // The line in which we collect the resulting reconstructed output.
272*753f127fSDimitry Andric   // To reduce special cases in the algorithm, the first level of the line
273*753f127fSDimitry Andric   // contains a single null token that has the reconstructed incoming
274*753f127fSDimitry Andric   // lines as children.
275*753f127fSDimitry Andric   // In the end, we stich the lines together so that each subsequent line
276*753f127fSDimitry Andric   // is a child of the last token of the previous line. This is necessary
277*753f127fSDimitry Andric   // in order to format the overall expression as a single logical line -
278*753f127fSDimitry Andric   // if we created separate lines, we'd format them with their own top-level
279*753f127fSDimitry Andric   // indent depending on the semantic structure, which is not desired.
280*753f127fSDimitry Andric   ReconstructedLine Result;
281*753f127fSDimitry Andric 
282*753f127fSDimitry Andric   // Stack of currently "open" lines, where each line's predecessor's last
283*753f127fSDimitry Andric   // token is the parent token for that line.
284*753f127fSDimitry Andric   llvm::SmallVector<ReconstructedLine *> ActiveReconstructedLines;
285*753f127fSDimitry Andric 
286*753f127fSDimitry Andric   // Maps from the expanded token to the token that takes its place in the
287*753f127fSDimitry Andric   // reconstructed token stream in terms of parent-child relationships.
288*753f127fSDimitry Andric   // Note that it might take multiple steps to arrive at the correct
289*753f127fSDimitry Andric   // parent in the output.
290*753f127fSDimitry Andric   // Given: #define C(a, b) []() { a; b; }
291*753f127fSDimitry Andric   // And a call: C(f(), g())
292*753f127fSDimitry Andric   // The structure in the incoming formatted unwrapped line will be:
293*753f127fSDimitry Andric   // []() {
294*753f127fSDimitry Andric   //      |- f();
295*753f127fSDimitry Andric   //      \- g();
296*753f127fSDimitry Andric   // }
297*753f127fSDimitry Andric   // with f and g being children of the opening brace.
298*753f127fSDimitry Andric   // In the reconstructed call:
299*753f127fSDimitry Andric   // C(f(), g())
300*753f127fSDimitry Andric   //  \- f()
301*753f127fSDimitry Andric   //      \- g()
302*753f127fSDimitry Andric   // We want f to be a child of the opening parenthesis and g to be a child
303*753f127fSDimitry Andric   // of the comma token in the macro call.
304*753f127fSDimitry Andric   // Thus, we map
305*753f127fSDimitry Andric   // { -> (
306*753f127fSDimitry Andric   // and add
307*753f127fSDimitry Andric   // ( -> ,
308*753f127fSDimitry Andric   // once we're past the comma in the reconstruction.
309*753f127fSDimitry Andric   llvm::DenseMap<FormatToken *, FormatToken *>
310*753f127fSDimitry Andric       SpelledParentToReconstructedParent;
311*753f127fSDimitry Andric 
312*753f127fSDimitry Andric   // Keeps track of a single expansion while we're reconstructing tokens it
313*753f127fSDimitry Andric   // generated.
314*753f127fSDimitry Andric   struct Expansion {
315*753f127fSDimitry Andric     // The identifier token of the macro call.
316*753f127fSDimitry Andric     FormatToken *ID;
317*753f127fSDimitry Andric     // Our current position in the reconstruction.
318*753f127fSDimitry Andric     std::list<UnwrappedLineNode>::iterator SpelledI;
319*753f127fSDimitry Andric     // The end of the reconstructed token sequence.
320*753f127fSDimitry Andric     std::list<UnwrappedLineNode>::iterator SpelledE;
321*753f127fSDimitry Andric   };
322*753f127fSDimitry Andric 
323*753f127fSDimitry Andric   // Stack of macro calls for which we're in the middle of an expansion.
324*753f127fSDimitry Andric   llvm::SmallVector<Expansion> ActiveExpansions;
325*753f127fSDimitry Andric 
326*753f127fSDimitry Andric   struct MacroCallState {
327*753f127fSDimitry Andric     MacroCallState(ReconstructedLine *Line, FormatToken *ParentLastToken,
328*753f127fSDimitry Andric                    FormatToken *MacroCallLParen);
329*753f127fSDimitry Andric 
330*753f127fSDimitry Andric     ReconstructedLine *Line;
331*753f127fSDimitry Andric 
332*753f127fSDimitry Andric     // The last token in the parent line or expansion, or nullptr if the macro
333*753f127fSDimitry Andric     // expansion is on a top-level line.
334*753f127fSDimitry Andric     //
335*753f127fSDimitry Andric     // For example, in the macro call:
336*753f127fSDimitry Andric     //   auto f = []() { ID(1); };
337*753f127fSDimitry Andric     // The MacroCallState for ID will have '{' as ParentLastToken.
338*753f127fSDimitry Andric     //
339*753f127fSDimitry Andric     // In the macro call:
340*753f127fSDimitry Andric     //   ID(ID(void f()));
341*753f127fSDimitry Andric     // The MacroCallState of the outer ID will have nullptr as ParentLastToken,
342*753f127fSDimitry Andric     // while the MacroCallState for the inner ID will have the '(' of the outer
343*753f127fSDimitry Andric     // ID as ParentLastToken.
344*753f127fSDimitry Andric     //
345*753f127fSDimitry Andric     // In the macro call:
346*753f127fSDimitry Andric     //   ID2(a, ID(b));
347*753f127fSDimitry Andric     // The MacroCallState of ID will have ',' as ParentLastToken.
348*753f127fSDimitry Andric     FormatToken *ParentLastToken;
349*753f127fSDimitry Andric 
350*753f127fSDimitry Andric     // The l_paren of this MacroCallState's macro call.
351*753f127fSDimitry Andric     FormatToken *MacroCallLParen;
352*753f127fSDimitry Andric   };
353*753f127fSDimitry Andric 
354*753f127fSDimitry Andric   // Keeps track of the lines into which the opening brace/parenthesis &
355*753f127fSDimitry Andric   // argument separating commas for each level in the macro call go in order to
356*753f127fSDimitry Andric   // put the corresponding closing brace/parenthesis into the same line in the
357*753f127fSDimitry Andric   // output and keep track of which parents in the expanded token stream map to
358*753f127fSDimitry Andric   // which tokens in the reconstructed stream.
359*753f127fSDimitry Andric   // When an opening brace/parenthesis has children, we want the structure of
360*753f127fSDimitry Andric   // the output line to be:
361*753f127fSDimitry Andric   // |- MACRO
362*753f127fSDimitry Andric   // |- (
363*753f127fSDimitry Andric   // |  \- <argument>
364*753f127fSDimitry Andric   // |- ,
365*753f127fSDimitry Andric   // |  \- <argument>
366*753f127fSDimitry Andric   // \- )
367*753f127fSDimitry Andric   llvm::SmallVector<MacroCallState> MacroCallStructure;
368*753f127fSDimitry Andric 
369*753f127fSDimitry Andric   // Level the generated UnwrappedLine will be at.
370*753f127fSDimitry Andric   const unsigned Level;
371*753f127fSDimitry Andric 
372*753f127fSDimitry Andric   // Maps from identifier of the macro call to an unwrapped line containing
373*753f127fSDimitry Andric   // all tokens of the macro call.
374*753f127fSDimitry Andric   const llvm::DenseMap<FormatToken *, std::unique_ptr<UnwrappedLine>>
375*753f127fSDimitry Andric       &IdToReconstructed;
376*753f127fSDimitry Andric };
377*753f127fSDimitry Andric 
378e8d8bef9SDimitry Andric } // namespace format
379e8d8bef9SDimitry Andric } // namespace clang
380e8d8bef9SDimitry Andric 
381e8d8bef9SDimitry Andric #endif
382