21#include "llvm/ADT/StringMap.h"
27class MissingOriginCollector
28 :
public RecursiveASTVisitor<MissingOriginCollector> {
30 MissingOriginCollector(
31 const llvm::DenseMap<const clang::Expr *, OriginList *> &ExprToOriginList,
32 LifetimeSafetyStats &LSStats)
33 : ExprToOriginList(ExprToOriginList), LSStats(LSStats) {}
34 bool VisitExpr(Expr *E) {
38 if (!ExprToOriginList.contains(E)) {
40 LSStats.ExprTypeToMissingOriginCount[E->getType().getTypePtr()]++;
41 LSStats.ExprStmtClassToMissingOriginCount[std::string(
42 E->getStmtClassName())]++;
48 const llvm::DenseMap<const clang::Expr *, OriginList *> &ExprToOriginList;
49 LifetimeSafetyStats &LSStats;
91 if (
const auto *MD = llvm::dyn_cast_or_null<CXXMethodDecl>(D);
92 MD && MD->isInstance())
93 ThisOrigins = buildListForType(MD->getThisType(), MD);
102OriginList *OriginManager::createNode(
const Expr *E,
QualType QT) {
105 return new (ListAllocator.Allocate<OriginList>()) OriginList(NewID);
109OriginList *OriginManager::buildListForType(
QualType QT,
const T *Node) {
110 assert(
hasOrigins(QT) &&
"buildListForType called for non-pointer type");
111 OriginList *Head = createNode(Node, QT);
118 Head->setInnerOriginList(buildListForType(PointeeTy, Node));
126 auto It = DeclToList.find(D);
127 if (It != DeclToList.end())
129 return DeclToList[D] = buildListForType(D->
getType(), D);
133 if (
auto *ParenIgnored = E->
IgnoreParens(); ParenIgnored != E)
142 auto It = ExprToList.find(E);
143 if (It != ExprToList.end())
149 if (llvm::isa<CXXThisExpr>(E)) {
150 assert(ThisOrigins &&
"origins for 'this' should be set for a method decl");
156 const ValueDecl *ReferencedDecl =
nullptr;
157 if (
auto *DRE = dyn_cast<DeclRefExpr>(E))
158 ReferencedDecl = DRE->getDecl();
159 else if (
auto *ME = dyn_cast<MemberExpr>(E))
160 if (
auto *Field = dyn_cast<FieldDecl>(ME->getMemberDecl());
162 ReferencedDecl = Field;
163 if (ReferencedDecl) {
182 return ExprToList[E] = Head;
189 Type = AST.getLValueReferenceType(
Type);
190 return ExprToList[E] = buildListForType(
Type, E);
197 OS <<
"Decl: " << VD->getNameAsString();
200 if (
auto *DRE = dyn_cast<DeclRefExpr>(E)) {
201 if (
const ValueDecl *VD = DRE->getDecl())
202 OS <<
", Decl: " << VD->getNameAsString();
213 assert(ID.Value < AllOrigins.size());
214 return AllOrigins[ID.Value];
219 MissingOriginCollector Collector(this->ExprToList, LSStats);
220 Collector.TraverseStmt(
const_cast<Stmt *
>(&FunctionBody));
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 the clang::Expr interface and subclasses for C++ expressions.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Decl - This represents one declaration (or definition), e.g.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
A (possibly-)qualified type.
const Type * getTypePtrOrNull() const
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Stmt - This represents one statement.
const char * getStmtClassName() const
The base class of the type hierarchy.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isPointerOrReferenceType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
A list of origins representing levels of indirection for pointer-like types.
void setInnerOriginList(OriginList *Inner)
OriginList * getOrCreateList(const ValueDecl *D)
Gets or creates the OriginList for a given ValueDecl.
const Origin & getOrigin(OriginID ID) const
void collectMissingOrigins(Stmt &FunctionBody, LifetimeSafetyStats &LSStats)
Collects statistics about expressions that lack associated origins.
void dump(OriginID OID, llvm::raw_ostream &OS) const
OriginManager(ASTContext &AST, const Decl *D)
utils::ID< struct OriginTag > OriginID
bool doesDeclHaveStorage(const ValueDecl *D)
Returns true if the declaration has its own storage that can be borrowed.
bool hasOrigins(QualType QT)
bool isGslPointerType(QualType QT)
bool isa(CodeGen::Address addr)
const FunctionProtoType * T
A structure to hold the statistics related to LifetimeAnalysis.
An Origin is a symbolic identifier that represents the set of possible loans a pointer-like object co...
const clang::Expr * getExpr() const
const clang::ValueDecl * getDecl() const
const Type * Ty
The type at this indirection level.