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

22using namespace clang;

24

26using llvm::Error;

27using llvm::StringError;

28

30

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

33}

34

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

38}

39

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

45}

46

48 StringRef Property) {

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

51}

52

54 StringRef ID) {

55 auto &NodesMap = Nodes.getMap();

56 auto It = NodesMap.find(ID);

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

59 return It->second;

60}

61

62

75

76

77

82 while (true) {

86

90

91 if (T.is(TK))

92 return T.getLocation();

93

94 Start = L;

95 }

96}

97

101 if (!SelectedRange)

102 return SelectedRange.takeError();

104 };

105}

106

110 if (!SelectedRange)

111 return SelectedRange.takeError();

113 if (SelectedRange->isTokenRange()) {

114

115

116

117

118

119

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

123 if (Range.isInvalid())

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

126 End = Range.getEnd();

127 }

128

130 };

131}

132

136 if (!Node)

137 return Node.takeError();

138 return (Node->get<Decl>() != nullptr ||

139 (Node->get<Stmt>() != nullptr && Node->get<Expr>() == nullptr))

143 Node->getSourceRange(true));

144 };

145}

146

150 if (!Node)

151 return Node.takeError();

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 if (!FirstRange)

186 return FirstRange.takeError();

188 if (!SecondRange)

189 return SecondRange.takeError();

190

195

197 Result.SourceManager->isBeforeInTranslationUnit(FirstB, SecondB)

198 ? FirstB

199 : SecondB;

200 if (FirstRange->isTokenRange() && SecondRange->isTokenRange()) {

201

203 Result.SourceManager->isBeforeInTranslationUnit(FirstE, SecondE)

204 ? SecondE

205 : FirstE;

207 }

208

209 if (FirstRange->isTokenRange()) {

210

211

213 *Result.SourceManager,

214 Result.Context->getLangOpts());

217 "merge: can't resolve first token range to valid source range");

218 }

219 if (SecondRange->isTokenRange()) {

220

221

223 *Result.SourceManager,

224 Result.Context->getLangOpts());

227 "merge: can't resolve second token range to valid source range");

228 }

229

231 Result.SourceManager->isBeforeInTranslationUnit(FirstE, SecondE)

232 ? SecondE

233 : FirstE;

235 };

236}

237

241 if (!Node)

242 return Node.takeError();

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

246 return typeError(ID, Node->getNodeKind(), "MemberExpr");

247 };

248}

249

253 if (!N)

254 return N.takeError();

255 auto &Node = *N;

256 if (const auto *D = Node.get<NamedDecl>()) {

257 if (!D->getDeclName().isIdentifier())

261

262

263

264

265

267 if (Text != D->getName())

268 return llvm::make_error(

269 llvm::errc::not_supported,

270 "range selected by name(node id=" + ID + "): '" + Text +

271 "' is different from decl name '" + D->getName() + "'");

272 return R;

273 }

274 if (const auto *E = Node.get<DeclRefExpr>()) {

275 if (!E->getNameInfo().getName().isIdentifier())

279 }

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

285 }

286 if (const auto *T = Node.get<TypeLoc>()) {

291 }

292 return typeError(ID, Node.getNodeKind(),

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

294 };

295}

296

297namespace {

298

299

300

301

302

303

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

305class RelativeSelector {

306 std::string ID;

307

308public:

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

310

313 if (!N)

314 return N.takeError();

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

316 return Func(Result, *Arg);

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

318 }

319};

320}

321

322

323

324

325

326namespace {

327

332}

333}

334

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

337}

338

339namespace {

340

346}

347

348

349

353 for (int i = CE.getNumArgs() - 1; i >= 0; --i) {

356 continue;

358 }

359 return {};

360}

361

362

363CharSourceRange getCallArgumentsRange(const MatchResult &Result,

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

368 Result.Context->getLangOpts())

369 .getLocWithOffset(1),

370 RLoc);

371}

372

373

374

375CharSourceRange getConstructArgumentsRange(const MatchResult &Result,

380 Result.Context->getLangOpts()),

381 R.getEnd());

382 }

