1 //===--- MacroExpander.h - Format C++ code ----------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file contains the main building blocks of macro support in 11 /// clang-format. 12 /// 13 /// In order to not violate the requirement that clang-format can format files 14 /// in isolation, clang-format's macro support uses expansions users provide 15 /// as part of clang-format's style configuration. 16 /// 17 /// Macro definitions are of the form "MACRO(p1, p2)=p1 + p2", but only support 18 /// one level of expansion (\see MacroExpander for a full description of what 19 /// is supported). 20 /// 21 /// As part of parsing, clang-format uses the MacroExpander to expand the 22 /// spelled token streams into expanded token streams when it encounters a 23 /// macro call. The UnwrappedLineParser continues to parse UnwrappedLines 24 /// from the expanded token stream. 25 /// After the expanded unwrapped lines are parsed, the MacroUnexpander matches 26 /// the spelled token stream into unwrapped lines that best resemble the 27 /// structure of the expanded unwrapped lines. 28 /// 29 /// When formatting, clang-format formats the expanded unwrapped lines first, 30 /// determining the token types. Next, it formats the spelled unwrapped lines, 31 /// keeping the token types fixed, while allowing other formatting decisions 32 /// to change. 33 /// 34 //===----------------------------------------------------------------------===// 35 36 #ifndef CLANG_LIB_FORMAT_MACROS_H 37 #define CLANG_LIB_FORMAT_MACROS_H 38 39 #include <string> 40 #include <unordered_map> 41 #include <vector> 42 43 #include "Encoding.h" 44 #include "FormatToken.h" 45 #include "llvm/ADT/ArrayRef.h" 46 #include "llvm/ADT/SmallVector.h" 47 #include "llvm/ADT/StringRef.h" 48 49 namespace llvm { 50 class MemoryBuffer; 51 } // namespace llvm 52 53 namespace clang { 54 class IdentifierTable; 55 class SourceManager; 56 57 namespace format { 58 struct FormatStyle; 59 60 /// Takes a set of macro definitions as strings and allows expanding calls to 61 /// those macros. 62 /// 63 /// For example: 64 /// Definition: A(x, y)=x + y 65 /// Call : A(int a = 1, 2) 66 /// Expansion : int a = 1 + 2 67 /// 68 /// Expansion does not check arity of the definition. 69 /// If fewer arguments than expected are provided, the remaining parameters 70 /// are considered empty: 71 /// Call : A(a) 72 /// Expansion: a + 73 /// If more arguments than expected are provided, they will be discarded. 74 /// 75 /// The expander does not support: 76 /// - recursive expansion 77 /// - stringification 78 /// - concatenation 79 /// - variadic macros 80 /// 81 /// Furthermore, only a single expansion of each macro argument is supported, 82 /// so that we cannot get conflicting formatting decisions from different 83 /// expansions. 84 /// Definition: A(x)=x+x 85 /// Call : A(id) 86 /// Expansion : id+x 87 /// 88 class MacroExpander { 89 public: 90 using ArgsList = llvm::ArrayRef<llvm::SmallVector<FormatToken *, 8>>; 91 92 /// Construct a macro expander from a set of macro definitions. 93 /// Macro definitions must be encoded as UTF-8. 94 /// 95 /// Each entry in \p Macros must conform to the following simple 96 /// macro-definition language: 97 /// <definition> ::= <id> <expansion> | <id> "(" <params> ")" <expansion> 98 /// <params> ::= <id-list> | "" 99 /// <id-list> ::= <id> | <id> "," <params> 100 /// <expansion> ::= "=" <tail> | <eof> 101 /// <tail> ::= <tok> <tail> | <eof> 102 /// 103 /// Macros that cannot be parsed will be silently discarded. 104 /// 105 MacroExpander(const std::vector<std::string> &Macros, 106 clang::SourceManager &SourceMgr, const FormatStyle &Style, 107 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator, 108 IdentifierTable &IdentTable); 109 ~MacroExpander(); 110 111 /// Returns whether a macro \p Name is defined. 112 bool defined(llvm::StringRef Name) const; 113 114 /// Returns whether the macro has no arguments and should not consume 115 /// subsequent parentheses. 116 bool objectLike(llvm::StringRef Name) const; 117 118 /// Returns the expanded stream of format tokens for \p ID, where 119 /// each element in \p Args is a positional argument to the macro call. 120 llvm::SmallVector<FormatToken *, 8> expand(FormatToken *ID, 121 ArgsList Args) const; 122 123 private: 124 struct Definition; 125 class DefinitionParser; 126 127 void parseDefinition(const std::string &Macro); 128 129 clang::SourceManager &SourceMgr; 130 const FormatStyle &Style; 131 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator; 132 IdentifierTable &IdentTable; 133 std::vector<std::unique_ptr<llvm::MemoryBuffer>> Buffers; 134 llvm::StringMap<Definition> Definitions; 135 }; 136 137 } // namespace format 138 } // namespace clang 139 140 #endif 141