clang  13.0.0git
Stencil.cpp
Go to the documentation of this file.
1 //===--- Stencil.cpp - Stencil implementation -------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "clang/AST/ASTContext.h"
12 #include "clang/AST/Expr.h"
16 #include "clang/Lex/Lexer.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/Support/Errc.h"
22 #include "llvm/Support/Error.h"
23 #include <atomic>
24 #include <memory>
25 #include <string>
26 
27 using namespace clang;
28 using namespace transformer;
29 
31 using llvm::errc;
32 using llvm::Error;
33 using llvm::Expected;
34 using llvm::StringError;
35 
38  auto &NodesMap = Nodes.getMap();
39  auto It = NodesMap.find(Id);
40  if (It == NodesMap.end())
41  return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument,
42  "Id not bound: " + Id);
43  return It->second;
44 }
45 
46 namespace {
47 // An arbitrary fragment of code within a stencil.
48 struct RawTextData {
49  explicit RawTextData(std::string T) : Text(std::move(T)) {}
51 };
52 
53 // A debugging operation to dump the AST for a particular (bound) AST node.
54 struct DebugPrintNodeData {
55  explicit DebugPrintNodeData(std::string S) : Id(std::move(S)) {}
57 };
58 
59 // Operators that take a single node Id as an argument.
60 enum class UnaryNodeOperator {
61  Parens,
62  Deref,
63  MaybeDeref,
64  AddressOf,
65  MaybeAddressOf,
66  Describe,
67 };
68 
69 // Generic container for stencil operations with a (single) node-id argument.
70 struct UnaryOperationData {
71  UnaryOperationData(UnaryNodeOperator Op, std::string Id)
72  : Op(Op), Id(std::move(Id)) {}
73  UnaryNodeOperator Op;
75 };
76 
77 // The fragment of code corresponding to the selected range.
78 struct SelectorData {
79  explicit SelectorData(RangeSelector S) : Selector(std::move(S)) {}
81 };
82 
83 // A stencil operation to build a member access `e.m` or `e->m`, as appropriate.
84 struct AccessData {
85  AccessData(StringRef BaseId, Stencil Member)
86  : BaseId(std::string(BaseId)), Member(std::move(Member)) {}
87  std::string BaseId;
89 };
90 
91 struct IfBoundData {
92  IfBoundData(StringRef Id, Stencil TrueStencil, Stencil FalseStencil)
93  : Id(std::string(Id)), TrueStencil(std::move(TrueStencil)),
94  FalseStencil(std::move(FalseStencil)) {}
96  Stencil TrueStencil;
97  Stencil FalseStencil;
98 };
99 
100 struct SequenceData {
101  SequenceData(std::vector<Stencil> Stencils) : Stencils(std::move(Stencils)) {}
102  std::vector<Stencil> Stencils;
103 };
104 
105 std::string toStringData(const RawTextData &Data) {
106  std::string Result;
107  llvm::raw_string_ostream OS(Result);
108  OS << "\"";
109  OS.write_escaped(Data.Text);
110  OS << "\"";
111  OS.flush();
112  return Result;
113 }
114 
115 std::string toStringData(const DebugPrintNodeData &Data) {
116  return (llvm::Twine("dPrint(\"") + Data.Id + "\")").str();
117 }
118 
119 std::string toStringData(const UnaryOperationData &Data) {
120  StringRef OpName;
121  switch (Data.Op) {
122  case UnaryNodeOperator::Parens:
123  OpName = "expression";
124  break;
125  case UnaryNodeOperator::Deref:
126  OpName = "deref";
127  break;
128  case UnaryNodeOperator::MaybeDeref:
129  OpName = "maybeDeref";
130  break;
131  case UnaryNodeOperator::AddressOf:
132  OpName = "addressOf";
133  break;
134  case UnaryNodeOperator::MaybeAddressOf:
135  OpName = "maybeAddressOf";
136  break;
137  case UnaryNodeOperator::Describe:
138  OpName = "describe";
139  break;
140  }
141  return (OpName + "(\"" + Data.Id + "\")").str();
142 }
143 
144 std::string toStringData(const SelectorData &) { return "selection(...)"; }
145 
146 std::string toStringData(const AccessData &Data) {
147  return (llvm::Twine("access(\"") + Data.BaseId + "\", " +
148  Data.Member->toString() + ")")
149  .str();
150 }
151 
152 std::string toStringData(const IfBoundData &Data) {
153  return (llvm::Twine("ifBound(\"") + Data.Id + "\", " +
154  Data.TrueStencil->toString() + ", " + Data.FalseStencil->toString() +
155  ")")
156  .str();
157 }
158 
159 std::string toStringData(const MatchConsumer<std::string> &) {
160  return "run(...)";
161 }
162 
163 std::string toStringData(const SequenceData &Data) {
165  Parts.reserve(Data.Stencils.size());
166  for (const auto &S : Data.Stencils)
167  Parts.push_back(S->toString());
168  return (llvm::Twine("seq(") + llvm::join(Parts, ", ") + ")").str();
169 }
170 
171 // The `evalData()` overloads evaluate the given stencil data to a string, given
172 // the match result, and append it to `Result`. We define an overload for each
173 // type of stencil data.
174 
175 Error evalData(const RawTextData &Data, const MatchFinder::MatchResult &,
176  std::string *Result) {
177  Result->append(Data.Text);
178  return Error::success();
179 }
180 
181 static Error printNode(StringRef Id, const MatchFinder::MatchResult &Match,
182  std::string *Result) {
183  std::string Output;
184  llvm::raw_string_ostream Os(Output);
185  auto NodeOrErr = getNode(Match.Nodes, Id);
186  if (auto Err = NodeOrErr.takeError())
187  return Err;
188  NodeOrErr->print(Os, PrintingPolicy(Match.Context->getLangOpts()));
189  *Result += Os.str();
190  return Error::success();
191 }
192 
193 Error evalData(const DebugPrintNodeData &Data,
194  const MatchFinder::MatchResult &Match, std::string *Result) {
195  return printNode(Data.Id, Match, Result);
196 }
197 
198 // FIXME: Consider memoizing this function using the `ASTContext`.
199 static bool isSmartPointerType(QualType Ty, ASTContext &Context) {
200  using namespace ::clang::ast_matchers;
201 
202  // Optimization: hard-code common smart-pointer types. This can/should be
203  // removed if we start caching the results of this function.
204  auto KnownSmartPointer =
205  cxxRecordDecl(hasAnyName("::std::unique_ptr", "::std::shared_ptr"));
206  const auto QuacksLikeASmartPointer = cxxRecordDecl(
208  returns(qualType(pointsTo(type()))))),
210  returns(qualType(references(type()))))));
211  const auto SmartPointer = qualType(hasDeclaration(
212  cxxRecordDecl(anyOf(KnownSmartPointer, QuacksLikeASmartPointer))));
213  return match(SmartPointer, Ty, Context).size() > 0;
214 }
215 
216 Error evalData(const UnaryOperationData &Data,
217  const MatchFinder::MatchResult &Match, std::string *Result) {
218  // The `Describe` operation can be applied to any node, not just expressions,
219  // so it is handled here, separately.
220  if (Data.Op == UnaryNodeOperator::Describe)
221  return printNode(Data.Id, Match, Result);
222 
223  const auto *E = Match.Nodes.getNodeAs<Expr>(Data.Id);
224  if (E == nullptr)
225  return llvm::make_error<StringError>(
226  errc::invalid_argument, "Id not bound or not Expr: " + Data.Id);
228  switch (Data.Op) {
229  case UnaryNodeOperator::Parens:
230  Source = tooling::buildParens(*E, *Match.Context);
231  break;
232  case UnaryNodeOperator::Deref:
233  Source = tooling::buildDereference(*E, *Match.Context);
234  break;
235  case UnaryNodeOperator::MaybeDeref:
236  if (E->getType()->isAnyPointerType() ||
237  isSmartPointerType(E->getType(), *Match.Context)) {
238  // Strip off any operator->. This can only occur inside an actual arrow
239  // member access, so we treat it as equivalent to an actual object
240  // expression.
241  if (const auto *OpCall = dyn_cast<clang::CXXOperatorCallExpr>(E)) {
242  if (OpCall->getOperator() == clang::OO_Arrow &&
243  OpCall->getNumArgs() == 1) {
244  E = OpCall->getArg(0);
245  }
246  }
247  Source = tooling::buildDereference(*E, *Match.Context);
248  break;
249  }
250  *Result += tooling::getText(*E, *Match.Context);
251  return Error::success();
252  case UnaryNodeOperator::AddressOf:
253  Source = tooling::buildAddressOf(*E, *Match.Context);
254  break;
255  case UnaryNodeOperator::MaybeAddressOf:
256  if (E->getType()->isAnyPointerType() ||
257  isSmartPointerType(E->getType(), *Match.Context)) {
258  // Strip off any operator->. This can only occur inside an actual arrow
259  // member access, so we treat it as equivalent to an actual object
260  // expression.
261  if (const auto *OpCall = dyn_cast<clang::CXXOperatorCallExpr>(E)) {
262  if (OpCall->getOperator() == clang::OO_Arrow &&
263  OpCall->getNumArgs() == 1) {
264  E = OpCall->getArg(0);
265  }
266  }
267  *Result += tooling::getText(*E, *Match.Context);
268  return Error::success();
269  }
270  Source = tooling::buildAddressOf(*E, *Match.Context);
271  break;
272  case UnaryNodeOperator::Describe:
273  llvm_unreachable("This case is handled at the start of the function");
274  }
275  if (!Source)
276  return llvm::make_error<StringError>(
277  errc::invalid_argument,
278  "Could not construct expression source from ID: " + Data.Id);
279  *Result += *Source;
280  return Error::success();
281 }
282 
283 Error evalData(const SelectorData &Data, const MatchFinder::MatchResult &Match,
284  std::string *Result) {
285  auto RawRange = Data.Selector(Match);
286  if (!RawRange)
287  return RawRange.takeError();
289  *RawRange, *Match.SourceManager, Match.Context->getLangOpts());
290  if (Range.isInvalid()) {
291  // Validate the original range to attempt to get a meaningful error message.
292  // If it's valid, then something else is the cause and we just return the
293  // generic failure message.
294  if (auto Err = tooling::validateEditRange(*RawRange, *Match.SourceManager))
295  return handleErrors(std::move(Err), [](std::unique_ptr<StringError> E) {
296  assert(E->convertToErrorCode() ==
297  llvm::make_error_code(errc::invalid_argument) &&
298  "Validation errors must carry the invalid_argument code");
299  return llvm::createStringError(
300  errc::invalid_argument,
301  "selected range could not be resolved to a valid source range; " +
302  E->getMessage());
303  });
304  return llvm::createStringError(
305  errc::invalid_argument,
306  "selected range could not be resolved to a valid source range");
307  }
308  // Validate `Range`, because `makeFileCharRange` accepts some ranges that
309  // `validateEditRange` rejects.
310  if (auto Err = tooling::validateEditRange(Range, *Match.SourceManager))
311  return joinErrors(
312  llvm::createStringError(errc::invalid_argument,
313  "selected range is not valid for editing"),
314  std::move(Err));
315  *Result += tooling::getText(Range, *Match.Context);
316  return Error::success();
317 }
318 
319 Error evalData(const AccessData &Data, const MatchFinder::MatchResult &Match,
320  std::string *Result) {
321  const auto *E = Match.Nodes.getNodeAs<Expr>(Data.BaseId);
322  if (E == nullptr)
323  return llvm::make_error<StringError>(errc::invalid_argument,
324  "Id not bound: " + Data.BaseId);
325  if (!E->isImplicitCXXThis()) {
327  E->getType()->isAnyPointerType()
328  ? tooling::buildArrow(*E, *Match.Context)
329  : tooling::buildDot(*E, *Match.Context))
330  *Result += *S;
331  else
332  return llvm::make_error<StringError>(
333  errc::invalid_argument,
334  "Could not construct object text from ID: " + Data.BaseId);
335  }
336  return Data.Member->eval(Match, Result);
337 }
338 
339 Error evalData(const IfBoundData &Data, const MatchFinder::MatchResult &Match,
340  std::string *Result) {
341  auto &M = Match.Nodes.getMap();
342  return (M.find(Data.Id) != M.end() ? Data.TrueStencil : Data.FalseStencil)
343  ->eval(Match, Result);
344 }
345 
346 Error evalData(const MatchConsumer<std::string> &Fn,
347  const MatchFinder::MatchResult &Match, std::string *Result) {
348  Expected<std::string> Value = Fn(Match);
349  if (!Value)
350  return Value.takeError();
351  *Result += *Value;
352  return Error::success();
353 }
354 
355 Error evalData(const SequenceData &Data, const MatchFinder::MatchResult &Match,
356  std::string *Result) {
357  for (const auto &S : Data.Stencils)
358  if (auto Err = S->eval(Match, Result))
359  return Err;
360  return Error::success();
361 }
362 
363 template <typename T> class StencilImpl : public StencilInterface {
364  T Data;
365 
366 public:
367  template <typename... Ps>
368  explicit StencilImpl(Ps &&... Args) : Data(std::forward<Ps>(Args)...) {}
369 
370  Error eval(const MatchFinder::MatchResult &Match,
371  std::string *Result) const override {
372  return evalData(Data, Match, Result);
373  }
374 
375  std::string toString() const override { return toStringData(Data); }
376 };
377 } // namespace
378 
380  return std::make_shared<StencilImpl<RawTextData>>(std::string(Text));
381 }
382 
384  return std::make_shared<StencilImpl<SelectorData>>(std::move(Selector));
385 }
386 
387 Stencil transformer::dPrint(StringRef Id) {
388  return std::make_shared<StencilImpl<DebugPrintNodeData>>(std::string(Id));
389 }
390 
392  return std::make_shared<StencilImpl<UnaryOperationData>>(
393  UnaryNodeOperator::Parens, std::string(Id));
394 }
395 
396 Stencil transformer::deref(llvm::StringRef ExprId) {
397  return std::make_shared<StencilImpl<UnaryOperationData>>(
398  UnaryNodeOperator::Deref, std::string(ExprId));
399 }
400 
401 Stencil transformer::maybeDeref(llvm::StringRef ExprId) {
402  return std::make_shared<StencilImpl<UnaryOperationData>>(
403  UnaryNodeOperator::MaybeDeref, std::string(ExprId));
404 }
405 
406 Stencil transformer::addressOf(llvm::StringRef ExprId) {
407  return std::make_shared<StencilImpl<UnaryOperationData>>(
408  UnaryNodeOperator::AddressOf, std::string(ExprId));
409 }
410 
411 Stencil transformer::maybeAddressOf(llvm::StringRef ExprId) {
412  return std::make_shared<StencilImpl<UnaryOperationData>>(
413  UnaryNodeOperator::MaybeAddressOf, std::string(ExprId));
414 }
415 
416 Stencil transformer::describe(StringRef Id) {
417  return std::make_shared<StencilImpl<UnaryOperationData>>(
418  UnaryNodeOperator::Describe, std::string(Id));
419 }
420 
421 Stencil transformer::access(StringRef BaseId, Stencil Member) {
422  return std::make_shared<StencilImpl<AccessData>>(BaseId, std::move(Member));
423 }
424 
425 Stencil transformer::ifBound(StringRef Id, Stencil TrueStencil,
426  Stencil FalseStencil) {
427  return std::make_shared<StencilImpl<IfBoundData>>(Id, std::move(TrueStencil),
428  std::move(FalseStencil));
429 }
430 
432  return std::make_shared<StencilImpl<MatchConsumer<std::string>>>(
433  std::move(Fn));
434 }
435 
436 Stencil transformer::catVector(std::vector<Stencil> Parts) {
437  // Only one argument, so don't wrap in sequence.
438  if (Parts.size() == 1)
439  return std::move(Parts[0]);
440  return std::make_shared<StencilImpl<SequenceData>>(std::move(Parts));
441 }
clang::index::SymbolRole::AddressOf
@ AddressOf
clang::Lexer::makeFileCharRange
static CharSourceRange makeFileCharRange(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)
Accepts a range and returns a character range with file locations.
Definition: Lexer.cpp:878
clang::tooling::buildDot
llvm::Optional< std::string > buildDot(const Expr &E, const ASTContext &Context)
Adds a dot to the end of the given expression, but adds parentheses when needed by the syntax,...
Definition: SourceCodeBuilders.cpp:115
clang::ast_matchers::hasAnyName
const internal::VariadicFunction< internal::Matcher< NamedDecl >, StringRef, internal::hasAnyNameFunc > hasAnyName
Matches NamedDecl nodes that have any of the specified names.
Definition: ASTMatchersInternal.cpp:982
clang::transformer::describe
Stencil describe(llvm::StringRef Id)
Produces a human-readable rendering of the node bound to Id, suitable for diagnostics and debugging.
Nodes
BoundNodesTreeBuilder Nodes
Definition: ASTMatchFinder.cpp:82
Error
llvm::Error Error
Definition: ByteCodeEmitter.cpp:19
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::transformer::access
Stencil access(llvm::StringRef BaseId, Stencil Member)
Constructs a MemberExpr that accesses the named member (Member) of the object bound to BaseId.
clang::ast_matchers::anyOf
const internal::VariadicOperatorMatcherFunc< 2, std::numeric_limits< unsigned >::max()> anyOf
Matches if any of the given matchers matches.
Definition: ASTMatchersInternal.cpp:974
llvm::SmallVector< std::string, 2 >
clang::ast_matchers::MatchFinder
A class to allow finding matches over the Clang AST.
Definition: ASTMatchFinder.h:68
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:661
clang::tooling::buildArrow
llvm::Optional< std::string > buildArrow(const Expr &E, const ASTContext &Context)
Adds an arrow to the end of the given expression, but adds parentheses when needed by the syntax,...
Definition: SourceCodeBuilders.cpp:139
clang::ast_matchers::type
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Definition: ASTMatchersInternal.cpp:772
clang::transformer::run
Stencil run(MatchConsumer< std::string > C)
Wraps a MatchConsumer in a Stencil, so that it can be used in a Stencil.
Definition: Stencil.cpp:431
clang::transformer::deref
Stencil deref(llvm::StringRef ExprId)
Constructs an idiomatic dereferencing of the expression bound to ExprId.
Definition: Stencil.cpp:396
llvm::Optional< std::string >
clang::transformer::Stencil
std::shared_ptr< StencilInterface > Stencil
A sequence of code fragments, references to parameters and code-generation operations that together c...
Definition: Stencil.h:46
llvm::Expected
Definition: LLVM.h:41
ASTMatchFinder.h
clang::PrintingPolicy
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:59
clang::transformer::detail::makeStencil
Stencil makeStencil(llvm::StringRef Text)
Convenience function to construct a Stencil.
clang::transformer::RangeSelector
MatchConsumer< CharSourceRange > RangeSelector
Definition: RangeSelector.h:27
Expected
llvm::Expected< T > Expected
Definition: ByteCodeExprGen.cpp:22
clang::transformer::addressOf
Stencil addressOf(llvm::StringRef ExprId)
Constructs an expression that idiomatically takes the address of the expression bound to ExprId.
Definition: Stencil.cpp:406
clang::ast_matchers
Definition: ASTMatchers.h:98
clang::transformer::maybeDeref
Stencil maybeDeref(llvm::StringRef ExprId)
If ExprId is of pointer type, constructs an idiomatic dereferencing of the expression bound to ExprId...
Definition: Stencil.cpp:401
clang::tooling::buildParens
llvm::Optional< std::string > buildParens(const Expr &E, const ASTContext &Context)
Builds source for an expression, adding parens if needed for unambiguous parsing.
Definition: SourceCodeBuilders.cpp:63
Id
int Id
Definition: ASTDiff.cpp:191
clang::threadSafety::sx::toString
std::string toString(const til::SExpr *E)
Definition: ThreadSafetyCommon.h:89
clang::tooling::buildAddressOf
llvm::Optional< std::string > buildAddressOf(const Expr &E, const ASTContext &Context)
Builds idiomatic source for taking the address of E: prefix with & but simplify when it already begin...
Definition: SourceCodeBuilders.cpp:94
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:187
ASTMatchers.h
clang::DeclaratorContext::Member
@ Member
SourceCodeBuilders.h
clang::ast_matchers::cxxMethodDecl
const internal::VariadicDynCastAllOfMatcher< Decl, CXXMethodDecl > cxxMethodDecl
Matches method declarations.
Definition: ASTMatchersInternal.cpp:785
clang::transformer::maybeAddressOf
Stencil maybeAddressOf(llvm::StringRef ExprId)
If ExprId is not a pointer type, constructs an expression that idiomatically takes the address of the...
Definition: Stencil.cpp:411
Expr.h
ASTContext.h
clang::transformer::MatchComputation
A failable computation over nodes bound by AST matchers, with (limited) reflection via the toString m...
Definition: MatchConsumer.h:64
clang::transformer::EditKind::Range
@ Range
clang::tooling::buildDereference
llvm::Optional< std::string > buildDereference(const Expr &E, const ASTContext &Context)
Builds idiomatic source for the dereferencing of E: prefix with * but simplify when it already begins...
Definition: SourceCodeBuilders.cpp:74
SourceLocation.h
clang::transformer::expression
Stencil expression(llvm::StringRef Id)
Generates the source of the expression bound to Id, wrapping it in parentheses if it may parse differ...
Definition: Stencil.cpp:391
SourceCode.h
clang::tooling::validateEditRange
llvm::Error validateEditRange(const CharSourceRange &Range, const SourceManager &SM)
Determines whether Range is one that can be edited by a rewrite; generally, one that starts and ends ...
Definition: SourceCode.cpp:53
Lexer.h
Value
Value
Definition: UninitializedValues.cpp:102
clang::CharSourceRange
Represents a character-granular source range.
Definition: SourceLocation.h:255
Stencil.h
clang::transformer::MatchConsumer
std::function< Expected< T >(const ast_matchers::MatchFinder::MatchResult &)> MatchConsumer
A failable computation over nodes bound by AST matchers.
Definition: MatchConsumer.h:35
clang::ast_matchers::MatchFinder::MatchResult::Context
clang::ASTContext *const Context
Utilities for interpreting the matched AST structures.
Definition: ASTMatchFinder.h:84
getNode
static llvm::Expected< DynTypedNode > getNode(const ast_matchers::BoundNodes &Nodes, StringRef Id)
Definition: Stencil.cpp:37
ASTTypeTraits.h
clang::ast_matchers::MatchFinder::MatchResult
Contains all information for a given match.
Definition: ASTMatchFinder.h:74
clang::ast_matchers::BoundNodes::getMap
const IDToNodeMap & getMap() const
Retrieve mapping from binding identifiers to bound nodes.
Definition: ASTMatchers.h:124
std
Definition: Format.h:3580
clang::transformer::ifBound
MatchConsumer< T > ifBound(std::string ID, MatchConsumer< T > TrueC, MatchConsumer< T > FalseC)
Chooses between the two consumers, based on whether ID is bound in the match.
Definition: MatchConsumer.h:47
clang::ast_matchers::MatchFinder::MatchResult::Nodes
const BoundNodes Nodes
Contains the nodes bound on the current match.
Definition: ASTMatchFinder.h:80
clang::ast_matchers::BoundNodes::getNodeAs
const T * getNodeAs(StringRef ID) const
Returns the AST node bound to ID.
Definition: ASTMatchers.h:114
clang
Dataflow Directional Tag Classes.
Definition: CalledOnceCheck.h:17
Text
StringRef Text
Definition: Format.cpp:2150
clang::Selector
Smart pointer class that efficiently represents Objective-C method names.
Definition: IdentifierTable.h:684
clang::ast_matchers::match
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
Definition: ASTMatchFinder.h:310
clang::tooling::getText
StringRef getText(CharSourceRange Range, const ASTContext &Context)
Returns the source-code text in the specified range.
Definition: SourceCode.cpp:31
clang::ast_matchers::BoundNodes
Maps string IDs to AST nodes matched by parts of a matcher.
Definition: ASTMatchers.h:107
clang::ast_matchers::cxxRecordDecl
const internal::VariadicDynCastAllOfMatcher< Decl, CXXRecordDecl > cxxRecordDecl
Matches C++ class declarations.
Definition: ASTMatchersInternal.cpp:745
clang::ast_matchers::MatchFinder::MatchResult::SourceManager
clang::SourceManager *const SourceManager
Definition: ASTMatchFinder.h:85
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::format::make_error_code
std::error_code make_error_code(ParseError e)
Definition: Format.cpp:778
clang::ast_matchers::hasDeclaration
internal::PolymorphicMatcher< internal::HasDeclarationMatcher, void(internal::HasDeclarationSupportedTypes), internal::Matcher< Decl > > hasDeclaration(const internal::Matcher< Decl > &InnerMatcher)
Matches a node if the declaration associated with that node matches the given matcher.
Definition: ASTMatchers.h:3549
clang::transformer::catVector
Stencil catVector(std::vector< Stencil > Parts)
Constructs the string representing the concatenation of the given Parts.
Definition: Stencil.cpp:436
clang::transformer::dPrint
Stencil dPrint(llvm::StringRef Id)
For debug use only; semantics are not guaranteed.
clang::ast_matchers::hasOverloadedOperatorName
internal::PolymorphicMatcher< internal::HasOverloadedOperatorNameMatcher, AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl), std::vector< std::string > > hasOverloadedOperatorName(StringRef Name)
Matches overloaded operator names.
Definition: ASTMatchers.h:3038
clang::ASTContext::getLangOpts
const LangOptions & getLangOpts() const
Definition: ASTContext.h:709
clang::ento::ObjKind::OS
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
clang::ast_matchers::qualType
const internal::VariadicAllOfMatcher< QualType > qualType
Matches QualTypes in the clang AST.
Definition: ASTMatchersInternal.cpp:771