@@ -5736,11 +5736,19 @@ class ConceptInfo {
57365736// In particular, when E->getType() is DependentTy, try to guess a likely type.
57375737// We accept some lossiness (like dropping parameters).
57385738// We only try to handle common expressions on the LHS of MemberExpr.
5739- QualType getApproximateType (const Expr *E) {
5739+ QualType getApproximateType (const Expr *E, HeuristicResolver &Resolver ) {
57405740 if (E->getType ().isNull ())
57415741 return QualType ();
57425742 E = E->IgnoreParenImpCasts ();
57435743 QualType Unresolved = E->getType ();
5744+ // Resolve DependentNameType
5745+ if (const auto *DNT = Unresolved->getAs <DependentNameType>()) {
5746+ if (auto Decls = Resolver.resolveDependentNameType (DNT);
5747+ Decls.size () == 1 ) {
5748+ if (const auto *TD = dyn_cast<TypeDecl>(Decls[0 ]))
5749+ return QualType (TD->getTypeForDecl (), 0 );
5750+ }
5751+ }
57445752 // We only resolve DependentTy, or undeduced autos (including auto* etc).
57455753 if (!Unresolved->isSpecificBuiltinType (BuiltinType::Dependent)) {
57465754 AutoType *Auto = Unresolved->getContainedAutoType ();
@@ -5749,7 +5757,7 @@ QualType getApproximateType(const Expr *E) {
57495757 }
57505758 // A call: approximate-resolve callee to a function type, get its return type
57515759 if (const CallExpr *CE = llvm::dyn_cast<CallExpr>(E)) {
5752- QualType Callee = getApproximateType (CE->getCallee ());
5760+ QualType Callee = getApproximateType (CE->getCallee (), Resolver );
57535761 if (Callee.isNull () ||
57545762 Callee->isSpecificPlaceholderType (BuiltinType::BoundMember))
57555763 Callee = Expr::findBoundMemberType (CE->getCallee ());
@@ -5792,7 +5800,7 @@ QualType getApproximateType(const Expr *E) {
57925800 if (const auto *CDSME = llvm::dyn_cast<CXXDependentScopeMemberExpr>(E)) {
57935801 QualType Base = CDSME->isImplicitAccess ()
57945802 ? CDSME->getBaseType ()
5795- : getApproximateType (CDSME->getBase ());
5803+ : getApproximateType (CDSME->getBase (), Resolver );
57965804 if (CDSME->isArrow () && !Base.isNull ())
57975805 Base = Base->getPointeeType (); // could handle unique_ptr etc here?
57985806 auto *RD =
@@ -5813,14 +5821,15 @@ QualType getApproximateType(const Expr *E) {
58135821 if (const auto *DRE = llvm::dyn_cast<DeclRefExpr>(E)) {
58145822 if (const auto *VD = llvm::dyn_cast<VarDecl>(DRE->getDecl ())) {
58155823 if (VD->hasInit ())
5816- return getApproximateType (VD->getInit ());
5824+ return getApproximateType (VD->getInit (), Resolver );
58175825 }
58185826 }
58195827 if (const auto *UO = llvm::dyn_cast<UnaryOperator>(E)) {
58205828 if (UO->getOpcode () == UnaryOperatorKind::UO_Deref) {
58215829 // We recurse into the subexpression because it could be of dependent
58225830 // type.
5823- if (auto Pointee = getApproximateType (UO->getSubExpr ())->getPointeeType ();
5831+ if (auto Pointee =
5832+ getApproximateType (UO->getSubExpr (), Resolver)->getPointeeType ();
58245833 !Pointee.isNull ())
58255834 return Pointee;
58265835 // Our caller expects a non-null result, even though the SubType is
@@ -5857,7 +5866,8 @@ void SemaCodeCompletion::CodeCompleteMemberReferenceExpr(
58575866 SemaRef.PerformMemberExprBaseConversion (Base, IsArrow);
58585867 if (ConvertedBase.isInvalid ())
58595868 return ;
5860- QualType ConvertedBaseType = getApproximateType (ConvertedBase.get ());
5869+ QualType ConvertedBaseType =
5870+ getApproximateType (ConvertedBase.get (), Resolver);
58615871
58625872 enum CodeCompletionContext::Kind contextKind;
58635873
@@ -5896,7 +5906,7 @@ void SemaCodeCompletion::CodeCompleteMemberReferenceExpr(
58965906 return false ;
58975907 Base = ConvertedBase.get ();
58985908
5899- QualType BaseType = getApproximateType (Base);
5909+ QualType BaseType = getApproximateType (Base, Resolver );
59005910 if (BaseType.isNull ())
59015911 return false ;
59025912 ExprValueKind BaseKind = Base->getValueKind ();
0 commit comments