clang: lib/Tooling/Transformer/SourceCodeBuilders.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
16#include "llvm/ADT/Twine.h"
17#include
18
19using namespace clang;
20using namespace tooling;
21
24 if (const auto *CE = dyn_cast(Expr)) {
25 if (CE->getNumArgs() > 0 &&
28 }
30}
31
34
35
36 if (isa(Expr) || isa(Expr) ||
37 isa(Expr))
38 return true;
39
40
41
42
43
44
45 if (const auto *Op = dyn_cast(Expr))
46 return Op->getOperator() != OO_Call && Op->getOperator() != OO_Subscript &&
47 Op->getOperator() != OO_Arrow;
48
49 return false;
50}
51
54 if (isa(Expr) || isa(Expr))
55 return true;
56
57 if (const auto *Op = dyn_cast(Expr))
58 return Op->getNumArgs() == 2 && Op->getOperator() != OO_PlusPlus &&
59 Op->getOperator() != OO_MinusMinus && Op->getOperator() != OO_Call &&
60 Op->getOperator() != OO_Subscript;
61
62 return false;
63}
64
66 using namespace ast_matchers;
67 const auto PointerLikeTy = type(hasUnqualifiedDesugaredType(
69 "::std::unique_ptr", "::std::shared_ptr", "::std::weak_ptr",
70 "::std::optional", "::absl::optional", "::llvm::Optional",
71 "absl::StatusOr", "::llvm::Expected"))))));
72 return match(PointerLikeTy, Ty, Context).size() > 0;
73}
74
78 if (Text.empty())
79 return std::nullopt;
81 return ("(" + Text + ")").str();
82 return Text.str();
83}
84
85std::optionalstd::string
87 if (const auto *Op = dyn_cast(&E))
88 if (Op->getOpcode() == UO_AddrOf) {
89
90 StringRef Text =
91 getText(*Op->getSubExpr()->IgnoreParenImpCasts(), Context);
92 if (Text.empty())
93 return std::nullopt;
94 return Text.str();
95 }
96
98 if (Text.empty())
99 return std::nullopt;
100
102 return ("*(" + Text + ")").str();
103 return ("*" + Text).str();
104}
105
109 return std::string("this");
110 if (const auto *Op = dyn_cast(&E))
111 if (Op->getOpcode() == UO_Deref) {
112
113 StringRef Text =
114 getText(*Op->getSubExpr()->IgnoreParenImpCasts(), Context);
115 if (Text.empty())
116 return std::nullopt;
117 return Text.str();
118 }
119
121 if (Text.empty())
122 return std::nullopt;
124 return ("&(" + Text + ")").str();
125 }
126 return ("&" + Text).str();
127}
128
129
130
131static std::optionalstd::string
133 if (const auto *Op = llvm::dyn_cast(&E))
134 if (Op->getOpcode() == UO_Deref) {
135
137 StringRef DerefText = getText(*SubExpr, Context);
138 if (DerefText.empty())
139 return std::nullopt;
141 return ("(" + DerefText + ")->").str();
142 return (DerefText + "->").str();
143 }
144
145
147 if (Text.empty())
148 return std::nullopt;
150 return ("(" + Text + ").").str();
151 }
152 return (Text + ".").str();
153}
154
155
156
157static std::optionalstd::string
159 if (const auto *Op = llvm::dyn_cast(&E))
160 if (Op->getOpcode() == UO_AddrOf) {
161
163 StringRef DerefText = getText(*SubExpr, Context);
164 if (DerefText.empty())
165 return std::nullopt;
167 return ("(" + DerefText + ").").str();
168 return (DerefText + ".").str();
169 }
170
171
173 if (Text.empty())
174 return std::nullopt;
176 return ("(" + Text + ")->").str();
177 return (Text + "->").str();
178}
179
183}
184
188}
189
190
191
194 if (const auto *OpCall = dyn_castclang::CXXOperatorCallExpr(&E)) {
195 if (OpCall->getOperator() == K && OpCall->getNumArgs() == 1)
196 return OpCall->getArg(0);
197 }
198 return nullptr;
199}
200
202 switch (C) {
203 case PLTClass::Value:
204 return false;
205 case PLTClass::Pointer:
207 }
208 llvm_unreachable("Unknown PLTClass enum");
209}
210
211
212
217
218
219 return std::string();
220
222
225
226
227
229 E = Obj;
231 }
232
234 if (treatLikePointer(Obj->getType(), Classification, Context))
236 };
237
239}
Defines the clang::ASTContext interface.
Defines the clang::Expr interface and subclasses for C++ expressions.
static bool treatLikePointer(QualType Ty, PLTClass C, ASTContext &Context)
static std::optional< std::string > buildAccessForPointer(const Expr &E, const ASTContext &Context)
static std::optional< std::string > buildAccessForValue(const Expr &E, const ASTContext &Context)
static const Expr * maybeGetOperatorObjectArg(const Expr &E, OverloadedOperatorKind K)
This file collects facilities for generating source code strings.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
This represents one expression.
bool isImplicitCXXThis() const
Whether this expression is an implicit reference to 'this' in C++.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
A (possibly-)qualified type.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
bool isAnyPointerType() const
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicFunction< internal::Matcher< NamedDecl >, StringRef, internal::hasAnyNameFunc > hasAnyName
Matches NamedDecl nodes that have any of the specified names.
const AstTypeMatcher< RecordType > recordType
Matches record types (e.g.
const internal::VariadicDynCastAllOfMatcher< Decl, CXXRecordDecl > cxxRecordDecl
Matches C++ class declarations.
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.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.