clang: lib/Tooling/Transformer/RangeSelector.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

16#include "llvm/ADT/StringRef.h"

17#include "llvm/Support/Errc.h"

18#include "llvm/Support/Error.h"

19#include

20#include

21#include

22

23using namespace clang;

24using namespace transformer;

25

27using llvm::Error;

28using llvm::StringError;

29

31

33 return llvm::make_error(llvm::errc::invalid_argument, Message);

34}

35

38 " kind=" + Kind.asStringRef() + ")");

39}

40

45 " kind=" + Kind.asStringRef() + ")");

46}

47

49 StringRef Property) {

51 "' (node id=" + ID + ")");

52}

53

55 StringRef ID) {

56 auto &NodesMap = Nodes.getMap();

57 auto It = NodesMap.find(ID);

58 if (It == NodesMap.end())

60 return It->second;

61}

62

63

69

73

75}

76

77

78

83 while (true) {

87

91

92 if (T.is(TK))

93 return T.getLocation();

94

95 Start = L;

96 }

97}

98

102 if (!SelectedRange)

103 return SelectedRange.takeError();

105 };

106}

107

111 if (!SelectedRange)

112 return SelectedRange.takeError();

114 if (SelectedRange->isTokenRange()) {

115

116

117

118

119

120

123 *Result.SourceManager, Result.Context->getLangOpts());

126 "after: can't resolve sub-range to valid source range");

128 }

129

131 };

132}

133

138 return Node.takeError();

142 *Result.Context)

144 };

145}

146

151 return Node.takeError();

153 *Result.Context);

154 };

155}

156

160 if (!BeginRange)

161 return BeginRange.takeError();

163 if (!EndRange)

164 return EndRange.takeError();

167

168

169 if (Result.SourceManager->isBeforeInTranslationUnit(E, B)) {

171 }

173 };

174}

175

177 std::string EndID) {

179}

180

185 return Node.takeError();

188 M->getMemberNameInfo().getSourceRange());

190 };

191}

192

196 if (!N)

197 return N.takeError();

198 auto &Node = *N;

200 if (D->getDeclName().isIdentifier())

204

205

206

207

208

211 return R;

212 }

214 if (E->getNameInfo().getName().isIdentifier())

218 }

220 if (!I->isMemberInitializer() && I->isWritten())

224 }

228 if (!ET.isNull())

229 Loc = ET.getNamedTypeLoc();

234 }

236 "DeclRefExpr, NamedDecl, CXXCtorInitializer, TypeLoc");

237 };

238}

239

240namespace {

241

242

243

244

245

246

247template <typename T, CharSourceRange (*Func)(const MatchResult &, const T &)>

248class RelativeSelector {

249 std::string ID;

250

251public:

252 RelativeSelector(std::string ID) : ID(std::move(ID)) {}

253

256 if (!N)

257 return N.takeError();

258 if (const auto *Arg = N->get<T>())

259 return Func(Result, *Arg);

260 return typeError(ID, N->getNodeKind());

261 }

262};

263}

264

265

266

267

268

269namespace {

270

275}

276}

277

279 return RelativeSelector<CompoundStmt, getStatementsRange>(std::move(ID));

280}

281

282namespace {

283

285

287 return E.getParenOrBraceRange().getEnd();

288}

289

291 return tok::TokenKind::l_paren;

292}

293

295 return isa(E) ? tok::TokenKind::l_paren

296 : tok::TokenKind::l_brace;

297}

298

299template

305}

306

307

308template

310 const ExprWithArgs &CE) {

313 findArgStartDelimiter(CE, RLoc, *Result.SourceManager,

315 .getLocWithOffset(1),

316 RLoc);

317}

318}

319

321 return RelativeSelector<CallExpr, getArgumentsRange>(std::move(ID));

322}

323

326 getArgumentsRange>(std::move(ID));

327}

328

329namespace {

330

331

335 E.getRBraceLoc());

336}

337}

338

