@@ -134,6 +134,85 @@ bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD,
134
134
return true ;
135
135
}
136
136
137
+ template <typename ResultT>
138
+ bool Context::evaluateStringRepr (State &Parent, const Expr *SizeExpr,
139
+ const Expr *PtrExpr, ResultT &Result) {
140
+ assert (Stk.empty ());
141
+ Compiler<EvalEmitter> C (*this , *P, Parent, Stk);
142
+
143
+ // Evaluate size value.
144
+ APValue SizeValue;
145
+ if (!evaluateAsRValue (Parent, SizeExpr, SizeValue))
146
+ return false ;
147
+
148
+ if (!SizeValue.isInt ())
149
+ return false ;
150
+ uint64_t Size = SizeValue.getInt ().getZExtValue ();
151
+
152
+ auto PtrRes = C.interpretAsPointer (PtrExpr, [&](const Pointer &Ptr ) {
153
+ if (Size == 0 ) {
154
+ if constexpr (std::is_same_v<ResultT, APValue>)
155
+ Result = APValue (APValue::UninitArray{}, 0 , 0 );
156
+ return true ;
157
+ }
158
+
159
+ if (!Ptr .isLive () || !Ptr .getFieldDesc ()->isPrimitiveArray ())
160
+ return false ;
161
+
162
+ // Must be char.
163
+ if (Ptr .getFieldDesc ()->getElemSize () != 1 /* bytes*/ )
164
+ return false ;
165
+
166
+ if (Size > Ptr .getNumElems ()) {
167
+ Parent.FFDiag (SizeExpr, diag::note_constexpr_access_past_end) << AK_Read;
168
+ Size = Ptr .getNumElems ();
169
+ }
170
+
171
+ if constexpr (std::is_same_v<ResultT, APValue>) {
172
+ QualType CharTy = PtrExpr->getType ()->getPointeeType ();
173
+ Result = APValue (APValue::UninitArray{}, Size , Size );
174
+ for (uint64_t I = 0 ; I != Size ; ++I) {
175
+ if (std::optional<APValue> ElemVal =
176
+ Ptr .atIndex (I).toRValue (*this , CharTy))
177
+ Result.getArrayInitializedElt (I) = *ElemVal;
178
+ else
179
+ return false ;
180
+ }
181
+ } else {
182
+ assert ((std::is_same_v<ResultT, std::string>));
183
+ if (Size < Result.max_size ())
184
+ Result.resize (Size );
185
+ Result.assign (reinterpret_cast <const char *>(Ptr .getRawAddress ()), Size );
186
+ }
187
+
188
+ return true ;
189
+ });
190
+
191
+ if (PtrRes.isInvalid ()) {
192
+ C.cleanup ();
193
+ Stk.clear ();
194
+ return false ;
195
+ }
196
+
197
+ return true ;
198
+ }
199
+
200
+ bool Context::evaluateCharRange (State &Parent, const Expr *SizeExpr,
201
+ const Expr *PtrExpr, APValue &Result) {
202
+ assert (SizeExpr);
203
+ assert (PtrExpr);
204
+
205
+ return evaluateStringRepr (Parent, SizeExpr, PtrExpr, Result);
206
+ }
207
+
208
+ bool Context::evaluateCharRange (State &Parent, const Expr *SizeExpr,
209
+ const Expr *PtrExpr, std::string &Result) {
210
+ assert (SizeExpr);
211
+ assert (PtrExpr);
212
+
213
+ return evaluateStringRepr (Parent, SizeExpr, PtrExpr, Result);
214
+ }
215
+
137
216
const LangOptions &Context::getLangOpts () const { return Ctx.getLangOpts (); }
138
217
139
218
std::optional<PrimType> Context::classify (QualType T) const {
0 commit comments