20#include "llvm/ADT/StringSet.h"
27bool hasPublicMethodInBaseClass(
const CXXRecordDecl *R, StringRef NameToMatch) {
29 assert(
R->hasDefinition());
33 if (MethodName == NameToMatch && MD->getAccess() ==
AS_public)
37 for (
const Decl *D :
R->decls()) {
38 const auto *Shadow = dyn_cast<UsingShadowDecl>(D);
39 if (!Shadow || Shadow->getAccess() !=
AS_public)
41 const auto *MD = dyn_cast<CXXMethodDecl>(Shadow->getTargetDecl());
52std::optional<const clang::CXXRecordDecl *>
56 const Type *
T =
Base->getType().getTypePtrOrNull();
62 auto CT =
Base->getType().getCanonicalType();
63 if (
auto *TST = dyn_cast<TemplateSpecializationType>(CT)) {
64 auto TmplName = TST->getTemplateName();
65 if (!TmplName.isNull()) {
66 if (
auto *TD = TmplName.getAsTemplateDecl())
67 R = dyn_cast_or_null<CXXRecordDecl>(TD->getTemplatedDecl());
73 if (!R->hasDefinition())
76 return hasPublicMethodInBaseClass(R, NameToMatch) ? R :
nullptr;
80 StringRef MethodName) {
83 R = R->getDefinition();
87 if (hasPublicMethodInBaseClass(R, MethodName))
93 bool AnyInconclusiveBase =
false;
97 if (!HasMethodInBase) {
98 AnyInconclusiveBase =
true;
101 return (*HasMethodInBase) !=
nullptr;
104 bool Found = R->lookupInBases(hasPublicMethod, Paths,
106 if (AnyInconclusiveBase)
113 StringRef IncMethodName,
114 StringRef DecMethodName) {
125 return *HasInc && *HasDec;
134 "decrementCheckedPtrCount");
149 return isBorrow(
T->getAsCXXRecordDecl());
153 while (!
T.isNull()) {
164 dyn_cast_or_null<ClassTemplateSpecializationDecl>(
165 T->getAsCXXRecordDecl());
171 return Args[0].getAsType();
175 if (!R || !R->hasDefinition())
178 for (
const ParmVarDecl *Param : Ctor->parameters()) {
179 if (Param->hasAttr<LifetimeBoundAttr>() ||
180 Param->hasAttr<LifetimeCaptureByAttr>())
188 if (!R || !R->getIdentifier() || R->getName() !=
"view_interface")
190 const auto *NS = dyn_cast<NamespaceDecl>(R->getDeclContext());
191 return NS && NS->getIdentifier() && NS->getName() ==
"ranges" &&
192 NS->getParent()->isStdNamespace();
198 R = R->getDefinition();
213 if (R->hasAttr<PointerAttr>())
215 static const llvm::StringSet<> StdIterators{
216 "reverse_iterator",
"move_iterator",
"common_iterator",
217 "counted_iterator",
"basic_const_iterator"};
218 if (R->isInStdNamespace() && R->getIdentifier() &&
219 StdIterators.contains(R->getName()))
223 if (
const auto *Parent = dyn_cast<CXXRecordDecl>(R->getDeclContext()))
229 if (
T->isReferenceType())
233 auto *
Record =
T->getAsCXXRecordDecl();
240 return Name ==
"Ref" || Name ==
"RefAllowingPartiallyDestroyed" ||
241 Name ==
"RefPtr" || Name ==
"RefPtrAllowingPartiallyDestroyed";
245 return Name ==
"RetainPtr" || Name ==
"RetainPtrArc" ||
246 Name ==
"OSObjectPtr" || Name ==
"OSObjectPtrArc";
250 return Name ==
"CheckedPtr" || Name ==
"CheckedRef";
254 return Name ==
"unique_ptr" || Name ==
"UniqueRef" || Name ==
"LazyUniqueRef";
257bool isBorrow(
const std::string &Name) {
return Name ==
"Borrow"; }
265 return Name ==
"WeakPtr" || Name ==
"SingleThreadPackedWeakPtr" ||
266 Name ==
"SingleThreadWeakPtr" || Name ==
"ThreadSafeWeakPtr" ||
267 Name ==
"ThreadSafeWeakOrStrongPtr" || Name ==
"InlineWeakPtr";
273 Name ==
"WeakPtrFactoryWithBitField" || Name ==
"WeakPtrImplBase" ||
274 Name ==
"WeakPtrImplBaseSingleThread" ||
275 Name ==
"ThreadSafeWeakOrStrongPtr" ||
276 Name ==
"ThreadSafeWeakPtrControlBlock" ||
277 Name ==
"ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr";
281 if (
auto *Ctor = dyn_cast_or_null<CXXConstructorDecl>(F))
289 return isRefType(FunctionName) || FunctionName ==
"adoptRef" ||
290 FunctionName ==
"UniqueRef" || FunctionName ==
"makeUniqueRef" ||
291 FunctionName ==
"makeUniqueRefWithoutFastMallocCheck"
293 || FunctionName ==
"String" || FunctionName ==
"AtomString" ||
294 FunctionName ==
"UniqueString"
296 || FunctionName ==
"Identifier";
307 FunctionName ==
"adoptNSNullable" || FunctionName ==
"adoptCF" ||
308 FunctionName ==
"adoptCFNullable" || FunctionName ==
"retainPtr" ||
309 FunctionName ==
"adoptNSArc" || FunctionName ==
"adoptOSObject" ||
310 FunctionName ==
"adoptOSObjectArc";
324 if (!isa_and_nonnull<TranslationUnitDecl>(TUDeck))
327 return (NsName ==
"WTF" || NsName ==
"std") && FnName ==
"move";
330template <
typename Predicate>
333 while (!
type.isNull()) {
334 if (
auto *SpecialT =
type->getAs<TemplateSpecializationType>()) {
335 auto *
Decl = SpecialT->getTemplateName().getAsTemplateDecl();
336 return Decl && Pred(
Decl->getNameAsString());
337 }
else if (
auto *DTS =
type->getAs<DeducedTemplateSpecializationType>()) {
338 auto *
Decl = DTS->getTemplateName().getAsTemplateDecl();
339 return Decl && Pred(
Decl->getNameAsString());
340 }
else if (
auto *RD =
type->getAs<RecordType>()) {
341 auto *
Decl = RD->getDecl();
342 return Decl && Pred(
Decl->getNameAsString());
363 if (
auto *Subst = dyn_cast<SubstTemplateTypeParmType>(
T)) {
364 if (
auto *
Decl = Subst->getAssociatedDecl()) {
373 if (
auto *Subst = dyn_cast<SubstTemplateTypeParmType>(
T)) {
374 if (
auto *
Decl = Subst->getAssociatedDecl()) {
384 IsARCEnabled = TUD->
getLangOpts().ObjCAutoRefCount;
385 DefaultSynthProperties = TUD->
getLangOpts().ObjCDefaultSynthProperties;
390 if (!QT->isPointerType())
396 if (TD->
hasAttr<ObjCBridgeAttr>() || TD->
hasAttr<ObjCBridgeMutableAttr>()) {
405 for (
auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
406 if (Redecl->getAttr<ObjCBridgeAttr>() ||
407 Redecl->getAttr<ObjCBridgeMutableAttr>()) {
408 CFPointees.insert({RT, TD});
417 if (
auto *RT = dyn_cast_or_null<RecordType>(
419 return CFPointees.contains(RT);
420 return RecordlessTypes.contains(QT.
getTypePtr());
425 if (
auto *TD = dyn_cast<TypedefDecl>(TT->getDecl()))
433 auto *RD = dyn_cast<RecordType>(PointeeType);
436 return CFPointees.lookup(RD);
449 return (*IsRefCountable);
459 if (
T->isPointerType() ||
T->isReferenceType()) {
460 if (
auto *CXXRD =
T->getPointeeCXXRecordDecl())
467 if (
T->isPointerType() ||
T->isReferenceType()) {
468 if (
auto *CXXRD =
T->getPointeeCXXRecordDecl())
478 std::string className =
safeGetName(calleeMethodsClass);
483 (method ==
"get" || method ==
"ptr" || OpType == OO_Star))
487 (method ==
"get" || method ==
"ptr" || OpType == OO_Star)) ||
488 ((className ==
"String" || className ==
"AtomString" ||
489 className ==
"AtomStringImpl" || className ==
"UniqueString" ||
490 className ==
"UniqueStringImpl" || className ==
"Identifier") &&
500 if (
auto *maybeRefToRawOperator = dyn_cast<CXXConversionDecl>(M)) {
501 QualType QT = maybeRefToRawOperator->getConversionType();
503 return T && (
T->isPointerType() ||
T->isReferenceType());
508 if (
auto *maybeRefToRawOperator = dyn_cast<CXXConversionDecl>(M)) {
509 QualType QT = maybeRefToRawOperator->getConversionType();
511 return T && (
T->isPointerType() ||
T->isReferenceType());
516 if (
auto *maybeRefToRawOperator = dyn_cast<CXXConversionDecl>(M)) {
517 QualType QT = maybeRefToRawOperator->getConversionType();
519 return T && (
T->isPointerType() ||
T->isReferenceType() ||
520 T->isObjCObjectPointerType());
531 if (method ==
"get" || method ==
"ptr")
533 if (
auto *conversion = dyn_cast<CXXConversionDecl>(M)) {
534 const Type *
T = conversion->getConversionType().getTypePtrOrNull();
535 return T && (
T->isPointerType() ||
T->isReferenceType());
542 if (
auto *TmplR = R->getTemplateInstantiationPattern()) {
552 if (
auto *TmplR = R->getTemplateInstantiationPattern()) {
561 if (
auto *TmplR = R->getTemplateInstantiationPattern())
568 if (
auto *TmplR = R->getTemplateInstantiationPattern())
575 if (
auto *TmplR = R->getTemplateInstantiationPattern())
587 if (Annotation ==
"webkit.pointerconversion")
589 if (Annotation ==
"webkit.nodelete")
601 auto *
Type = RetType.getTypePtrOrNull();
602 if (
auto *MacroQualified = dyn_cast_or_null<MacroQualifiedType>(
Type))
603 Type = MacroQualified->desugar().getTypePtrOrNull();
604 auto *
Attr = dyn_cast_or_null<AttributedType>(
Type);
607 auto *AnnotateType = dyn_cast_or_null<AnnotateTypeAttr>(
Attr->getAttr());
610 return annotationType(AnnotateType->getAnnotation()) == TargetAnnotation;
620 if (FunctionName ==
"getPtr" || FunctionName ==
"WeakPtr" ||
621 FunctionName ==
"dynamicDowncast" || FunctionName ==
"downcast" ||
622 FunctionName ==
"checkedDowncast" || FunctionName ==
"bit_cast" ||
623 FunctionName ==
"uncheckedDowncast" || FunctionName ==
"bitwise_cast" ||
624 FunctionName ==
"bridge_cast" || FunctionName ==
"bridge_id_cast" ||
625 FunctionName ==
"dynamic_cf_cast" || FunctionName ==
"checked_cf_cast" ||
626 FunctionName ==
"dynamic_objc_cast" ||
627 FunctionName ==
"checked_objc_cast")
644 const auto *MD = dyn_cast<CXXMethodDecl>(F);
645 if (!MD || !MD->isVirtual())
648 auto Overriders = llvm::to_vector(MD->overridden_methods());
649 while (!Overriders.empty()) {
650 const auto *Fn = Overriders.pop_back_val();
651 llvm::append_range(Overriders, Fn->overridden_methods());
663 return Name.starts_with(
"__builtin") || Name ==
"__libcpp_verbose_abort" ||
664 Name.starts_with(
"os_log") || Name.starts_with(
"_os_log");
670 if (
auto *MethodDecl = dyn_cast<CXXMethodDecl>(F)) {
671 if (!MethodDecl->isStatic())
675 StringRef Name = NameStr;
676 return Name ==
"singleton" || Name.ends_with(
"Singleton");
686 bool VisitChildren(
const Stmt *S) {
688 if (Child && !
Visit(Child))
695 bool canUseCachedResult(
bool CachedResult)
const {
696 return CachedResult || !CallStack;
699 template <
typename StmtOrDecl,
typename CheckFunction>
700 bool WithCachedResult(
const StmtOrDecl *S, CheckFunction
Function) {
701 auto CacheIt = Cache.find(S);
702 if (CacheIt != Cache.end() && canUseCachedResult(CacheIt->second))
703 return CacheIt->second;
706 auto [RecursiveIt, IsNew] = RecursiveFn.insert(std::make_pair(S,
true));
708 return RecursiveIt->second;
713 for (
auto &It : RecursiveFn)
716 RecursiveIt = RecursiveFn.find(S);
717 assert(RecursiveIt != RecursiveFn.end());
718 Result = RecursiveIt->second;
719 RecursiveFn.erase(RecursiveIt);
725 static bool isTrivialType(
QualType Ty) {
737 bool CanTriviallyDestruct(
QualType Ty) {
749 if (isTrivialType(Ty))
754 if (R->hasDefinition() && R->hasTrivialDestructor())
757 if (
auto *Dtor = R->getDestructor()) {
767 if (
const auto *Dtor = R->getDestructor())
778 return CanTriviallyDestruct(AT->getElementType());
783 bool CanTriviallyConstruct(
QualType Ty) {
787 if (isTrivialType(Ty))
792 if (R->hasDefinition() && R->hasTrivialDefaultConstructor())
794 for (
auto *Ctor : R->ctors()) {
803 template <
typename CacheTy,
typename IsTrivialTypeFn>
806 IsTrivialTypeFn IsTrivialType) {
807 auto CacheIt = Cache.find(Cls);
808 if (CacheIt != Cache.end() && !OffendingField)
809 return CacheIt->second;
814 if (!IsTrivialType(F->getType())) {
823 if (HasNonTrivialField(Cls))
836 auto *R =
T->getAsCXXRecordDecl();
837 return R && HasNonTrivialField(R);
848 using CacheTy = TrivialFunctionAnalysis::CacheTy;
852 : Cache(Cache), OffendingStmt(Reason ? &Reason->OffendingStmt :
nullptr),
853 CallStack(Reason ? &Reason->CallStack :
nullptr) {}
863 if (!
Result && OffendingStmt && !*OffendingStmt &&
873 const auto *FnDecl = dyn_cast<FunctionDecl>(D);
881 CallStack->truncate(ActiveDepth);
882 size_t Index = ActiveDepth++;
883 CallStack->push_back({FnDecl,
nullptr});
887 const Stmt *CalleeOffendingStmt =
nullptr;
888 const Stmt **SavedOffendingStmt =
889 std::exchange(OffendingStmt, &CalleeOffendingStmt);
891 OffendingStmt = SavedOffendingStmt;
897 CallStack->truncate(Index);
899 (*CallStack)[Index].OffendingStmt = CalleeOffendingStmt;
904 return WithCachedResult(D, [&]() {
905 auto *FnDecl = dyn_cast<FunctionDecl>(D);
906 auto *MethodDecl = dyn_cast<CXXMethodDecl>(D);
907 auto *CtorDecl = dyn_cast<CXXConstructorDecl>(D);
908 auto *DtorDecl = dyn_cast<CXXDestructorDecl>(D);
913 if (MethodDecl && MethodDecl->isVirtual())
915 for (
auto *Param : FnDecl->parameters()) {
921 for (
auto *CtorInit : CtorDecl->inits()) {
922 if (!
Visit(CtorInit->getInit()))
931 if (MethodDecl && !MethodDecl->isUserProvided()) {
934 if ((CtorDecl->isDefaultConstructor() &&
936 (CtorDecl->isCopyConstructor() &&
938 (CtorDecl->isMoveConstructor() &&
942 if (DtorDecl && DtorDecl->getParent()->hasTrivialDestructor())
953 return WithCachedResult(
954 VD, [&] {
return CanTriviallyDestruct(VD->
getType()); });
958 const FieldDecl *OffendingField =
nullptr;
960 Cls, &OffendingField, FieldCtorCache,
961 [&](
const QualType Ty) {
return CanTriviallyConstruct(Ty); });
962 return OffendingField;
966 const FieldDecl *OffendingField =
nullptr;
968 Cls, &OffendingField, FieldDtorCache,
969 [&](
const QualType Ty) {
return CanTriviallyDestruct(Ty); });
970 return OffendingField;
974 auto CacheIt = Cache.find(S);
975 if (CacheIt != Cache.end() && canUseCachedResult(CacheIt->second))
976 return CacheIt->second;
996 return WithCachedResult(CS, [&]() {
return VisitChildren(CS); });
1000 return WithCachedResult(CBS, [&]() {
return VisitChildren(CBS); });
1016 if (
auto *VD = dyn_cast<VarDecl>(
Decl)) {
1021 return VisitChildren(DS);
1025 return WithCachedResult(IS, [&]() {
return VisitChildren(IS); });
1028 return WithCachedResult(FS, [&]() {
return VisitChildren(FS); });
1031 return WithCachedResult(FS, [&]() {
return VisitChildren(FS); });
1034 return WithCachedResult(WS, [&]() {
return VisitChildren(WS); });
1059 return VisitChildren(CAO);
1063 return VisitChildren(ASE);
1068 return VisitChildren(CO);
1091 if (Callee->isInStdNamespace() &&
1092 (Name ==
"addressof" || Name ==
"forward" || Name ==
"move"))
1095 if (Name ==
"WTFCrashWithInfo" || Name ==
"WTFBreakpointTrap" ||
1096 Name ==
"WTFReportBacktrace" ||
1097 Name ==
"WTFCrashWithSecurityImplication" || Name ==
"WTFCrash" ||
1098 Name ==
"WTFReportAssertionFailure" || Name ==
"isMainThread" ||
1099 Name ==
"isMainThreadOrGCThread" || Name ==
"isMainRunLoop" ||
1100 Name ==
"isWebThread" || Name ==
"isUIThread" ||
1101 Name ==
"mayBeGCThread" || Name ==
"compilerFenceForCrash" ||
1119 return VisitChildren(E);
1149 if (Name ==
"ref" || Name ==
"incrementCheckedPtrCount")
1153 if (IsGetterOfRefCounted && *IsGetterOfRefCounted)
1172 return SemanticExpr &&
Visit(SemanticExpr);
1189 if (Arg && !
Visit(Arg))
1218 if (
auto *
Init = dyn_cast<InitListExpr>(Arg)) {
1219 if (
Init->getNumInits() == 1)
1220 Arg =
Init->getInit(0);
1222 if (
auto *BTE = dyn_cast<CXXBindTemporaryExpr>(Arg)) {
1228 BTE->getType().getCanonicalType().getUnqualifiedType())
1229 return Visit(BTE->getSubExpr());
1236 auto *InnerArg = CE->
getArg(0);
1237 if (
auto *MTE = dyn_cast<MaterializeTemporaryExpr>(InnerArg)) {
1238 auto *InnerExpr = MTE->getSubExpr();
1239 if (
auto *BTE = dyn_cast<CXXBindTemporaryExpr>(InnerExpr))
1240 InnerExpr = BTE->getSubExpr();
1241 auto InnerQT = InnerExpr->getType();
1242 if (
auto *InnerDecl = InnerQT->getAsCXXRecordDecl()) {
1246 return Visit(InnerExpr);
1252 if (Arg && !
Visit(Arg))
1275 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(VMT->
getSubExpr());
1276 ICE && ICE->getCastKind() == CK_NoOp &&
1277 ICE->getType().isConstQualified()) {
1278 if (
auto *BTE = dyn_cast<CXXBindTemporaryExpr>(ICE->getSubExpr());
1280 return Visit(BTE->getSubExpr());
1291 if (!E || Depth > 4)
1295 if (
auto *EWC = dyn_cast<ExprWithCleanups>(E))
1296 E = EWC->getSubExpr();
1297 else if (
auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1298 E = MTE->getSubExpr();
1299 else if (
auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
1300 E = BTE->getSubExpr();
1304 if (
auto *CE = dyn_cast<CXXConstructExpr>(E)) {
1305 auto *Ctor = CE->getConstructor();
1308 if (Ctor->isDefaultConstructor())
1310 if (CE->getNumArgs() != 1)
1312 auto *Arg = CE->getArg(0)->IgnoreParenImpCasts();
1313 auto ArgType = Arg->getType();
1316 if (
auto *TD =
ArgType->getAsTagDecl();
1317 TD &&
safeGetName(TD) ==
"HashTableEmptyValueType")
1319 if (Ctor->isCopyOrMoveConstructor())
1323 if (
auto *CE = dyn_cast<CallExpr>(E)) {
1324 auto *Callee = CE->getDirectCallee();
1327 if (
auto *MD = dyn_cast<CXXMethodDecl>(Callee); MD && MD->isVirtual())
1329 auto *Body = dyn_cast_or_null<CompoundStmt>(Callee->getBody());
1330 if (!Body || Body->size() != 1)
1332 auto *RS = dyn_cast<ReturnStmt>(Body->body_front());
1366 for (
const Expr *Child : ILE->
inits()) {
1367 if (Child && !
Visit(Child))
1379 if (!CanTriviallyDestruct(SubExpr->getType()))
1381 return Visit(SubExpr);
1429 CacheTy FieldCtorCache;
1430 CacheTy FieldDtorCache;
1431 CacheTy RecursiveFn;
1432 const Stmt **OffendingStmt;
1434 unsigned ActiveDepth = 0;
1437bool TrivialFunctionAnalysis::isTrivialImpl(
1438 const Decl *D, TrivialFunctionAnalysis::CacheTy &
Cache) {
1440 return V.IsFunctionTrivial(D);
1443bool TrivialFunctionAnalysis::isTrivialImpl(
1444 const Stmt *S, TrivialFunctionAnalysis::CacheTy &
Cache) {
1446 return V.IsStatementTrivial(S);
1453 [[maybe_unused]]
bool Trivial =
V.IsStatementTrivial(S);
1454 assert(!Trivial &&
"computeReason called on a trivial statement");
1458bool TrivialFunctionAnalysis::hasTrivialDtorImpl(
const VarDecl *VD,
1461 return V.HasTrivialDestructor(VD);
1465TrivialFunctionAnalysis::fieldWithNonTrivialCtorImpl(
const CXXRecordDecl *RD,
1468 return V.FieldWithNonTrivialCtor(RD);
1472TrivialFunctionAnalysis::fieldWithNonTrivialDtorImpl(
const CXXRecordDecl *RD,
1475 return V.FieldWithNonTrivialDtor(RD);
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
llvm::MachO::Record Record
TypePropertyCache< Private > Cache
QualType getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const
Return the unique reference to the type for the specified typedef-name decl.
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Represents a loop initializing the elements of an array.
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Attr - This represents one attribute.
Represents an attribute applied to a statement.
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...
void setOrigin(const CXXRecordDecl *Rec)
Represents a base class of a C++ class.
QualType getType() const
Retrieves the type of the base 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.
Expr * getArg(unsigned Arg)
Return the specified argument.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Expr * getExpr()
Get the initialization expression that will be used.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Represents a call to an inherited base class constructor from an inheriting constructor.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
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.
QualType getObjectType() const
Retrieve the type of the object argument.
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.
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
bool hasTrivialMoveConstructor() const
Determine whether this class has a trivial move constructor (C++11 [class.copy]p12)
bool hasTrivialCopyConstructor() const
Determine whether this class has a trivial copy constructor (C++ [class.copy]p6, C++11 [class....
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
A rewritten comparison expression that was originally written using operator syntax.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
An expression "T()" which creates an rvalue of a non-class type T.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
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 ?
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.
Represents the body of a coroutine.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
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.
ASTContext & getASTContext() const LLVM_READONLY
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
bool isIdentifier() const
Predicate functions for querying what type of name this is.
DoStmt - This represents a 'do/while' stmt.
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.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Represents a member of a struct/union/class.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
const Expr * getSubExpr() const
Represents a function declaration or definition.
QualType getReturnType() const
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
This represents a GCC inline-assembly statement extension.
std::string getAsmString() 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 ...
Represents an implicitly-generated value initialization of an object of a given type.
Describes an C or C++ initializer list.
ArrayRef< Expr * > inits() const
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.
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
ParenExpr - This represents a parenthesized expression, e.g.
const Expr * getSubExpr() const
Represents a parameter to a function.
[C99 6.4.2.2] - A predefined identifier such as func.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
const Type * getTypePtrOrNull() const
const TypedefDecl * getCanonicalDecl(QualType)
bool isUnretained(const QualType, bool ignoreARC=false)
void visitTranslationUnitDecl(const TranslationUnitDecl *)
void visitTypedef(const TypedefDecl *)
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
bool isValid() const
Return true if this is a valid SourceLocation object.
Represents a C++11 static_assert declaration.
RetTy Visit(PTR(Stmt) S, ParamTys... P)
Stmt - This represents one statement.
SourceLocation getBeginLoc() const LLVM_READONLY
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.
@ Type
The template argument is a type.
The top declaration context.
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
bool Visit(const Stmt *S)
bool VisitMemberExpr(const MemberExpr *ME)
bool VisitStringLiteral(const StringLiteral *E)
bool HasTrivialDestructor(const VarDecl *VD)
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 IsStatementTrivial(const Stmt *S)
TrivialFunctionAnalysisVisitor(CacheTy &Cache, NonTrivialityReason *Reason=nullptr)
bool VisitUnaryOperator(const UnaryOperator *UO)
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *AILE)
bool VisitPredefinedExpr(const PredefinedExpr *E)
bool VisitContinueStmt(const ContinueStmt *)
bool VisitSwitchStmt(const SwitchStmt *SS)
bool VisitGCCAsmStmt(const GCCAsmStmt *AS)
bool VisitCompoundAssignOperator(const CompoundAssignOperator *CAO)
const FieldDecl * FieldWithNonTrivialDtor(const CXXRecordDecl *Cls)
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
bool VisitFixedPointLiteral(const FixedPointLiteral *E)
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *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 VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
bool IsFunctionTrivialImpl(const Decl *D)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *Op)
bool visitReturnValueElidingTemp(const Expr *Arg)
bool VisitFloatingLiteral(const FloatingLiteral *E)
TrivialFunctionAnalysis::CacheTy CacheTy
bool VisitCaseStmt(const CaseStmt *CS)
bool VisitDeclStmt(const DeclStmt *DS)
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *ILE)
bool VisitConditionalOperator(const ConditionalOperator *CO)
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitCompoundStmt(const CompoundStmt *CS)
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *IVIE)
bool VisitConstantExpr(const ConstantExpr *CE)
bool VisitImplicitCastExpr(const ImplicitCastExpr *ICE)
bool VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE)
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitOpaqueValueExpr(const OpaqueValueExpr *OVE)
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 VisitCoroutineBodyStmt(const CoroutineBodyStmt *CBS)
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 VisitAttributedStmt(const AttributedStmt *AS)
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool VisitAtomicExpr(const AtomicExpr *E)
bool VisitStmt(const Stmt *S)
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
const FieldDecl * FieldWithNonTrivialCtor(const CXXRecordDecl *Cls)
bool VisitExplicitCastExpr(const ExplicitCastExpr *ECE)
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *AIIE)
bool VisitParenExpr(const ParenExpr *PE)
bool VisitDefaultStmt(const DefaultStmt *DS)
bool VisitOffsetOfExpr(const OffsetOfExpr *OE)
bool VisitCXXConstructExpr(const CXXConstructExpr *CE)
bool isNullSmartPtr(const Expr *E, unsigned Depth=0)
bool VisitReturnStmt(const ReturnStmt *RS)
friend class TrivialFunctionAnalysisVisitor
static NonTrivialityReason computeReason(const Stmt *S)
The base class of the type hierarchy.
bool isFundamentalType() const
Tests whether the type is categorized as a fundamental type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isPointerOrReferenceType() const
bool isObjCObjectPointerType() const
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
bool isRecordType() const
Represents the declaration of a typedef-name via the 'typedef' type specifier.
QualType getUnderlyingType() const
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represents a variable declaration or definition.
WhileStmt - This represents a 'while' stmt.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
bool isCocoaObjectRef(QualType T)
bool isPointerLikeType(QualType QT)
Top level wrappers for InstallAPI frontend operations.
bool isCtorOfSafePtr(const clang::FunctionDecl *F)
bool isTrivialBuiltinFunction(const FunctionDecl *F)
bool isa(CodeGen::Address addr)
static bool isNoDeleteFunctionDecl(const FunctionDecl *F)
bool isPtrConversion(const FunctionDecl *F)
static bool isWeakPtrClass(const std::string &Name)
QualType pointeeType(QualType T)
std::optional< bool > isCheckedPtrCapable(const clang::CXXRecordDecl *R)
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
std::optional< bool > isUnchecked(const QualType T)
QualType borrowedType(QualType T)
bool isCtorOfRefCounted(const clang::FunctionDecl *F)
bool isRefOrCheckedPtrType(const clang::QualType T)
bool isView(const clang::QualType T)
static bool hasLifetimeBoundCtor(const clang::CXXRecordDecl *R)
bool isRetainPtrOrOSPtrType(const clang::QualType T)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isGetterOfUniquePtr(const CXXMethodDecl *M)
static bool isStdRangesViewInterface(const clang::CXXRecordDecl *R)
bool isCtorOfRetainPtrOrOSPtr(const clang::FunctionDecl *F)
bool isBorrow(const clang::CXXRecordDecl *R)
std::optional< bool > isBorrowable(const clang::CXXRecordDecl *R)
@ Result
The result type of a method or function.
bool isOwnerPtr(const std::string &Name)
bool isStdView(const clang::CXXRecordDecl *R)
const FunctionProtoType * T
std::optional< bool > isRefCountable(const clang::CXXRecordDecl *R)
std::optional< const clang::CXXRecordDecl * > hasPublicMethodInBase(const CXXBaseSpecifier *Base, StringRef NameToMatch)
bool isSmartPtrClass(const std::string &Name)
std::string getConstructorName(const clang::FunctionDecl *F)
bool isRefCounted(const CXXRecordDecl *R)
static bool derivesFromViewInterface(const clang::CXXRecordDecl *R)
static bool isPtrOfType(const clang::QualType T, Predicate Pred)
std::optional< bool > isSmartPtrCompatible(const CXXRecordDecl *R, StringRef IncMethodName, StringRef DecMethodName)
bool isNoDeleteFunction(const FunctionDecl *F)
bool isOwnerPtrType(const clang::QualType T)
bool isSmartPtr(const CXXRecordDecl *R)
std::optional< bool > isGetterOfSafePtr(const CXXMethodDecl *M)
bool isRetainPtrOrOSPtr(const std::string &Name)
bool isRefType(const std::string &Name)
bool isUniquePtr(const std::string &Name)
std::optional< bool > isUncountedPtr(const QualType T)
static std::optional< bool > hasPublicMethodInHierarchy(const CXXRecordDecl *R, StringRef MethodName)
std::string safeGetName(const T *ASTNode)
bool isCtorOfCheckedPtr(const clang::FunctionDecl *F)
bool isSingleton(const NamedDecl *F)
bool isCheckedPtr(const std::string &Name)
bool isStdOrWTFMove(const clang::FunctionDecl *F)
bool isBorrowType(const clang::QualType T)
@ None
No keyword precedes the qualified type name.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
static bool hasAnnotationForFunction(const FunctionDecl *FD, WebKitAnnotation TargetAnnotation)
std::optional< bool > isUncounted(const QualType T)
static WebKitAnnotation annotationType(StringRef Annotation)
std::optional< bool > isUncheckedPtr(const QualType T)
bool isWeakPtr(const CXXRecordDecl *R)
Explains why TrivialFunctionAnalysis rejected a statement, so that a diagnostic can blame the code th...