18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/Support/Errc.h" 25 using namespace clang;
26 using namespace transformer;
33 using llvm::StringError;
37 auto &NodesMap = Nodes.
getMap();
38 auto It = NodesMap.find(Id);
39 if (It == NodesMap.end())
40 return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument,
41 "Id not bound: " + Id);
48 explicit RawTextData(std::string T) :
Text(std::move(T)) {}
53 struct DebugPrintNodeData {
54 explicit DebugPrintNodeData(std::string S) :
Id(std::move(S)) {}
68 struct UnaryOperationData {
70 : Op(Op),
Id(std::move(Id)) {}
83 AccessData(StringRef BaseId,
Stencil Member)
84 : BaseId(BaseId), Member(std::move(Member)) {}
91 :
Id(Id), TrueStencil(std::move(TrueStencil)),
92 FalseStencil(std::move(FalseStencil)) {}
99 SequenceData(std::vector<Stencil> Stencils) : Stencils(std::move(Stencils)) {}
100 std::vector<Stencil> Stencils;
103 std::string toStringData(
const RawTextData &Data) {
105 llvm::raw_string_ostream OS(Result);
107 OS.write_escaped(Data.Text);
113 std::string toStringData(
const DebugPrintNodeData &Data) {
114 return (llvm::Twine(
"dPrint(\"") + Data.Id +
"\")").str();
117 std::string toStringData(
const UnaryOperationData &Data) {
120 case UnaryNodeOperator::Parens:
121 OpName =
"expression";
123 case UnaryNodeOperator::Deref:
126 case UnaryNodeOperator::MaybeDeref:
127 OpName =
"maybeDeref";
129 case UnaryNodeOperator::AddressOf:
130 OpName =
"addressOf";
132 case UnaryNodeOperator::MaybeAddressOf:
133 OpName =
"maybeAddressOf";
136 return (OpName +
"(\"" + Data.Id +
"\")").str();
139 std::string toStringData(
const SelectorData &) {
return "selection(...)"; }
141 std::string toStringData(
const AccessData &Data) {
142 return (llvm::Twine(
"access(\"") + Data.BaseId +
"\", " +
143 Data.Member->toString() +
")")
147 std::string toStringData(
const IfBoundData &Data) {
148 return (llvm::Twine(
"ifBound(\"") + Data.Id +
"\", " +
149 Data.TrueStencil->toString() +
", " + Data.FalseStencil->toString() +
158 std::string toStringData(
const SequenceData &Data) {
160 Parts.reserve(Data.Stencils.size());
161 for (
const auto &S : Data.Stencils)
162 Parts.push_back(S->toString());
163 return (llvm::Twine(
"seq(") + llvm::join(Parts,
", ") +
")").str();
171 std::string *Result) {
172 Result->append(Data.Text);
173 return Error::success();
176 Error evalData(
const DebugPrintNodeData &Data,
179 llvm::raw_string_ostream Os(Output);
181 if (
auto Err = NodeOrErr.takeError())
185 return Error::success();
188 Error evalData(
const UnaryOperationData &Data,
192 return llvm::make_error<StringError>(
193 errc::invalid_argument,
"Id not bound or not Expr: " + Data.Id);
196 case UnaryNodeOperator::Parens:
199 case UnaryNodeOperator::Deref:
202 case UnaryNodeOperator::MaybeDeref:
203 if (!E->getType()->isAnyPointerType()) {
205 return Error::success();
209 case UnaryNodeOperator::AddressOf:
212 case UnaryNodeOperator::MaybeAddressOf:
213 if (E->getType()->isAnyPointerType()) {
215 return Error::success();
221 return llvm::make_error<StringError>(
222 errc::invalid_argument,
223 "Could not construct expression source from ID: " + Data.Id);
225 return Error::success();
229 std::string *Result) {
230 auto Range = Data.Selector(Match);
232 return Range.takeError();
234 return Error::success();
238 std::string *Result) {
241 return llvm::make_error<StringError>(errc::invalid_argument,
242 "Id not bound: " + Data.BaseId);
243 if (!E->isImplicitCXXThis()) {
245 E->getType()->isAnyPointerType()
250 return llvm::make_error<StringError>(
251 errc::invalid_argument,
252 "Could not construct object text from ID: " + Data.BaseId);
254 return Data.Member->eval(Match, Result);
258 std::string *Result) {
260 return (M.find(Data.Id) != M.end() ? Data.TrueStencil : Data.FalseStencil)
261 ->eval(Match, Result);
268 return Value.takeError();
270 return Error::success();
274 std::string *Result) {
275 for (
const auto &S : Data.Stencils)
276 if (
auto Err = S->eval(Match, Result))
278 return Error::success();
285 template <
typename... Ps>
286 explicit StencilImpl(Ps &&... Args) : Data(std::forward<Ps>(Args)...) {}
289 std::string *Result)
const override {
290 return evalData(Data, Match, Result);
293 std::string
toString()
const override {
return toStringData(Data); }
304 return std::make_shared<StencilImpl<RawTextData>>(
Text);
308 return std::make_shared<StencilImpl<SelectorData>>(std::move(Selector));
312 return std::make_shared<StencilImpl<DebugPrintNodeData>>(
Id);
316 return std::make_shared<StencilImpl<UnaryOperationData>>(
317 UnaryNodeOperator::Parens,
Id);
321 return std::make_shared<StencilImpl<UnaryOperationData>>(
322 UnaryNodeOperator::Deref, ExprId);
326 return std::make_shared<StencilImpl<UnaryOperationData>>(
327 UnaryNodeOperator::MaybeDeref, ExprId);
331 return std::make_shared<StencilImpl<UnaryOperationData>>(
332 UnaryNodeOperator::AddressOf, ExprId);
336 return std::make_shared<StencilImpl<UnaryOperationData>>(
337 UnaryNodeOperator::MaybeAddressOf, ExprId);
341 return std::make_shared<StencilImpl<AccessData>>(BaseId, std::move(Member));
346 return std::make_shared<StencilImpl<IfBoundData>>(
Id, std::move(TrueStencil),
347 std::move(FalseStencil));
351 return std::make_shared<StencilImpl<MatchConsumer<std::string>>>(
357 if (Parts.size() == 1)
358 return std::move(Parts[0]);
359 return std::make_shared<StencilImpl<SequenceData>>(std::move(Parts));
A class to allow finding matches over the Clang AST.
Defines the clang::ASTContext interface.
Smart pointer class that efficiently represents Objective-C method names.
llvm::Expected< T > Expected
Describes how types, statements, expressions, and declarations should be printed. ...
BoundNodesTreeBuilder Nodes
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
const IDToNodeMap & getMap() const
Retrieve mapping from binding identifiers to bound nodes.
const T * getNodeAs(StringRef ID) const
Returns the AST node bound to ID.
This file defines the Stencil abstraction: a code-generating object, parameterized by named reference...
This represents one expression.
Contains all information for a given match.
This file collects facilities for generating source code strings.
Maps string IDs to AST nodes matched by parts of a matcher.
clang::ASTContext *const Context
Utilities for interpreting the matched AST structures.
static llvm::Expected< DynTypedNode > getNode(const ast_matchers::BoundNodes &Nodes, StringRef Id)
ast_type_traits::DynTypedNode DynTypedNode
const BoundNodes Nodes
Contains the nodes bound on the current match.
Dataflow Directional Tag Classes.
const LangOptions & getLangOpts() const