@@ -42,8 +42,8 @@ class HeuristicResolverImpl {
4242 resolveDependentNameType (const DependentNameType *DNT);
4343 std::vector<const NamedDecl *> resolveTemplateSpecializationType (
4444 const DependentTemplateSpecializationType *DTST);
45- const Type * resolveNestedNameSpecifierToType (const NestedNameSpecifier *NNS);
46- const Type * getPointeeType (const Type * T);
45+ QualType resolveNestedNameSpecifierToType (const NestedNameSpecifier *NNS);
46+ QualType getPointeeType (QualType T);
4747
4848private:
4949 ASTContext &Ctx;
@@ -61,12 +61,12 @@ class HeuristicResolverImpl {
6161 // This heuristic will give the desired answer in many cases, e.g.
6262 // for a call to vector<T>::size().
6363 std::vector<const NamedDecl *>
64- resolveDependentMember (const Type * T, DeclarationName Name,
64+ resolveDependentMember (QualType T, DeclarationName Name,
6565 llvm::function_ref<bool (const NamedDecl *ND)> Filter);
6666
6767 // Try to heuristically resolve the type of a possibly-dependent expression
6868 // `E`.
69- const Type * resolveExprToType (const Expr *E);
69+ QualType resolveExprToType (const Expr *E);
7070 std::vector<const NamedDecl *> resolveExprToDecls (const Expr *E);
7171
7272 // Helper function for HeuristicResolver::resolveDependentMember()
@@ -104,17 +104,17 @@ const auto TemplateFilter = [](const NamedDecl *D) {
104104 return isa<TemplateDecl>(D);
105105};
106106
107- const Type * resolveDeclsToType (const std::vector<const NamedDecl *> &Decls,
108- ASTContext &Ctx) {
107+ QualType resolveDeclsToType (const std::vector<const NamedDecl *> &Decls,
108+ ASTContext &Ctx) {
109109 if (Decls.size () != 1 ) // Names an overload set -- just bail.
110- return nullptr ;
110+ return QualType () ;
111111 if (const auto *TD = dyn_cast<TypeDecl>(Decls[0 ])) {
112- return Ctx.getTypeDeclType (TD). getTypePtr () ;
112+ return Ctx.getTypeDeclType (TD);
113113 }
114114 if (const auto *VD = dyn_cast<ValueDecl>(Decls[0 ])) {
115- return VD->getType (). getTypePtrOrNull () ;
115+ return VD->getType ();
116116 }
117- return nullptr ;
117+ return QualType () ;
118118}
119119
120120TemplateName getReferencedTemplateName (const Type *T) {
@@ -137,7 +137,8 @@ CXXRecordDecl *HeuristicResolverImpl::resolveTypeToRecordDecl(const Type *T) {
137137 T = T->getCanonicalTypeInternal ().getTypePtr ();
138138
139139 if (const auto *DNT = T->getAs <DependentNameType>()) {
140- T = resolveDeclsToType (resolveDependentNameType (DNT), Ctx);
140+ T = resolveDeclsToType (resolveDependentNameType (DNT), Ctx)
141+ .getTypePtrOrNull ();
141142 if (!T)
142143 return nullptr ;
143144 T = T->getCanonicalTypeInternal ().getTypePtr ();
@@ -163,12 +164,12 @@ CXXRecordDecl *HeuristicResolverImpl::resolveTypeToRecordDecl(const Type *T) {
163164 return TD->getTemplatedDecl ();
164165}
165166
166- const Type * HeuristicResolverImpl::getPointeeType (const Type * T) {
167- if (!T )
168- return nullptr ;
167+ QualType HeuristicResolverImpl::getPointeeType (QualType T) {
168+ if (T. isNull () )
169+ return QualType () ;
169170
170171 if (T->isPointerType ())
171- return T->castAs <PointerType>()->getPointeeType (). getTypePtrOrNull () ;
172+ return T->castAs <PointerType>()->getPointeeType ();
172173
173174 // Try to handle smart pointer types.
174175
@@ -177,7 +178,7 @@ const Type *HeuristicResolverImpl::getPointeeType(const Type *T) {
177178 auto ArrowOps = resolveDependentMember (
178179 T, Ctx.DeclarationNames .getCXXOperatorName (OO_Arrow), NonStaticFilter);
179180 if (ArrowOps.empty ())
180- return nullptr ;
181+ return QualType () ;
181182
182183 // Getting the return type of the found operator-> method decl isn't useful,
183184 // because we discarded template arguments to perform lookup in the primary
@@ -187,13 +188,13 @@ const Type *HeuristicResolverImpl::getPointeeType(const Type *T) {
187188 // form of SmartPtr<X, ...>, and assume X is the pointee type.
188189 auto *TST = T->getAs <TemplateSpecializationType>();
189190 if (!TST)
190- return nullptr ;
191+ return QualType () ;
191192 if (TST->template_arguments ().size () == 0 )
192- return nullptr ;
193+ return QualType () ;
193194 const TemplateArgument &FirstArg = TST->template_arguments ()[0 ];
194195 if (FirstArg.getKind () != TemplateArgument::Type)
195- return nullptr ;
196- return FirstArg.getAsType (). getTypePtrOrNull () ;
196+ return QualType () ;
197+ return FirstArg.getAsType ();
197198}
198199
199200std::vector<const NamedDecl *> HeuristicResolverImpl::resolveMemberExpr (
@@ -210,7 +211,8 @@ std::vector<const NamedDecl *> HeuristicResolverImpl::resolveMemberExpr(
210211 // with `this` as the base expression as `X` as the qualifier
211212 // (which could be valid if `X` names a base class after instantiation).
212213 if (NestedNameSpecifier *NNS = ME->getQualifier ()) {
213- if (const Type *QualifierType = resolveNestedNameSpecifierToType (NNS)) {
214+ if (QualType QualifierType = resolveNestedNameSpecifierToType (NNS);
215+ !QualifierType.isNull ()) {
214216 auto Decls =
215217 resolveDependentMember (QualifierType, ME->getMember (), NoFilter);
216218 if (!Decls.empty ())
@@ -225,11 +227,11 @@ std::vector<const NamedDecl *> HeuristicResolverImpl::resolveMemberExpr(
225227 }
226228
227229 // Try resolving the member inside the expression's base type.
228- const Type * BaseType = ME->getBaseType (). getTypePtrOrNull ();
230+ QualType BaseType = ME->getBaseType ();
229231 if (ME->isArrow ()) {
230232 BaseType = getPointeeType (BaseType);
231233 }
232- if (! BaseType)
234+ if (BaseType. isNull () )
233235 return {};
234236 if (const auto *BT = BaseType->getAs <BuiltinType>()) {
235237 // If BaseType is the type of a dependent expression, it's just
@@ -245,17 +247,17 @@ std::vector<const NamedDecl *> HeuristicResolverImpl::resolveMemberExpr(
245247
246248std::vector<const NamedDecl *>
247249HeuristicResolverImpl::resolveDeclRefExpr (const DependentScopeDeclRefExpr *RE) {
248- return resolveDependentMember (RE->getQualifier ()->getAsType (),
250+ return resolveDependentMember (QualType ( RE->getQualifier ()->getAsType (), 0 ),
249251 RE->getDeclName (), StaticFilter);
250252}
251253
252254std::vector<const NamedDecl *>
253255HeuristicResolverImpl::resolveTypeOfCallExpr (const CallExpr *CE) {
254- const auto * CalleeType = resolveExprToType (CE->getCallee ());
255- if (! CalleeType)
256+ QualType CalleeType = resolveExprToType (CE->getCallee ());
257+ if (CalleeType. isNull () )
256258 return {};
257259 if (const auto *FnTypePtr = CalleeType->getAs <PointerType>())
258- CalleeType = FnTypePtr->getPointeeType (). getTypePtr () ;
260+ CalleeType = FnTypePtr->getPointeeType ();
259261 if (const FunctionType *FnType = CalleeType->getAs <FunctionType>()) {
260262 if (const auto *D =
261263 resolveTypeToRecordDecl (FnType->getReturnType ().getTypePtr ())) {
@@ -276,7 +278,7 @@ HeuristicResolverImpl::resolveCalleeOfCallExpr(const CallExpr *CE) {
276278
277279std::vector<const NamedDecl *> HeuristicResolverImpl::resolveUsingValueDecl (
278280 const UnresolvedUsingValueDecl *UUVD) {
279- return resolveDependentMember (UUVD->getQualifier ()->getAsType (),
281+ return resolveDependentMember (QualType ( UUVD->getQualifier ()->getAsType (), 0 ),
280282 UUVD->getNameInfo ().getName (), ValueFilter);
281283}
282284
@@ -317,18 +319,18 @@ HeuristicResolverImpl::resolveExprToDecls(const Expr *E) {
317319 return {};
318320}
319321
320- const Type * HeuristicResolverImpl::resolveExprToType (const Expr *E) {
322+ QualType HeuristicResolverImpl::resolveExprToType (const Expr *E) {
321323 std::vector<const NamedDecl *> Decls = resolveExprToDecls (E);
322324 if (!Decls.empty ())
323325 return resolveDeclsToType (Decls, Ctx);
324326
325- return E->getType (). getTypePtr () ;
327+ return E->getType ();
326328}
327329
328- const Type * HeuristicResolverImpl::resolveNestedNameSpecifierToType (
330+ QualType HeuristicResolverImpl::resolveNestedNameSpecifierToType (
329331 const NestedNameSpecifier *NNS) {
330332 if (!NNS)
331- return nullptr ;
333+ return QualType () ;
332334
333335 // The purpose of this function is to handle the dependent (Kind ==
334336 // Identifier) case, but we need to recurse on the prefix because
@@ -337,7 +339,7 @@ const Type *HeuristicResolverImpl::resolveNestedNameSpecifierToType(
337339 switch (NNS->getKind ()) {
338340 case NestedNameSpecifier::TypeSpec:
339341 case NestedNameSpecifier::TypeSpecWithTemplate:
340- return NNS->getAsType ();
342+ return QualType ( NNS->getAsType (), 0 );
341343 case NestedNameSpecifier::Identifier: {
342344 return resolveDeclsToType (
343345 resolveDependentMember (
@@ -348,7 +350,7 @@ const Type *HeuristicResolverImpl::resolveNestedNameSpecifierToType(
348350 default :
349351 break ;
350352 }
351- return nullptr ;
353+ return QualType () ;
352354}
353355
354356bool isOrdinaryMember (const NamedDecl *ND) {
@@ -410,8 +412,9 @@ std::vector<const NamedDecl *> HeuristicResolverImpl::lookupDependentName(
410412}
411413
412414std::vector<const NamedDecl *> HeuristicResolverImpl::resolveDependentMember (
413- const Type *T , DeclarationName Name,
415+ QualType QT , DeclarationName Name,
414416 llvm::function_ref<bool (const NamedDecl *ND)> Filter) {
417+ const Type *T = QT.getTypePtrOrNull ();
415418 if (!T)
416419 return {};
417420 if (auto *ET = T->getAs <EnumType>()) {
@@ -422,7 +425,15 @@ std::vector<const NamedDecl *> HeuristicResolverImpl::resolveDependentMember(
422425 if (!RD->hasDefinition ())
423426 return {};
424427 RD = RD->getDefinition ();
425- return lookupDependentName (RD, Name, Filter);
428+ return lookupDependentName (RD, Name, [&](const NamedDecl *ND) {
429+ if (!Filter (ND))
430+ return false ;
431+ if (const auto *MD = dyn_cast<CXXMethodDecl>(ND)) {
432+ return MD->getMethodQualifiers ().compatiblyIncludes (QT.getQualifiers (),
433+ Ctx);
434+ }
435+ return true ;
436+ });
426437 }
427438 return {};
428439}
@@ -457,11 +468,11 @@ HeuristicResolver::resolveTemplateSpecializationType(
457468 const DependentTemplateSpecializationType *DTST) const {
458469 return HeuristicResolverImpl (Ctx).resolveTemplateSpecializationType (DTST);
459470}
460- const Type * HeuristicResolver::resolveNestedNameSpecifierToType (
471+ QualType HeuristicResolver::resolveNestedNameSpecifierToType (
461472 const NestedNameSpecifier *NNS) const {
462473 return HeuristicResolverImpl (Ctx).resolveNestedNameSpecifierToType (NNS);
463474}
464- const Type * HeuristicResolver::getPointeeType (const Type * T) const {
475+ const QualType HeuristicResolver::getPointeeType (QualType T) const {
465476 return HeuristicResolverImpl (Ctx).getPointeeType (T);
466477}
467478
0 commit comments