383

387 findLastArgEnd(CE, *Result.SourceManager,

388 Result.Context->getLangOpts()));

389 }

390

391 return {};

392}

393

394}

395

397 return RelativeSelector<CallExpr, getCallArgumentsRange>(std::move(ID));

398}

399

401 return RelativeSelector<CXXConstructExpr, getConstructArgumentsRange>(

402 std::move(ID));

403}

404

405namespace {

406

407

412}

413}

414

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

417}

418

419namespace {

420

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

425}

426}

427

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

430}

431

435 if (!SRange)

436 return SRange.takeError();

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

438 };

439}

static Error invalidArgumentError(Twine Message)

Definition RangeSelector.cpp:31

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

Definition RangeSelector.cpp:78

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

Definition RangeSelector.cpp:63

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

Definition RangeSelector.cpp:47

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

Definition RangeSelector.cpp:35

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

Definition RangeSelector.cpp:53

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.

SourceRange getParenOrBraceRange() const

Expr * getArg(unsigned Arg)

Return the specified argument.

unsigned getNumArgs() const

Return the number of arguments to the constructor call.

Represents a C++ base or member initializer.

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

Expr * getArg(unsigned Arg)

getArg - Return the specified argument.

unsigned getNumArgs() const

getNumArgs - Return the number of actual arguments to this call.

SourceLocation getRParenLoc() const

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.

This represents one expression.

IfStmt - This represents an if/then/else.

SourceLocation getElseLoc() const

SourceLocation getEndLoc() const LLVM_READONLY

Describes an C or C++ initializer list.

SourceLocation getLBraceLoc() const

SourceLocation getRBraceLoc() const

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.

static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)

Computes the source location just past the end of the token at this source 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.

Stmt - This represents one statement.

SourceLocation getEndLoc() const LLVM_READONLY

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.

const IDToNodeMap & getMap() const

Retrieve mapping from binding identifiers to bound nodes.

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)

Definition RangeSelector.cpp:415

RangeSelector enclose(RangeSelector Begin, RangeSelector End)

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

Definition RangeSelector.cpp:157

RangeSelector merge(RangeSelector First, RangeSelector Second)

Selects the merge of the two ranges, i.e.

Definition RangeSelector.cpp:181

RangeSelector member(std::string ID)

Given a MemberExpr, selects the member token. ID is the node's binding in the match result.

Definition RangeSelector.cpp:238

RangeSelector elseBranch(std::string ID)

Given an \IfStmt (bound to ID), selects the range of the else branch, starting from the else keyword.

Definition RangeSelector.cpp:428

RangeSelector node(std::string ID)

Selects a node, including trailing semicolon, if any (for declarations and non-expression statements)...

Definition RangeSelector.cpp:133

RangeSelector encloseNodes(std::string BeginID, std::string EndID)

Convenience version of range where end-points are bound nodes.

Definition RangeSelector.cpp:176

RangeSelector after(RangeSelector Selector)

Selects the point immediately following Selector.

Definition RangeSelector.cpp:107

RangeSelector constructExprArgs(std::string ID)

Definition RangeSelector.cpp:400

MatchConsumer< CharSourceRange > RangeSelector

RangeSelector callArgs(std::string ID)

Definition RangeSelector.cpp:396

RangeSelector before(RangeSelector Selector)

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

Definition RangeSelector.cpp:98

RangeSelector statement(std::string ID)

Selects a node, including trailing semicolon (always). Useful for selecting expression statements....

Definition RangeSelector.cpp:147

RangeSelector expansion(RangeSelector S)

Selects the range from which S was expanded (possibly along with other source), if S is an expansion,...

Definition RangeSelector.cpp:432

RangeSelector statements(std::string ID)

Definition RangeSelector.cpp:335

RangeSelector name(std::string ID)

Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...

Definition RangeSelector.cpp:250

The JSON file list parser is used to communicate input to InstallAPI.

bool isa(CodeGen::Address addr)

@ Result

The result type of a method or function.

const FunctionProtoType * T

llvm::Expected< QualType > ExpectedType

Contains all information for a given match.