16#include "llvm/ADT/Twine.h"
20using namespace tooling;
24 if (
const auto *CE = dyn_cast<CXXConstructExpr>(
Expr)) {
25 if (CE->getNumArgs() > 0 &&
36 if (isa<UnaryOperator>(
Expr) || isa<BinaryOperator>(
Expr) ||
37 isa<AbstractConditionalOperator>(
Expr))
45 if (
const auto *Op = dyn_cast<CXXOperatorCallExpr>(
Expr))
46 return Op->getOperator() != OO_Call && Op->getOperator() != OO_Subscript &&
47 Op->getOperator() != OO_Arrow;
54 if (isa<BinaryOperator>(
Expr) || isa<AbstractConditionalOperator>(
Expr))
57 if (
const auto *Op = dyn_cast<CXXOperatorCallExpr>(
Expr))
58 return Op->getNumArgs() == 2 && Op->getOperator() != OO_PlusPlus &&
59 Op->getOperator() != OO_MinusMinus && Op->getOperator() != OO_Call &&
60 Op->getOperator() != OO_Subscript;
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;
81 return (
"(" +
Text +
")").str();
85std::optional<std::string>
87 if (
const auto *Op = dyn_cast<UnaryOperator>(&
E))
88 if (Op->getOpcode() == UO_AddrOf) {
91 getText(*Op->getSubExpr()->IgnoreParenImpCasts(), Context);
102 return (
"*(" +
Text +
")").str();
103 return (
"*" +
Text).str();
109 return std::string(
"this");
110 if (
const auto *Op = dyn_cast<UnaryOperator>(&
E))
111 if (Op->getOpcode() == UO_Deref) {
114 getText(*Op->getSubExpr()->IgnoreParenImpCasts(), Context);
124 return (
"&(" +
Text +
")").str();
126 return (
"&" +
Text).str();
131static std::optional<std::string>
133 if (
const auto *Op = llvm::dyn_cast<UnaryOperator>(&
E))
134 if (Op->getOpcode() == UO_Deref) {
137 StringRef DerefText =
getText(*SubExpr, Context);
138 if (DerefText.empty())
141 return (
"(" + DerefText +
")->").str();
142 return (DerefText +
"->").str();
150 return (
"(" +
Text +
").").str();
152 return (
Text +
".").str();
157static std::optional<std::string>
159 if (
const auto *Op = llvm::dyn_cast<UnaryOperator>(&
E))
160 if (Op->getOpcode() == UO_AddrOf) {
163 StringRef DerefText =
getText(*SubExpr, Context);
164 if (DerefText.empty())
167 return (
"(" + DerefText +
").").str();
168 return (DerefText +
".").str();
176 return (
"(" +
Text +
")->").str();
177 return (
Text +
"->").str();
194 if (
const auto *OpCall = dyn_cast<clang::CXXOperatorCallExpr>(&
E)) {
195 if (OpCall->getOperator() == K && OpCall->getNumArgs() == 1)
196 return OpCall->getArg(0);
203 case PLTClass::Value:
205 case PLTClass::Pointer:
208 llvm_unreachable(
"Unknown PLTClass enum");
219 return std::string();
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.