17#include "llvm/ADT/StringSet.h"
29 return cast_if_present<CXXMethodDecl>(
43 auto *MD = dyn_cast<CXXMethodDecl>(FD);
44 if (MD && MD->isCXXInstanceMember())
60static const LifetimeBoundAttr *
68 if (
auto *LBAttr = ATL.getAttrAs<LifetimeBoundAttr>())
70 TL = ATL.getModifiedLoc();
75const LifetimeBoundAttr *
83const LifetimeBoundAttr *
88 auto CheckRedecls = [](
const FunctionDecl *F) ->
const LifetimeBoundAttr * {
95 if (
const auto *
Attr = CheckRedecls(FD))
98 return CheckRedecls(Pattern);
110 if (DC->isStdNamespace())
112 if (
const auto *ND = dyn_cast<NamespaceDecl>(DC))
114 StringRef Name = II->getName();
115 if (Name.size() >= 2 && Name.front() ==
'_' &&
133 bool RunningUnderLifetimeSafety) {
138 const bool IsGslOwnerImplicitObject =
140 (RunningUnderLifetimeSafety &&
142 if (
auto *Conv = dyn_cast<CXXConversionDecl>(Callee))
143 if (
isGslPointerType(Conv->getConversionType()) && IsGslOwnerImplicitObject)
146 !IsGslOwnerImplicitObject)
150 static const llvm::StringSet<> IteratorMembers = {
151 "begin",
"end",
"rbegin",
"rend",
"cbegin",
"cend",
"crbegin",
"crend"};
152 static const llvm::StringSet<> InnerPointerGetters = {
154 "c_str",
"data",
"get"};
155 static const llvm::StringSet<> ContainerFindFns = {
157 "find",
"equal_range",
"lower_bound",
"upper_bound"};
161 if (RunningUnderLifetimeSafety &&
166 switch (Callee->getOverloadedOperator()) {
177 if (Callee->getIdentifier() &&
178 (IteratorMembers.contains(Callee->getName()) ||
179 InnerPointerGetters.contains(Callee->getName())))
187 if (!Callee->getIdentifier())
189 return RunningUnderLifetimeSafety
190 ? IsGslOwnerImplicitObject &&
191 Callee->getOverloadedOperator() ==
192 OverloadedOperatorKind::OO_Arrow
194 return IteratorMembers.contains(Callee->getName()) ||
195 InnerPointerGetters.contains(Callee->getName()) ||
196 ContainerFindFns.contains(Callee->getName());
198 if (Callee->getReturnType()->isReferenceType()) {
199 if (!Callee->getIdentifier()) {
200 auto OO = Callee->getOverloadedOperator();
201 if (!IsGslOwnerImplicitObject)
203 return OO == OverloadedOperatorKind::OO_Subscript ||
204 OO == OverloadedOperatorKind::OO_Star;
206 return llvm::StringSwitch<bool>(Callee->getName())
207 .Cases({
"front",
"back",
"at",
"top",
"value"},
true)
222 if (llvm::StringSwitch<bool>(FD->
getName())
241 if (!RD || !RD->isInStdNamespace())
243 if (!RD->hasAttr<PointerAttr>() && !RD->hasAttr<OwnerAttr>())
251 return llvm::StringSwitch<bool>(FD->
getName())
252 .Cases({
"begin",
"rbegin",
"cbegin",
"crbegin"},
true)
253 .Cases({
"end",
"rend",
"cend",
"crend"},
true)
258 return llvm::StringSwitch<bool>(FD->
getName())
259 .Cases({
"get",
"any_cast"},
true)
273 return RD->
hasAttr<PointerAttr>() &&
301 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
302 Result |= CTSD->getSpecializedTemplate()->getTemplatedDecl()->hasAttr<T>();
318 if (
const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(&RD))
319 return CTSD->getSpecializedTemplate()->getName();
347 static const llvm::StringSet<>
Vector = {
348 "insert",
"emplace",
"emplace_back",
349 "push_back",
"insert_range",
354 "reserve",
"resize",
"shrink_to_fit",
356 "assign",
"assign_range"};
360 static const llvm::StringSet<> Deque = {
361 "insert",
"emplace",
"insert_range",
365 "resize",
"shrink_to_fit",
367 "assign",
"assign_range"};
369 static const llvm::StringSet<> String = {
371 "insert",
"push_back",
"append",
"replace",
"replace_with_range",
372 "insert_range",
"append_range",
374 "pop_back",
"erase",
"clear",
376 "reserve",
"resize",
"resize_and_overwrite",
"shrink_to_fit",
378 "swap",
"assign",
"assign_range"};
382 static const llvm::StringSet<> PriorityQueue = {
390 static const llvm::StringSet<> NodeBased = {
396 static const llvm::StringSet<> Flat = {
397 "insert",
"emplace",
"emplace_hint",
398 "try_emplace",
"insert_or_assign",
399 "insert_range",
"merge",
401 "extract",
"erase",
"clear",
405 static const llvm::StringSet<> UniquePtr = {
408 const StringRef RecordName =
getName(*RD);
411 const llvm::StringSet<> *InvalidatingMethods =
412 llvm::StringSwitch<const llvm::StringSet<> *>(RecordName)
414 .Case(
"basic_string", &String)
415 .Case(
"deque", &Deque)
416 .Case(
"priority_queue", &PriorityQueue)
417 .Cases({
"set",
"multiset",
"map",
"multimap",
"unordered_set",
418 "unordered_multiset",
"unordered_map",
"unordered_multimap"},
420 .Cases({
"flat_map",
"flat_set",
"flat_multimap",
"flat_multiset"},
422 .Case(
"unique_ptr", &UniquePtr)
425 if (!InvalidatingMethods)
438 return RecordName ==
"flat_map";
447 return InvalidatingMethods->contains(MD.
getName());
460 return Name ==
"function" || Name ==
"move_only_function";
467 case Builtin::BImove:
468 case Builtin::BImove_if_noexcept:
469 case Builtin::BIforward:
470 case Builtin::BIforward_like:
471 case Builtin::BIas_const:
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines an enumeration for C++ overloaded operators.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Attr - This represents one attribute.
Type source information for an attributed type.
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 C++ struct/union/class.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
ASTContext & getASTContext() const LLVM_READONLY
DeclContext * getDeclContext()
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
TypeSourceInfo * getTypeSourceInfo() const
This represents one expression.
const CXXRecordDecl * getBestDynamicClassType() const
For an expression of class type or pointer to class type, return the most derived class decl the expr...
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
QualType getReturnType() const
FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const
Retrieve the function declaration from which this function could be instantiated, if it is an instant...
FunctionDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
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.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
size_t param_size() const
One of these records is kept for each identifier that is lexed.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
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.
A (possibly-)qualified type.
Base wrapper for a particular "section" of type source info.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
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.
bool isLValueReferenceType() const
bool isNullPtrType() const
const LifetimeBoundAttr * getDirectImplicitObjectLifetimeBoundAttr(const FunctionDecl *FD)
bool isGslPointerType(QualType QT)
bool isStdCallableWrapperType(const CXXRecordDecl *RD)
bool shouldTrackFirstArgument(const FunctionDecl *FD)
static StringRef getName(const CXXRecordDecl &RD)
bool isAssignmentOperatorLifetimeBound(const CXXMethodDecl *CMD)
bool shouldTrackImplicitObjectArg(const Expr &ImplicitObjectArgument, const CXXMethodDecl *Callee, bool RunningUnderLifetimeSafety)
static const LifetimeBoundAttr * getLifetimeBoundAttrFromFunctionType(const TypeSourceInfo &TSI)
Check if a function has a lifetimebound attribute on its function type (which represents the implicit...
bool isPointerLikeType(QualType QT)
bool isNormalAssignmentOperator(const FunctionDecl *FD)
bool isUniquePtrRelease(const CXXMethodDecl &MD)
static bool isRecordWithAttr(const CXXRecordDecl *RD)
static bool isReferenceOrPointerLikeType(QualType QT)
bool isStdReferenceCast(const FunctionDecl *FD)
bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD)
const LifetimeBoundAttr * getImplicitObjectParamLifetimeBoundAttr(const FunctionDecl *FD)
const FunctionDecl * getDeclWithMergedLifetimeBoundAttrs(const FunctionDecl *FD)
bool isInvalidationMethod(const CXXMethodDecl &MD)
bool destructsFirstArg(const FunctionDecl &FD)
bool isGslOwnerType(QualType QT)
bool isInStlNamespace(const Decl *D)
bool shouldTrackSecondArgument(const FunctionDecl *FD)
static bool isStdUniquePtr(const CXXRecordDecl &RD)
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
bool isa(CodeGen::Address addr)
bool isCompoundAssignmentOperator(OverloadedOperatorKind Kind)
Determine if this is a compound assignment operator.
LLVM_READONLY bool isUppercase(unsigned char c)
Return true if this character is an uppercase ASCII letter: [A-Z].
@ Vector
'vector' clause, allowed on 'loop', Combined, and 'routine' directives.
@ Result
The result type of a method or function.