19 using namespace clang;
36 if (!Self || !(Self->Item == Other->Item))
41 llvm_unreachable(
"The above loop can only be terminated via return!");
45 ConstructionContext::createMaterializedTemporaryFromLayers(
74 ElidedCE = cast<CXXConstructExpr>(ElidedItem.
getStmt());
75 assert(ElidedCE->isElidable());
80 ElidedCC = createFromLayers(C, ParentLayer->
getParent());
84 return create<SimpleTemporaryObjectConstructionContext>(
C, BTE, MTE);
86 return create<ElidedTemporaryObjectConstructionContext>(
87 C, BTE, MTE, ElidedCE, ElidedCC);
92 return create<SimpleTemporaryObjectConstructionContext>(
C, BTE, MTE);
103 return create<SimpleTemporaryObjectConstructionContext>(
C, BTE,
108 switch (ParentItem.getKind()) {
110 const auto *DS = cast<DeclStmt>(ParentItem.getStmt());
111 assert(!cast<VarDecl>(DS->getSingleDecl())->getType().getCanonicalType()
112 ->getAsCXXRecordDecl()->hasTrivialDestructor());
113 return create<CXX17ElidedCopyVariableConstructionContext>(
C, DS, BTE);
116 llvm_unreachable(
"This context does not accept a bound temporary!");
119 assert(ParentLayer->
isLast());
120 const auto *RS = cast<ReturnStmt>(ParentItem.getStmt());
121 assert(!RS->getRetValue()->getType().getCanonicalType()
122 ->getAsCXXRecordDecl()->hasTrivialDestructor());
123 return create<CXX17ElidedCopyReturnedValueConstructionContext>(
C, RS,
129 const auto *MTE = cast<MaterializeTemporaryExpr>(ParentItem.getStmt());
130 return createMaterializedTemporaryFromLayers(C, MTE, BTE,
134 llvm_unreachable(
"Duplicate CXXBindTemporaryExpr in the AST!");
137 llvm_unreachable(
"Elided destructor items are not produced by the CFG!");
140 llvm_unreachable(
"Materialization is necessary to put temporary into a " 141 "copy or move constructor!");
144 assert(ParentLayer->
isLast());
145 const auto *E = cast<Expr>(ParentItem.getStmt());
146 assert(isa<CallExpr>(E) || isa<CXXConstructExpr>(E) ||
147 isa<ObjCMessageExpr>(E));
148 return create<ArgumentConstructionContext>(
C, E, ParentItem.getIndex(),
152 assert(ParentLayer->
isLast());
153 const auto *I = ParentItem.getCXXCtorInitializer();
154 assert(!I->getAnyMember()->getType().getCanonicalType()
155 ->getAsCXXRecordDecl()->hasTrivialDestructor());
156 return create<CXX17ElidedCopyConstructorInitializerConstructionContext>(
161 llvm_unreachable(
"Unexpected construction context with destructor!");
172 assert(TopLayer->
isLast());
173 const auto *DS = cast<DeclStmt>(TopItem.
getStmt());
174 return create<SimpleVariableConstructionContext>(
C, DS);
177 assert(TopLayer->
isLast());
178 const auto *
NE = cast<CXXNewExpr>(TopItem.
getStmt());
179 return create<NewAllocatedObjectConstructionContext>(
C,
NE);
182 assert(TopLayer->
isLast());
183 const auto *RS = cast<ReturnStmt>(TopItem.
getStmt());
184 return create<SimpleReturnedValueConstructionContext>(
C, RS);
187 const auto *MTE = cast<MaterializeTemporaryExpr>(TopItem.
getStmt());
188 return createMaterializedTemporaryFromLayers(C, MTE,
nullptr,
192 const auto *BTE = cast<CXXBindTemporaryExpr>(TopItem.
getStmt());
195 return createBoundTemporaryFromLayers(C, BTE, TopLayer->
getParent());
198 llvm_unreachable(
"Elided destructor items are not produced by the CFG!");
201 llvm_unreachable(
"The argument needs to be materialized first!");
204 assert(TopLayer->
isLast());
206 return create<SimpleConstructorInitializerConstructionContext>(
C, I);
209 assert(TopLayer->
isLast());
210 const auto *E = cast<Expr>(TopItem.
getStmt());
211 return create<ArgumentConstructionContext>(
C, E, TopItem.
getIndex(),
215 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.
bool NE(InterpState &S, CodePtr OpPC)
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).