clang: lib/Tooling/Transformer/Parsing.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
12#include "llvm/ADT/StringMap.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/Support/Error.h"
15#include
16#include
17#include
18
19using namespace clang;
21
22
23
24
25
26
27
28namespace {
30
31template <typename... Ts> using RangeSelectorOp = RangeSelector (*)(Ts...);
32
33struct ParseState {
34
35 StringRef Input;
36
37
38 StringRef OriginalInput;
39};
40
41
42
43template struct ParseProgress {
44 ParseState State;
45
46 ResultType Value;
47};
48
50template using ParseFunction = ExpectedProgress (*)(ParseState);
51
52class ParseError : public llvm::ErrorInfo {
53public:
54
55 static char ID;
56
57 ParseError(size_t Pos, std::string ErrorMsg, std::string InputExcerpt)
58 : Pos(Pos), ErrorMsg(std::move(ErrorMsg)),
59 Excerpt(std::move(InputExcerpt)) {}
60
61 void log(llvm::raw_ostream &OS) const override {
62 OS << "parse error at position (" << Pos << "): " << ErrorMsg
63 << ": " + Excerpt;
64 }
65
66 std::error_code convertToErrorCode() const override {
67 return llvm::inconvertibleErrorCode();
68 }
69
70
71 size_t Pos;
72 std::string ErrorMsg;
73
74 std::string Excerpt;
75};
76
77char ParseError::ID;
78}
79
80static const llvm::StringMap<RangeSelectorOpstd::string> &
82 static const llvm::StringMap<RangeSelectorOpstd::string> M = {
83 {"name", name},
84 {"node", node},
91 return M;
92}
93
94static const llvm::StringMap<RangeSelectorOp> &
96 static const llvm::StringMap<RangeSelectorOp> M = {
98 return M;
99}
100
101static const llvm::StringMap<RangeSelectorOp<std::string, std::string>> &
103 static const llvm::StringMap<RangeSelectorOp<std::string, std::string>> M = {
105 return M;
106}
107
108static const llvm::StringMap<RangeSelectorOp<RangeSelector, RangeSelector>> &
110 static const llvm::StringMap<RangeSelectorOp<RangeSelector, RangeSelector>>
112 return M;
113}
114
115template
116std::optional findOptional(const llvm::StringMap &Map,
117 llvm::StringRef Key) {
118 auto it = Map.find(Key);
119 if (it == Map.end())
120 return std::nullopt;
121 return it->second;
122}
123
124template
126 ResultType Result) {
127 return ParseProgress{State, std::move(Result)};
128}
129
130static llvm::Error makeParseError(const ParseState &S, std::string ErrorMsg) {
131 size_t Pos = S.OriginalInput.size() - S.Input.size();
132 return llvm::make_error(Pos, std::move(ErrorMsg),
133 S.OriginalInput.substr(Pos, 20).str());
134}
135
136
137static ParseState advance(ParseState S, size_t N) {
138 S.Input = S.Input.drop_front(N);
139 return S;
140}
141
145
146
147
148static ExpectedProgressstd::nullopt\_t parseChar(char c, ParseState State) {
150 if (State.Input.empty() || State.Input.front() != c)
152 ("expected char not found: " + llvm::Twine(c)).str());
154}
155
156
157static ExpectedProgressstd::string parseId(ParseState State) {
159 auto Id = State.Input.take_while(
161 if (Id.empty())
162 return makeParseError(State, "failed to parse name");
164}
165
166
167
168static ExpectedProgressstd::string parseStringId(ParseState State) {
170 if (State.Input.empty())
171 return makeParseError(State, "unexpected end of input");
172 if (!State.Input.consume_front("\""))
174 State,
175 "expecting string, but encountered other character or end of input");
176
177 StringRef Id = State.Input.take_until([](char c) { return c == '"'; });
178 if (State.Input.size() == Id.size())
180
182}
183
184
185
186template
187ExpectedProgress parseSingle(ParseFunction ParseElement,
188 RangeSelectorOp Op,
189 ParseState State) {
191 if (!P)
192 return P.takeError();
193
194 auto E = ParseElement(P->State);
195 if (!E)
196 return E.takeError();
197
199 if (!P)
200 return P.takeError();
201
203}
204
205
206
207template
208ExpectedProgress parsePair(ParseFunction ParseElement,
209 RangeSelectorOp<T, T> Op,
210 ParseState State) {
212 if (!P)
213 return P.takeError();
214
215 auto Left = ParseElement(P->State);
216 if (!Left)
217 return Left.takeError();
218
220 if (!P)
221 return P.takeError();
222
223 auto Right = ParseElement(P->State);
224 if (!Right)
225 return Right.takeError();
226
227 P = parseChar(')', Right->State);
228 if (!P)
229 return P.takeError();
230
232 Op(std::move(Left->Value), std::move(Right->Value)));
233}
234
235
236
237
238static ExpectedProgress
240 auto Id = parseId(State);
241 if (!Id)
242 return Id.takeError();
243
244 std::string OpName = std::move(Id->Value);
247
250
253
256
257 return makeParseError(State, "unknown selector name: " + OpName);
258}
259
261 ParseState State = {Input, Input};
264 return Result.takeError();
265 State = Result->State;
266
268 if (State.Input.empty())
269 return Result->Value;
270 return makeParseError(State, "unexpected input after selector");
271}
static ExpectedProgress< std::string > parseStringId(ParseState State)
Definition Parsing.cpp:168
static ExpectedProgress< std::nullopt_t > parseChar(char c, ParseState State)
Definition Parsing.cpp:148
ParseProgress< ResultType > makeParseProgress(ParseState State, ResultType Result)
Definition Parsing.cpp:125
static StringRef consumeWhitespace(StringRef S)
Definition Parsing.cpp:142
ExpectedProgress< RangeSelector > parseSingle(ParseFunction< T > ParseElement, RangeSelectorOp< T > Op, ParseState State)
Definition Parsing.cpp:187
ExpectedProgress< RangeSelector > parsePair(ParseFunction< T > ParseElement, RangeSelectorOp< T, T > Op, ParseState State)
Definition Parsing.cpp:208
std::optional< Element > findOptional(const llvm::StringMap< Element > &Map, llvm::StringRef Key)
Definition Parsing.cpp:116
static llvm::Error makeParseError(const ParseState &S, std::string ErrorMsg)
Definition Parsing.cpp:130
static const llvm::StringMap< RangeSelectorOp< RangeSelector > > & getUnaryRangeSelectors()
Definition Parsing.cpp:95
static ExpectedProgress< RangeSelector > parseRangeSelectorImpl(ParseState State)
Definition Parsing.cpp:239
static ExpectedProgress< std::string > parseId(ParseState State)
Definition Parsing.cpp:157
static ParseState advance(ParseState S, size_t N)
Definition Parsing.cpp:137
static const llvm::StringMap< RangeSelectorOp< RangeSelector, RangeSelector > > & getBinaryRangeSelectors()
Definition Parsing.cpp:109
static const llvm::StringMap< RangeSelectorOp< std::string, std::string > > & getBinaryStringSelectors()
Definition Parsing.cpp:102
static const llvm::StringMap< RangeSelectorOp< std::string > > & getUnaryStringSelectors()
Definition Parsing.cpp:81
Defines parsing functions for Transformer types.
Defines a combinator library supporting the definition of selectors, which select source ranges based...
__device__ __2f16 float c
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
RangeSelector initListElements(std::string ID)
RangeSelector enclose(RangeSelector Begin, RangeSelector End)
Selects from the start of Begin and to the end of End.
RangeSelector merge(RangeSelector First, RangeSelector Second)
Selects the merge of the two ranges, i.e.
RangeSelector member(std::string ID)
Given a MemberExpr, selects the member token. ID is the node's binding in the match result.
RangeSelector between(RangeSelector R1, RangeSelector R2)
Selects the range between R1 and `R2.
RangeSelector elseBranch(std::string ID)
Given an \IfStmt (bound to ID), selects the range of the else branch, starting from the else keyword.
RangeSelector node(std::string ID)
Selects a node, including trailing semicolon, if any (for declarations and non-expression statements)...
RangeSelector encloseNodes(std::string BeginID, std::string EndID)
Convenience version of range where end-points are bound nodes.
RangeSelector after(RangeSelector Selector)
Selects the point immediately following Selector.
MatchConsumer< CharSourceRange > RangeSelector
RangeSelector callArgs(std::string ID)
RangeSelector before(RangeSelector Selector)
Selects the (empty) range [B,B) when Selector selects the range [B,E).
llvm::Expected< RangeSelector > parseRangeSelector(llvm::StringRef Input)
Parses a string representation of a RangeSelector.
Definition Parsing.cpp:260
RangeSelector statement(std::string ID)
Selects a node, including trailing semicolon (always). Useful for selecting expression statements....
RangeSelector expansion(RangeSelector S)
Selects the range from which S was expanded (possibly along with other source), if S is an expansion,...
RangeSelector statements(std::string ID)
RangeSelector name(std::string ID)
Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...
The JSON file list parser is used to communicate input to InstallAPI.
LLVM_READNONE bool isASCII(char c)
Returns true if a byte is an ASCII character.
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)
@ Result
The result type of a method or function.
LLVM_READONLY bool isWhitespace(unsigned char c)
Return true if this character is horizontal or vertical ASCII whitespace: ' ', '\t',...