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',...