@@ -210,37 +210,46 @@ QualType HeuristicResolverImpl::getPointeeType(QualType T) {
210
210
QualType HeuristicResolverImpl::simplifyType (QualType Type, const Expr *E,
211
211
bool UnwrapPointer) {
212
212
bool DidUnwrapPointer = false ;
213
- auto SimplifyOneStep = [&](QualType T) {
213
+ // A type, together with an optional expression whose type it represents
214
+ // which may have additional information about the expression's type
215
+ // not stored in the QualType itself.
216
+ struct TypeExprPair {
217
+ QualType Type;
218
+ const Expr *E = nullptr ;
219
+ };
220
+ TypeExprPair Current{Type, E};
221
+ auto SimplifyOneStep = [UnwrapPointer, &DidUnwrapPointer,
222
+ this ](TypeExprPair T) -> TypeExprPair {
214
223
if (UnwrapPointer) {
215
- if (QualType Pointee = getPointeeType (T); !Pointee.isNull ()) {
224
+ if (QualType Pointee = getPointeeType (T. Type ); !Pointee.isNull ()) {
216
225
DidUnwrapPointer = true ;
217
- return Pointee;
226
+ return { Pointee} ;
218
227
}
219
228
}
220
- if (const auto *RT = T->getAs <ReferenceType>()) {
229
+ if (const auto *RT = T. Type ->getAs <ReferenceType>()) {
221
230
// Does not count as "unwrap pointer".
222
- return RT->getPointeeType ();
231
+ return { RT->getPointeeType ()} ;
223
232
}
224
- if (const auto *BT = T->getAs <BuiltinType>()) {
233
+ if (const auto *BT = T. Type ->getAs <BuiltinType>()) {
225
234
// If BaseType is the type of a dependent expression, it's just
226
235
// represented as BuiltinType::Dependent which gives us no information. We
227
236
// can get further by analyzing the dependent expression.
228
- if (E && BT->getKind () == BuiltinType::Dependent) {
229
- return resolveExprToType (E) ;
237
+ if (T. E && BT->getKind () == BuiltinType::Dependent) {
238
+ return { resolveExprToType (T. E ), T. E } ;
230
239
}
231
240
}
232
- if (const auto *AT = T->getContainedAutoType ()) {
241
+ if (const auto *AT = T. Type ->getContainedAutoType ()) {
233
242
// If T contains a dependent `auto` type, deduction will not have
234
243
// been performed on it yet. In simple cases (e.g. `auto` variable with
235
244
// initializer), get the approximate type that would result from
236
245
// deduction.
237
246
// FIXME: A more accurate implementation would propagate things like the
238
247
// `const` in `const auto`.
239
- if (E && AT->isUndeducedAutoType ()) {
240
- if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
248
+ if (T. E && AT->isUndeducedAutoType ()) {
249
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(T. E )) {
241
250
if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl ())) {
242
- if (VD->hasInit ())
243
- return resolveExprToType (VD-> getInit ()) ;
251
+ if (auto *Init = VD->getInit ())
252
+ return { resolveExprToType (Init), Init} ;
244
253
}
245
254
}
246
255
}
@@ -251,15 +260,15 @@ QualType HeuristicResolverImpl::simplifyType(QualType Type, const Expr *E,
251
260
// simplification steps.
252
261
size_t StepCount = 0 ;
253
262
const size_t MaxSteps = 64 ;
254
- while (!Type.isNull () && StepCount++ < MaxSteps) {
255
- QualType New = SimplifyOneStep (Type );
256
- if (New == Type)
263
+ while (!Current. Type .isNull () && StepCount++ < MaxSteps) {
264
+ TypeExprPair New = SimplifyOneStep (Current );
265
+ if (New. Type == Current. Type )
257
266
break ;
258
- Type = New;
267
+ Current = New;
259
268
}
260
269
if (UnwrapPointer && !DidUnwrapPointer)
261
270
return QualType ();
262
- return Type;
271
+ return Current. Type ;
263
272
}
264
273
265
274
std::vector<const NamedDecl *> HeuristicResolverImpl::resolveMemberExpr (
0 commit comments