23 const char *NameToMatch) {
29 if (MethodName == NameToMatch && MD->getAccess() ==
AS_public)
39std::optional<const clang::CXXRecordDecl *>
43 const Type *
T =
Base->getType().getTypePtrOrNull();
53 return hasPublicMethodInBaseClass(R, NameToMatch) ? R :
nullptr;
64 bool hasRef = hasPublicMethodInBaseClass(R,
"ref");
65 bool hasDeref = hasPublicMethodInBaseClass(R,
"deref");
66 if (hasRef && hasDeref)
72 bool AnyInconclusiveBase =
false;
73 const auto hasPublicRefInBase =
77 AnyInconclusiveBase =
true;
80 return (*hasRefInBase) !=
nullptr;
83 hasRef = hasRef || R->
lookupInBases(hasPublicRefInBase, Paths,
85 if (AnyInconclusiveBase)
89 const auto hasPublicDerefInBase =
92 if (!hasDerefInBase) {
93 AnyInconclusiveBase =
true;
96 return (*hasDerefInBase) !=
nullptr;
98 hasDeref = hasDeref || R->
lookupInBases(hasPublicDerefInBase, Paths,
100 if (AnyInconclusiveBase)
103 return hasRef && hasDeref;
107 return Name ==
"Ref" || Name ==
"RefAllowingPartiallyDestroyed" ||
108 Name ==
"RefPtr" || Name ==
"RefPtrAllowingPartiallyDestroyed";
115 return isRefType(FunctionName) || FunctionName ==
"makeRef" ||
116 FunctionName ==
"makeRefPtr" || FunctionName ==
"UniqueRef" ||
117 FunctionName ==
"makeUniqueRef" ||
118 FunctionName ==
"makeUniqueRefWithoutFastMallocCheck"
120 || FunctionName ==
"String" || FunctionName ==
"AtomString" ||
121 FunctionName ==
"UniqueString"
123 || FunctionName ==
"Identifier";
129 while (!
type.isNull()) {
131 type = elaboratedT->desugar();
135 if (
auto *
decl = specialT->getTemplateName().getAsTemplateDecl()) {
136 auto name =
decl->getNameAsString();
156 return (*IsRefCountable);
175 if (isa<CXXMethodDecl>(M)) {
180 if ((
isRefType(className) && (method ==
"get" || method ==
"ptr")) ||
181 ((className ==
"String" || className ==
"AtomString" ||
182 className ==
"AtomStringImpl" || className ==
"UniqueString" ||
183 className ==
"UniqueStringImpl" || className ==
"Identifier") &&
190 if (
auto *maybeRefToRawOperator = dyn_cast<CXXConversionDecl>(M)) {
191 if (
auto *targetConversionType =
192 maybeRefToRawOperator->getConversionType().getTypePtrOrNull()) {
218 if (FunctionName ==
"getPtr" || FunctionName ==
"WeakPtr" ||
219 FunctionName ==
"dynamicDowncast" || FunctionName ==
"downcast" ||
220 FunctionName ==
"checkedDowncast" ||
221 FunctionName ==
"uncheckedDowncast" || FunctionName ==
"bitwise_cast")
230 if (
auto *MethodDecl = dyn_cast<CXXMethodDecl>(F)) {
231 if (!MethodDecl->isStatic())
235 std::string SingletonStr =
"singleton";
236 auto index = Name.find(SingletonStr);
237 return index != std::string::npos &&
238 index == Name.size() - SingletonStr.size();
247 bool VisitChildren(
const Stmt *S) {
248 for (
const Stmt *Child : S->children()) {
249 if (Child && !
Visit(Child))
256 template <
typename CheckFunction>
257 bool WithCachedResult(
const Stmt *S, CheckFunction
Function) {
261 auto [It, IsNew] =
Cache.insert(std::make_pair(S,
false));
270 using CacheTy = TrivialFunctionAnalysis::CacheTy;
275 auto CacheIt =
Cache.find(
D);
276 if (CacheIt !=
Cache.end())
277 return CacheIt->second;
280 auto [RecursiveIt, IsNew] = RecursiveFn.insert(std::make_pair(
D,
true));
282 return RecursiveIt->second;
285 if (
auto *CtorDecl = dyn_cast<CXXConstructorDecl>(
D)) {
286 for (
auto *CtorInit : CtorDecl->inits()) {
287 if (!
Visit(CtorInit->getInit()))
299 for (
auto &It : RecursiveFn)
302 RecursiveIt = RecursiveFn.find(
D);
303 assert(RecursiveIt != RecursiveFn.end());
304 Result = RecursiveIt->second;
305 RecursiveFn.erase(RecursiveIt);
320 return WithCachedResult(CS, [&]() {
return VisitChildren(CS); });
333 return WithCachedResult(IS, [&]() {
return VisitChildren(IS); });
336 return WithCachedResult(FS, [&]() {
return VisitChildren(FS); });
339 return WithCachedResult(FS, [&]() {
return VisitChildren(FS); });
342 return WithCachedResult(WS, [&]() {
return VisitChildren(WS); });
367 return VisitChildren(CAO);
371 return VisitChildren(ASE);
376 return VisitChildren(CO);
395 if (Callee->isInStdNamespace() &&
396 (Name ==
"addressof" || Name ==
"forward" || Name ==
"move"))
399 if (Name ==
"WTFCrashWithInfo" || Name ==
"WTFBreakpointTrap" ||
400 Name ==
"WTFCrashWithSecurityImplication" || Name ==
"WTFCrash" ||
401 Name ==
"WTFReportAssertionFailure" || Name ==
"isMainThread" ||
402 Name ==
"isMainThreadOrGCThread" || Name ==
"isMainRunLoop" ||
403 Name ==
"isWebThread" || Name ==
"isUIThread" ||
404 Name ==
"mayBeGCThread" || Name ==
"compilerFenceForCrash" ||
405 Name ==
"bitwise_cast" || Name.find(
"__builtin") == 0)
418 return VisitChildren(
E);
439 if (IsGetterOfRefCounted && *IsGetterOfRefCounted)
457 if (
auto *
Expr =
E->getExpr()) {
466 if (Arg && !
Visit(Arg))
474 if (Arg && !
Visit(Arg))
498 if (!TrivialFunctionAnalysis::isTrivialImpl(Temp->getDestructor(),
Cache))
512 if (Child && !
Visit(Child))
556bool TrivialFunctionAnalysis::isTrivialImpl(
557 const Decl *
D, TrivialFunctionAnalysis::CacheTy &
Cache) {
559 return V.IsFunctionTrivial(
D);
562bool TrivialFunctionAnalysis::isTrivialImpl(
563 const Stmt *S, TrivialFunctionAnalysis::CacheTy &
Cache) {
571 assert(
Cache.contains(S) &&
"Top-level statement not properly cached!");
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
A builtin binary operation expression such as "x + y" or "x <= y".
BreakStmt - This represents a break.
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Represents a base class of a C++ class.
Represents binding an expression to a temporary.
CXXTemporary * getTemporary()
const Expr * getSubExpr() const
A boolean literal, per ([C++ lex.bool] Boolean literals).
Represents a call to a C++ constructor.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
A default argument (C++ [dcl.fct.default]).
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Represents a call to a member function that may be written either with member call syntax (e....
CXXMethodDecl * getMethodDecl() const
Retrieve the declaration of the called method.
Expr * getImplicitObjectArgument() const
Retrieve the implicit object argument for the member call.
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
The null pointer literal (C++11 [lex.nullptr])
A call to an overloaded operator written using operator syntax.
Represents a C++ struct/union/class.
method_range methods() const
CXXRecordDecl * getDefinition() const
const CXXRecordDecl * getTemplateInstantiationPattern() const
Retrieve the record declaration from which this record could be instantiated.
bool lookupInBases(BaseMatchesCallback BaseMatches, CXXBasePaths &Paths, bool LookupInDependent=false) const
Look for entities within the base classes of this C++ class, transitively searching all base class su...
bool hasDefinition() const
Represents the this expression in C++.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
CaseStmt - Represent a case statement.
CompoundAssignOperator - For compound assignments (e.g.
CompoundStmt - This represents a group of statements like { stmt stmt }.
ConditionalOperator - The ?: ternary operator.
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
ContinueStmt - This represents a continue.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
DoStmt - This represents a 'do/while' stmt.
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
ExplicitCastExpr - An explicit cast written in the source code.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
const Expr * getSubExpr() const
Represents a function declaration or definition.
QualType getReturnType() const
GotoStmt - This represents a direct goto.
IfStmt - This represents an if/then/else.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Describes an C or C++ initializer list.
ArrayRef< Expr * > inits()
LabelStmt - Represents a label, which has a substatement.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ParenExpr - This represents a parenthesized expression, e.g.
const Expr * getSubExpr() const
[C99 6.4.2.2] - A predefined identifier such as func.
A (possibly-)qualified type.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Represents a C++11 static_assert declaration.
RetTy Visit(PTR(Stmt) S, ParamTys... P)
Stmt - This represents one statement.
StringLiteral - This represents a string literal expression, e.g.
Represents a reference to a non-type template parameter that has been substituted with a template arg...
SwitchStmt - This represents a 'switch' stmt.
Represents a type template specialization; the template must be a class template, a type alias templa...
bool VisitMemberExpr(const MemberExpr *ME)
TrivialFunctionAnalysisVisitor(CacheTy &Cache)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitStaticAssertDecl(const StaticAssertDecl *SAD)
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE)
bool VisitBreakStmt(const BreakStmt *)
bool VisitCXXThisExpr(const CXXThisExpr *CTE)
bool IsFunctionTrivial(const Decl *D)
bool VisitLabelStmt(const LabelStmt *)
bool VisitUnaryOperator(const UnaryOperator *UO)
bool VisitPredefinedExpr(const PredefinedExpr *E)
bool VisitContinueStmt(const ContinueStmt *)
bool VisitSwitchStmt(const SwitchStmt *SS)
bool VisitCompoundAssignOperator(const CompoundAssignOperator *CAO)
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
bool VisitFixedPointLiteral(const FixedPointLiteral *E)
bool VisitDeclRefExpr(const DeclRefExpr *DRE)
bool VisitDoStmt(const DoStmt *DS)
bool VisitIfStmt(const IfStmt *IS)
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *VMT)
bool VisitFloatingLiteral(const FloatingLiteral *E)
TrivialFunctionAnalysis::CacheTy CacheTy
bool VisitCaseStmt(const CaseStmt *CS)
bool VisitDeclStmt(const DeclStmt *DS)
bool VisitConditionalOperator(const ConditionalOperator *CO)
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitCompoundStmt(const CompoundStmt *CS)
bool VisitConstantExpr(const ConstantExpr *CE)
bool VisitImplicitCastExpr(const ImplicitCastExpr *ICE)
bool VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE)
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitExprWithCleanups(const ExprWithCleanups *EWC)
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *ASE)
bool VisitCallExpr(const CallExpr *CE)
bool VisitForStmt(const ForStmt *FS)
bool VisitCXXNewExpr(const CXXNewExpr *NE)
bool VisitBinaryOperator(const BinaryOperator *BO)
bool checkArguments(const CallExpr *CE)
bool VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE)
bool VisitCXXForRangeStmt(const CXXForRangeStmt *FS)
bool VisitGotoStmt(const GotoStmt *)
bool VisitWhileStmt(const WhileStmt *WS)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool VisitInitListExpr(const InitListExpr *ILE)
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool VisitAtomicExpr(const AtomicExpr *E)
bool VisitStmt(const Stmt *S)
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
bool VisitExplicitCastExpr(const ExplicitCastExpr *ECE)
bool VisitParenExpr(const ParenExpr *PE)
bool VisitDefaultStmt(const DefaultStmt *DS)
bool VisitCXXConstructExpr(const CXXConstructExpr *CE)
bool VisitReturnStmt(const ReturnStmt *RS)
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isPointerType() const
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
WhileStmt - This represents a 'while' stmt.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
std::optional< bool > isGetterOfRefCounted(const CXXMethodDecl *M)
std::optional< bool > isUncountedPtr(const Type *T)
bool isPtrConversion(const FunctionDecl *F)
bool isCtorOfRefCounted(const clang::FunctionDecl *F)
std::optional< bool > isUncounted(const CXXRecordDecl *Class)
std::optional< const clang::CXXRecordDecl * > hasPublicMethodInBase(const CXXBaseSpecifier *Base, const char *NameToMatch)
std::optional< bool > isRefCountable(const CXXRecordDecl *R)
@ Result
The result type of a method or function.
bool isSingleton(const FunctionDecl *F)
bool isRefCounted(const CXXRecordDecl *R)
bool isReturnValueRefCounted(const clang::FunctionDecl *F)
bool isRefType(const std::string &Name)
const FunctionProtoType * T
std::string safeGetName(const T *ASTNode)
@ Class
The "class" keyword introduces the elaborated-type-specifier.