28#include "llvm/ADT/StringSet.h"
29#include "llvm/Support/ErrorHandling.h"
51 assert(!Tokens.empty());
58 if (Current->
isNot(tok::identifier))
62 if (Current->
is(tok::l_paren)) {
67 if (!parseExpansion())
75 assert(Current->
is(tok::l_paren));
77 while (Current->
is(tok::identifier)) {
78 Def.
Params.push_back(Current);
81 if (Current->
isNot(tok::comma))
85 if (Current->
isNot(tok::r_paren))
91 bool parseExpansion() {
92 if (!Current->
isOneOf(tok::equal, tok::eof))
94 if (Current->
is(tok::equal))
101 while (Current->
isNot(tok::eof)) {
102 Def.
Body.push_back(Current);
105 Def.
Body.push_back(Current);
109 if (Pos + 1 < Tokens.size())
111 Current = Tokens[Pos];
116 FormatToken *Current =
nullptr;
118 ArrayRef<FormatToken *> Tokens;
122 const std::vector<std::string> &Macros,
SourceManager &SourceMgr,
124 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
126 : SourceMgr(SourceMgr), Style(Style), Allocator(Allocator),
127 IdentTable(IdentTable) {
128 for (
const std::string &Macro : Macros)
129 parseDefinition(Macro);
134void MacroExpander::parseDefinition(
const std::string &Macro) {
136 llvm::MemoryBuffer::getMemBufferCopy(Macro,
"<scratch space>"));
139 Allocator, IdentTable);
140 const auto Tokens = Lex.lex();
141 if (!Tokens.empty()) {
142 DefinitionParser
Parser(Tokens);
143 auto Definition =
Parser.parse();
144 if (Definition.ObjectLike) {
145 ObjectLike[Definition.Name] = std::move(Definition);
147 FunctionLike[Definition.Name][Definition.Params.size()] =
148 std::move(Definition);
154 return FunctionLike.contains(Name) || ObjectLike.contains(Name);
158 return ObjectLike.contains(Name);
162 auto it = FunctionLike.find(Name);
163 return it != FunctionLike.end() && it->second.contains(Arity);
168 std::optional<ArgsList> OptionalArgs)
const {
170 assert(
hasArity(
ID->TokenText, OptionalArgs->size()));
174 ? FunctionLike.find(
ID->TokenText)
175 ->second.find(OptionalArgs.value().size())
177 : ObjectLike.find(
ID->TokenText)->second;
181 llvm::StringSet<> ExpandedArgs;
185 Tok->MacroCtx->ExpandedFrom.push_back(
ID);
191 auto expandArgument = [&](
FormatToken *Tok) ->
bool {
194 if (Tok->isNot(tok::identifier) || ExpandedArgs.contains(Tok->TokenText))
196 ExpandedArgs.insert(Tok->TokenText);
197 auto I = Def.
ArgMap.find(Tok->TokenText);
198 if (I == Def.
ArgMap.end())
203 if (I->getValue() >= Args.size())
220 if (expandArgument(Tok))
231 assert(
Result.size() >= 1 &&
Result.back()->is(tok::eof));
233 ++
Result[0]->MacroCtx->StartOfExpansion;
Contains functions for text encoding manipulation.
This file contains the main building blocks of macro support in clang-format.
Defines the clang::Preprocessor interface.
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.