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