@@ -210,37 +210,46 @@ QualType HeuristicResolverImpl::getPointeeType(QualType T) {
210210QualType HeuristicResolverImpl::simplifyType (QualType Type, const Expr *E,
211211 bool UnwrapPointer) {
212212 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 {
214223 if (UnwrapPointer) {
215- if (QualType Pointee = getPointeeType (T); !Pointee.isNull ()) {
224+ if (QualType Pointee = getPointeeType (T. Type ); !Pointee.isNull ()) {
216225 DidUnwrapPointer = true ;
217- return Pointee;
226+ return { Pointee} ;
218227 }
219228 }
220- if (const auto *RT = T->getAs <ReferenceType>()) {
229+ if (const auto *RT = T. Type ->getAs <ReferenceType>()) {
221230 // Does not count as "unwrap pointer".
222- return RT->getPointeeType ();
231+ return { RT->getPointeeType ()} ;
223232 }
224- if (const auto *BT = T->getAs <BuiltinType>()) {
233+ if (const auto *BT = T. Type ->getAs <BuiltinType>()) {
225234 // If BaseType is the type of a dependent expression, it's just
226235 // represented as BuiltinType::Dependent which gives us no information. We
227236 // 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 } ;
230239 }
231240 }
232- if (const auto *AT = T->getContainedAutoType ()) {
241+ if (const auto *AT = T. Type ->getContainedAutoType ()) {
233242 // If T contains a dependent `auto` type, deduction will not have
234243 // been performed on it yet. In simple cases (e.g. `auto` variable with
235244 // initializer), get the approximate type that would result from
236245 // deduction.
237246 // FIXME: A more accurate implementation would propagate things like the
238247 // `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 )) {
241250 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} ;
244253 }
245254 }
246255 }
@@ -251,15 +260,15 @@ QualType HeuristicResolverImpl::simplifyType(QualType Type, const Expr *E,
251260 // simplification steps.
252261 size_t StepCount = 0 ;
253262 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 )
257266 break ;
258- Type = New;
267+ Current = New;
259268 }
260269 if (UnwrapPointer && !DidUnwrapPointer)
261270 return QualType ();
262- return Type;
271+ return Current. Type ;
263272}
264273
265274std::vector<const NamedDecl *> HeuristicResolverImpl::resolveMemberExpr (
0 commit comments