20 using namespace clang;
37 if (!Self || !(Self->Item == Other->Item))
42 llvm_unreachable(
"The above loop can only be terminated via return!");
46 ConstructionContext::createMaterializedTemporaryFromLayers(
75 ElidedCE = cast<CXXConstructExpr>(ElidedItem.
getStmt());
76 assert(ElidedCE->isElidable());
81 ElidedCC = createFromLayers(C, ParentLayer->
getParent());
85 return create<SimpleTemporaryObjectConstructionContext>(
C, BTE, MTE);
87 return create<ElidedTemporaryObjectConstructionContext>(
88 C, BTE, MTE, ElidedCE, ElidedCC);
93 return create<SimpleTemporaryObjectConstructionContext>(
C, BTE, MTE);
104 return create<SimpleTemporaryObjectConstructionContext>(
C, BTE,
109 switch (ParentItem.getKind()) {
111 const auto *DS = cast<DeclStmt>(ParentItem.getStmt());
112 assert(!cast<VarDecl>(DS->getSingleDecl())->getType().getCanonicalType()
113 ->getAsCXXRecordDecl()->hasTrivialDestructor());
114 return create<CXX17ElidedCopyVariableConstructionContext>(
C, DS, BTE);
117 llvm_unreachable(
"This context does not accept a bound temporary!");
120 assert(ParentLayer->
isLast());
121 const auto *RS = cast<ReturnStmt>(ParentItem.getStmt());
122 assert(!RS->getRetValue()->getType().getCanonicalType()
123 ->getAsCXXRecordDecl()->hasTrivialDestructor());
124 return create<CXX17ElidedCopyReturnedValueConstructionContext>(
C, RS,
130 const auto *MTE = cast<MaterializeTemporaryExpr>(ParentItem.getStmt());
131 return createMaterializedTemporaryFromLayers(C, MTE, BTE,
135 llvm_unreachable(
"Duplicate CXXBindTemporaryExpr in the AST!");
138 llvm_unreachable(
"Elided destructor items are not produced by the CFG!");
141 llvm_unreachable(
"Materialization is necessary to put temporary into a " 142 "copy or move constructor!");
145 assert(ParentLayer->
isLast());
146 const auto *E = cast<Expr>(ParentItem.getStmt());
147 assert(isa<CallExpr>(E) || isa<CXXConstructExpr>(E) ||
148 isa<ObjCMessageExpr>(E));
149 return create<ArgumentConstructionContext>(
C, E, ParentItem.getIndex(),
153 assert(ParentLayer->
isLast());
154 const auto *I = ParentItem.getCXXCtorInitializer();
155 assert(!I->getAnyMember()->getType().getCanonicalType()
156 ->getAsCXXRecordDecl()->hasTrivialDestructor());
157 return create<CXX17ElidedCopyConstructorInitializerConstructionContext>(
162 llvm_unreachable(
"Unexpected construction context with destructor!");
173 assert(TopLayer->
isLast());
174 const auto *DS = cast<DeclStmt>(TopItem.
getStmt());
175 return create<SimpleVariableConstructionContext>(
C, DS);
178 assert(TopLayer->
isLast());
179 const auto *NE = cast<CXXNewExpr>(TopItem.
getStmt());
180 return create<NewAllocatedObjectConstructionContext>(
C, NE);
183 assert(TopLayer->
isLast());
184 const auto *RS = cast<ReturnStmt>(TopItem.
getStmt());
185 return create<SimpleReturnedValueConstructionContext>(
C, RS);
188 const auto *MTE = cast<MaterializeTemporaryExpr>(TopItem.
getStmt());
189 return createMaterializedTemporaryFromLayers(C, MTE,
nullptr,
193 const auto *BTE = cast<CXXBindTemporaryExpr>(TopItem.
getStmt());
196 return createBoundTemporaryFromLayers(C, BTE, TopLayer->
getParent());
199 llvm_unreachable(
"Elided destructor items are not produced by the CFG!");
202 llvm_unreachable(
"The argument needs to be materialized first!");
205 assert(TopLayer->
isLast());
207 return create<SimpleConstructorInitializerConstructionContext>(
C, I);
210 assert(TopLayer->
isLast());
211 const auto *E = cast<Expr>(TopItem.
getStmt());
212 return create<ArgumentConstructionContext>(
C, E, TopItem.
getIndex(),
216 llvm_unreachable(
"Unexpected construction context!");
Represents a call to a C++ constructor.
bool isStrictlyMoreSpecificThan(const ConstructionContextLayer *Other) const
See if Other is a proper initial segment of this construction context in terms of the parent chain - ...
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
llvm::BumpPtrAllocator & getAllocator()
const ConstructionContextLayer * getParent() const
Represents binding an expression to a temporary.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool hasNonTrivialDestructor() const
Determine whether this class has a non-trivial destructor (C++ [class.dtor]p3)
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
static const ConstructionContext * createFromLayers(BumpVectorContext &C, const ConstructionContextLayer *TopLayer)
Consume the construction context layer, together with its parent layers, and wrap it up into a comple...
QualType getCanonicalType() const
Construction context can be seen as a linked list of multiple layers.
const CXXCtorInitializer * getCXXCtorInitializer() const
The construction site is not necessarily a statement.
unsigned getIndex() const
If a single trigger statement triggers multiple constructors, they are usually being enumerated...
Dataflow Directional Tag Classes.
Represents a single point (AST node) in the program that requires attention during construction of an...
Represents a C++ base or member initializer.
const ConstructionContextItem & getItem() const
static const ConstructionContextLayer * create(BumpVectorContext &C, const ConstructionContextItem &Item, const ConstructionContextLayer *Parent=nullptr)
const Stmt * getStmt() const
The construction site - the statement that triggered the construction for one of its parts...
ConstructionContext's subclasses describe different ways of constructing an object in C++...
Full-expression storage duration (for temporaries).