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
50namespace llvm {
51class MemoryBuffer;
52} // namespace llvm
53
54namespace clang {
55class IdentifierTable;
56class SourceManager;
57
58namespace format {
59struct 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///
89class MacroExpander {
90public:
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
124private:
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