clang: lib/Analysis/ConstructionContext.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
18
19using namespace clang;
20
28}
29
33 while (true) {
37 return false;
40 }
41 llvm_unreachable("The above loop can only be terminated via return!");
42}
43
45ConstructionContext::createMaterializedTemporaryFromLayers(
49 assert(MTE);
50
51
52
53
57 return nullptr;
58 }
59
60
61
62
64 BTE = nullptr;
65 }
66
67
70 if (ParentLayer) {
72 assert(ElidedItem.getKind() ==
74 ElidedCE = cast(ElidedItem.getStmt());
76
77
78
79
81 if (!ElidedCC) {
82
83
84 return create(C, BTE, MTE);
85 }
86 return create(
87 C, BTE, MTE, ElidedCE, ElidedCC);
88 }
89
90
91 assert(!ParentLayer);
92 return create(C, BTE, MTE);
93}
94
95const ConstructionContext *ConstructionContext::createBoundTemporaryFromLayers(
98 if (!ParentLayer) {
99
100
101
102
103 return create(C, BTE,
104 nullptr);
105 }
106
108 switch (ParentItem.getKind()) {
110 const auto *DS = cast(ParentItem.getStmt());
111 assert(!cast(DS->getSingleDecl())->getType().getCanonicalType()
112 ->getAsCXXRecordDecl()->hasTrivialDestructor());
113 return create(C, DS, BTE);
114 }
116 llvm_unreachable("This context does not accept a bound temporary!");
117 }
119 assert(ParentLayer->isLast());
120 const auto *RS = cast(ParentItem.getStmt());
121 assert(!RS->getRetValue()->getType().getCanonicalType()
122 ->getAsCXXRecordDecl()->hasTrivialDestructor());
123 return create(C, RS,
124 BTE);
125 }
126
128
129 const auto *MTE = cast(ParentItem.getStmt());
130 return createMaterializedTemporaryFromLayers(C, MTE, BTE,
132 }
134 llvm_unreachable("Duplicate CXXBindTemporaryExpr in the AST!");
135 }
137 llvm_unreachable("Elided destructor items are not produced by the CFG!");
138 }
140 llvm_unreachable("Materialization is necessary to put temporary into a "
141 "copy or move constructor!");
142 }
144 assert(ParentLayer->isLast());
145 const auto *E = cast(ParentItem.getStmt());
146 assert(isa(E) || isa(E) ||
147 isa(E));
148 return create(C, E, ParentItem.getIndex(),
149 BTE);
150 }
152 assert(ParentLayer->isLast());
154 assert(!I->getAnyMember()->getType().getCanonicalType()
155 ->getAsCXXRecordDecl()->hasTrivialDestructor());
156 return create(
157 C, I, BTE);
158 }
160 assert(ParentLayer->isLast());
161 const auto *E = cast(ParentItem.getStmt());
164 }
165 }
166
167 llvm_unreachable("Unexpected construction context with destructor!");
168}
169
172
173
174
176 switch (TopItem.getKind()) {
178 assert(TopLayer->isLast());
179 const auto *DS = cast(TopItem.getStmt());
180 return create(C, DS);
181 }
183 assert(TopLayer->isLast());
184 const auto *NE = cast(TopItem.getStmt());
185 return create(C, NE);
186 }
188 assert(TopLayer->isLast());
189 const auto *RS = cast(TopItem.getStmt());
190 return create(C, RS);
191 }
193 const auto *MTE = cast(TopItem.getStmt());
194 return createMaterializedTemporaryFromLayers(C, MTE, nullptr,
196 }
198 const auto *BTE = cast(TopItem.getStmt());
201 return createBoundTemporaryFromLayers(C, BTE, TopLayer->getParent());
202 }
204 llvm_unreachable("Elided destructor items are not produced by the CFG!");
205 }
207 llvm_unreachable("The argument needs to be materialized first!");
208 }
210 assert(TopLayer->isLast());
211 const auto *E = cast(TopItem.getStmt());
212 return create(C, E, TopItem.getIndex());
213 }
215 assert(TopLayer->isLast());
217 return create(C, I);
218 }
220 assert(TopLayer->isLast());
221 const auto *E = cast(TopItem.getStmt());
222 return create(C, E, TopItem.getIndex(),
223 nullptr);
224 }
225 }
226 llvm_unreachable("Unexpected construction context!");
227}
Represents binding an expression to a temporary.
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Represents a C++ base or member initializer.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
bool hasNonTrivialDestructor() const
Determine whether this class has a non-trivial destructor (C++ [class.dtor]p3)
Represents a single point (AST node) in the program that requires attention during construction of an...
unsigned getIndex() const
If a single trigger statement triggers multiple constructors, they are usually being enumerated.
const CXXCtorInitializer * getCXXCtorInitializer() const
The construction site is not necessarily a statement.
@ TemporaryDestructorKind
@ ElidableConstructorKind
const Stmt * getStmt() const
The construction site - the statement that triggered the construction for one of its parts.
Construction context can be seen as a linked list of multiple layers.
static const ConstructionContextLayer * create(BumpVectorContext &C, const ConstructionContextItem &Item, const ConstructionContextLayer *Parent=nullptr)
const ConstructionContextItem & getItem() const
const ConstructionContextLayer * getParent() const
bool isStrictlyMoreSpecificThan(const ConstructionContextLayer *Other) const
See if Other is a proper initial segment of this construction context in terms of the parent chain - ...
ConstructionContext's subclasses describe different ways of constructing an object in C++.
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...
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
QualType getCanonicalType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
The JSON file list parser is used to communicate input to InstallAPI.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
@ Other
Other implicit parameter.