//===--- Macros.h - Format C++ code -----------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// /// \file /// This file contains the main building blocks of macro support in /// clang-format. /// /// In order to not violate the requirement that clang-format can format files /// in isolation, clang-format's macro support uses expansions users provide /// as part of clang-format's style configuration. /// /// Macro definitions are of the form "MACRO(p1, p2)=p1 + p2", but only support /// one level of expansion (\see MacroExpander for a full description of what /// is supported). /// /// As part of parsing, clang-format uses the MacroExpander to expand the /// spelled token streams into expanded token streams when it encounters a /// macro call. The UnwrappedLineParser continues to parse UnwrappedLines /// from the expanded token stream. /// After the expanded unwrapped lines are parsed, the MacroCallReconstructor /// matches the spelled token stream into unwrapped lines that best resemble the /// structure of the expanded unwrapped lines. These reconstructed unwrapped /// lines are aliasing the tokens in the expanded token stream, so that token /// annotations will be reused when formatting the spelled macro calls. /// /// When formatting, clang-format annotates and formats the expanded unwrapped /// lines first, determining the token types. Next, it formats the spelled /// unwrapped lines, keeping the token types fixed, while allowing other /// formatting decisions to change. /// //===----------------------------------------------------------------------===// #ifndef CLANG_LIB_FORMAT_MACROS_H #define CLANG_LIB_FORMAT_MACROS_H #include <list> #include "FormatToken.h" #include "llvm/ADT/DenseMap.h" namespace clang { namespace format { struct UnwrappedLine; struct UnwrappedLineNode; /// Takes a set of macro definitions as strings and allows expanding calls to /// those macros. /// /// For example: /// Definition: A(x, y)=x + y /// Call : A(int a = 1, 2) /// Expansion : int a = 1 + 2 /// /// Expansion does not check arity of the definition. /// If fewer arguments than expected are provided, the remaining parameters /// are considered empty: /// Call : A(a) /// Expansion: a + /// If more arguments than expected are provided, they will be discarded. /// /// The expander does not support: /// - recursive expansion /// - stringification /// - concatenation /// - variadic macros /// /// Furthermore, only a single expansion of each macro argument is supported, /// so that we cannot get conflicting formatting decisions from different /// expansions. /// Definition: A(x)=x+x /// Call : A(id) /// Expansion : id+x /// class MacroExpander { … }; /// Converts a sequence of UnwrappedLines containing expanded macros into a /// single UnwrappedLine containing the macro calls. This UnwrappedLine may be /// broken into child lines, in a way that best conveys the structure of the /// expanded code. /// /// In the simplest case, a spelled UnwrappedLine contains one macro, and after /// expanding it we have one expanded UnwrappedLine. In general, macro /// expansions can span UnwrappedLines, and multiple macros can contribute /// tokens to the same line. We keep consuming expanded lines until: /// * all expansions that started have finished (we're not chopping any macros /// in half) /// * *and* we've reached the end of a *spelled* unwrapped line. /// /// A single UnwrappedLine represents this chunk of code. /// /// After this point, the state of the spelled/expanded stream is "in sync" /// (both at the start of an UnwrappedLine, with no macros open), so the /// Reconstructor can be thrown away and parsing can continue. /// /// Given a mapping from the macro name identifier token in the macro call /// to the tokens of the macro call, for example: /// CLASSA -> CLASSA({public: void x();}) /// /// When getting the formatted lines of the expansion via the \c addLine method /// (each '->' specifies a call to \c addLine ): /// -> class A { /// -> public: /// -> void x(); /// -> }; /// /// Creates the tree of unwrapped lines containing the macro call tokens so that /// the macro call tokens fit the semantic structure of the expanded formatted /// lines: /// -> CLASSA({ /// -> public: /// -> void x(); /// -> }) class MacroCallReconstructor { … }; } // namespace format } // namespace clang #endif