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