340 return RelativeSelector<InitListExpr, getElementsRange>(std::move(ID));

341}

342

343namespace {

344

348 tok::TokenKind::semi, *Result.Context);

349}

350}

351

353 return RelativeSelector<IfStmt, getElseRange>(std::move(ID));

354}

355

359 if (!SRange)

360 return SRange.takeError();

361 return Result.SourceManager->getExpansionRange(*SRange);

362 };

363}

BoundNodesTreeBuilder Nodes

static Error invalidArgumentError(Twine Message)

static SourceLocation findPreviousTokenKind(SourceLocation Start, const SourceManager &SM, const LangOptions &LangOpts, tok::TokenKind TK)

static SourceLocation findPreviousTokenStart(SourceLocation Start, const SourceManager &SM, const LangOptions &LangOpts)

static Error missingPropertyError(StringRef ID, Twine Description, StringRef Property)

static Error typeError(StringRef ID, const ASTNodeKind &Kind)

static Expected< DynTypedNode > getNode(const ast_matchers::BoundNodes &Nodes, StringRef ID)

Defines a combinator library supporting the definition of selectors, which select source ranges based...

Defines the clang::SourceLocation class and associated facilities.

Defines the clang::TypeLoc interface and its subclasses.

Represents a call to a C++ constructor.

Represents a C++ base or member initializer.

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

Represents a character-granular source range.

static CharSourceRange getCharRange(SourceRange R)

static CharSourceRange getTokenRange(SourceRange R)

CompoundStmt - This represents a group of statements like { stmt stmt }.

SourceLocation getLBracLoc() const

SourceLocation getRBracLoc() const

A reference to a declared variable, function, enum, etc.

Decl - This represents one declaration (or definition), e.g.

SourceLocation getLocation() const

const LangOptions & getLangOpts() const LLVM_READONLY

Helper to get the language options from the ASTContext.

ASTNodeKind getNodeKind() const

SourceRange getSourceRange() const

For nodes which represent textual entities in the source code, return their SourceRange.

const T * get() const

Retrieve the stored node as type T.

This represents one expression.

IfStmt - This represents an if/then/else.

Describes an C or C++ initializer list.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

static CharSourceRange makeFileCharRange(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)

Accepts a range and returns a character range with file locations.

static SourceLocation GetBeginningOfToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)

Given a location any where in a source buffer, find the location that corresponds to the beginning of...

static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, const LangOptions &LangOpts, bool IgnoreWhiteSpace=false)

Relex the token at the specified location.

MemberExpr - [C99 6.5.2.3] Structure and Union Members.

This represents a decl that may have a name.

Smart pointer class that efficiently represents Objective-C method names.

Encodes a location in the source.

SourceLocation getLocWithOffset(IntTy Offset) const

Return a source location with the specified offset from this SourceLocation.

This class handles loading and caching of source files into memory.

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

Stmt - This represents one statement.

SourceLocation getBeginLoc() const LLVM_READONLY

Token - This structure provides full information about a lexed token.

Base wrapper for a particular "section" of type source info.

Maps string IDs to AST nodes matched by parts of a matcher.

A class to allow finding matches over the Clang AST.

TokenKind

Provides a simple uniform namespace for tokens from all C languages.

RangeSelector initListElements(std::string ID)

RangeSelector enclose(RangeSelector Begin, RangeSelector End)

Selects from the start of Begin and to the end of End.

RangeSelector member(std::string ID)

Given a MemberExpr, selects the member token.

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)...

MatchConsumer< CharSourceRange > RangeSelector

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.

RangeSelector constructExprArgs(std::string ID)

RangeSelector callArgs(std::string ID)

RangeSelector before(RangeSelector Selector)

Selects the (empty) range [B,B) when Selector selects the range [B,E).

RangeSelector statement(std::string ID)

Selects a node, including trailing semicolon (always).

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.

@ Property

The type of a property.

const FunctionProtoType * T

Contains all information for a given match.