@@ -5736,11 +5736,19 @@ class ConceptInfo {
5736
5736
// In particular, when E->getType() is DependentTy, try to guess a likely type.
5737
5737
// We accept some lossiness (like dropping parameters).
5738
5738
// 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 ) {
5740
5740
if (E->getType ().isNull ())
5741
5741
return QualType ();
5742
5742
E = E->IgnoreParenImpCasts ();
5743
5743
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
+ }
5744
5752
// We only resolve DependentTy, or undeduced autos (including auto* etc).
5745
5753
if (!Unresolved->isSpecificBuiltinType (BuiltinType::Dependent)) {
5746
5754
AutoType *Auto = Unresolved->getContainedAutoType ();
@@ -5749,7 +5757,7 @@ QualType getApproximateType(const Expr *E) {
5749
5757
}
5750
5758
// A call: approximate-resolve callee to a function type, get its return type
5751
5759
if (const CallExpr *CE = llvm::dyn_cast<CallExpr>(E)) {
5752
- QualType Callee = getApproximateType (CE->getCallee ());
5760
+ QualType Callee = getApproximateType (CE->getCallee (), Resolver );
5753
5761
if (Callee.isNull () ||
5754
5762
Callee->isSpecificPlaceholderType (BuiltinType::BoundMember))
5755
5763
Callee = Expr::findBoundMemberType (CE->getCallee ());
@@ -5792,7 +5800,7 @@ QualType getApproximateType(const Expr *E) {
5792
5800
if (const auto *CDSME = llvm::dyn_cast<CXXDependentScopeMemberExpr>(E)) {
5793
5801
QualType Base = CDSME->isImplicitAccess ()
5794
5802
? CDSME->getBaseType ()
5795
- : getApproximateType (CDSME->getBase ());
5803
+ : getApproximateType (CDSME->getBase (), Resolver );
5796
5804
if (CDSME->isArrow () && !Base.isNull ())
5797
5805
Base = Base->getPointeeType (); // could handle unique_ptr etc here?
5798
5806
auto *RD =
@@ -5813,14 +5821,15 @@ QualType getApproximateType(const Expr *E) {
5813
5821
if (const auto *DRE = llvm::dyn_cast<DeclRefExpr>(E)) {
5814
5822
if (const auto *VD = llvm::dyn_cast<VarDecl>(DRE->getDecl ())) {
5815
5823
if (VD->hasInit ())
5816
- return getApproximateType (VD->getInit ());
5824
+ return getApproximateType (VD->getInit (), Resolver );
5817
5825
}
5818
5826
}
5819
5827
if (const auto *UO = llvm::dyn_cast<UnaryOperator>(E)) {
5820
5828
if (UO->getOpcode () == UnaryOperatorKind::UO_Deref) {
5821
5829
// We recurse into the subexpression because it could be of dependent
5822
5830
// type.
5823
- if (auto Pointee = getApproximateType (UO->getSubExpr ())->getPointeeType ();
5831
+ if (auto Pointee =
5832
+ getApproximateType (UO->getSubExpr (), Resolver)->getPointeeType ();
5824
5833
!Pointee.isNull ())
5825
5834
return Pointee;
5826
5835
// Our caller expects a non-null result, even though the SubType is
@@ -5857,7 +5866,8 @@ void SemaCodeCompletion::CodeCompleteMemberReferenceExpr(
5857
5866
SemaRef.PerformMemberExprBaseConversion (Base, IsArrow);
5858
5867
if (ConvertedBase.isInvalid ())
5859
5868
return ;
5860
- QualType ConvertedBaseType = getApproximateType (ConvertedBase.get ());
5869
+ QualType ConvertedBaseType =
5870
+ getApproximateType (ConvertedBase.get (), Resolver);
5861
5871
5862
5872
enum CodeCompletionContext::Kind contextKind;
5863
5873
@@ -5896,7 +5906,7 @@ void SemaCodeCompletion::CodeCompleteMemberReferenceExpr(
5896
5906
return false ;
5897
5907
Base = ConvertedBase.get ();
5898
5908
5899
- QualType BaseType = getApproximateType (Base);
5909
+ QualType BaseType = getApproximateType (Base, Resolver );
5900
5910
if (BaseType.isNull ())
5901
5911
return false ;
5902
5912
ExprValueKind BaseKind = Base->getValueKind ();
0 commit comments