25#include "llvm/ADT/StringSet.h"
26#include "llvm/Support/ErrorHandling.h"
48 assert(!Tokens.empty());
55 if (Current->
isNot(tok::identifier))
59 if (Current->
is(tok::l_paren)) {
64 if (!parseExpansion())
72 assert(Current->
is(tok::l_paren));
74 while (Current->
is(tok::identifier)) {
75 Def.
Params.push_back(Current);
78 if (Current->
isNot(tok::comma))
82 if (Current->
isNot(tok::r_paren))
88 bool parseExpansion() {
89 if (!Current->
isOneOf(tok::equal, tok::eof))
91 if (Current->
is(tok::equal))
98 while (Current->
isNot(tok::eof)) {
99 Def.
Body.push_back(Current);
102 Def.
Body.push_back(Current);
106 if (Pos + 1 < Tokens.size())
108 Current = Tokens[Pos];
113 FormatToken *Current =
nullptr;
115 ArrayRef<FormatToken *> Tokens;
119 const std::vector<std::string> &Macros,
SourceManager &SourceMgr,
121 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
123 : SourceMgr(SourceMgr), Style(Style), Allocator(Allocator),
124 IdentTable(IdentTable) {
125 for (
const std::string &
Macro : Macros)
126 parseDefinition(
Macro);
131void MacroExpander::parseDefinition(
const std::string &
Macro) {
133 llvm::MemoryBuffer::getMemBufferCopy(
Macro,
"<scratch space>"));
136 Allocator, IdentTable);
137 const auto Tokens = Lex.lex();
138 if (!Tokens.empty()) {
139 DefinitionParser
Parser(Tokens);
140 auto Definition =
Parser.parse();
141 if (Definition.ObjectLike) {
142 ObjectLike[Definition.Name] = std::move(Definition);
144 FunctionLike[Definition.Name][Definition.Params.size()] =
145 std::move(Definition);
151 return FunctionLike.contains(Name) || ObjectLike.contains(Name);
155 return ObjectLike.contains(Name);
159 auto it = FunctionLike.find(Name);
160 return it != FunctionLike.end() && it->second.contains(Arity);
165 std::optional<ArgsList> OptionalArgs)
const {
167 assert(
hasArity(
ID->TokenText, OptionalArgs->size()));
171 ? FunctionLike.find(
ID->TokenText)
172 ->second.find(OptionalArgs.value().size())
174 : ObjectLike.find(
ID->TokenText)->second;
178 llvm::StringSet<> ExpandedArgs;
182 Tok->MacroCtx->ExpandedFrom.push_back(
ID);
188 auto expandArgument = [&](
FormatToken *Tok) ->
bool {
191 if (Tok->isNot(tok::identifier))
193 if (!ExpandedArgs.insert(Tok->TokenText).second)
195 auto I = Def.
ArgMap.find(Tok->TokenText);
196 if (I == Def.
ArgMap.end())
201 if (I->getValue() >= Args.size())
218 if (expandArgument(Tok))
224 assert(!
New->MacroCtx);
231 ++
Result[0]->MacroCtx->StartOfExpansion;
235 Result[0]->MacroCtx->StartOfExpansion = 1;
236 Result[0]->MacroCtx->EndOfExpansion = 1;
Contains functions for text encoding manipulation.
This file contains the main building blocks of macro support in clang-format.
Defines the clang::TokenKind enum and support functions.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements an efficient mapping from strings to IdentifierInfo nodes.
Parser - This implements a parser for the C family of languages.
This class handles loading and caching of source files into memory.
FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.