@@ -42,8 +42,8 @@ class HeuristicResolverImpl {
42
42
resolveDependentNameType (const DependentNameType *DNT);
43
43
std::vector<const NamedDecl *> resolveTemplateSpecializationType (
44
44
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);
47
47
48
48
private:
49
49
ASTContext &Ctx;
@@ -61,12 +61,12 @@ class HeuristicResolverImpl {
61
61
// This heuristic will give the desired answer in many cases, e.g.
62
62
// for a call to vector<T>::size().
63
63
std::vector<const NamedDecl *>
64
- resolveDependentMember (const Type * T, DeclarationName Name,
64
+ resolveDependentMember (QualType T, DeclarationName Name,
65
65
llvm::function_ref<bool (const NamedDecl *ND)> Filter);
66
66
67
67
// Try to heuristically resolve the type of a possibly-dependent expression
68
68
// `E`.
69
- const Type * resolveExprToType (const Expr *E);
69
+ QualType resolveExprToType (const Expr *E);
70
70
std::vector<const NamedDecl *> resolveExprToDecls (const Expr *E);
71
71
72
72
// Helper function for HeuristicResolver::resolveDependentMember()
@@ -104,17 +104,17 @@ const auto TemplateFilter = [](const NamedDecl *D) {
104
104
return isa<TemplateDecl>(D);
105
105
};
106
106
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) {
109
109
if (Decls.size () != 1 ) // Names an overload set -- just bail.
110
- return nullptr ;
110
+ return QualType () ;
111
111
if (const auto *TD = dyn_cast<TypeDecl>(Decls[0 ])) {
112
- return Ctx.getTypeDeclType (TD). getTypePtr () ;
112
+ return Ctx.getTypeDeclType (TD);
113
113
}
114
114
if (const auto *VD = dyn_cast<ValueDecl>(Decls[0 ])) {
115
- return VD->getType (). getTypePtrOrNull () ;
115
+ return VD->getType ();
116
116
}
117
- return nullptr ;
117
+ return QualType () ;
118
118
}
119
119
120
120
TemplateName getReferencedTemplateName (const Type *T) {
@@ -137,7 +137,8 @@ CXXRecordDecl *HeuristicResolverImpl::resolveTypeToRecordDecl(const Type *T) {
137
137
T = T->getCanonicalTypeInternal ().getTypePtr ();
138
138
139
139
if (const auto *DNT = T->getAs <DependentNameType>()) {
140
- T = resolveDeclsToType (resolveDependentNameType (DNT), Ctx);
140
+ T = resolveDeclsToType (resolveDependentNameType (DNT), Ctx)
141
+ .getTypePtrOrNull ();
141
142
if (!T)
142
143
return nullptr ;
143
144
T = T->getCanonicalTypeInternal ().getTypePtr ();
@@ -163,12 +164,12 @@ CXXRecordDecl *HeuristicResolverImpl::resolveTypeToRecordDecl(const Type *T) {
163
164
return TD->getTemplatedDecl ();
164
165
}
165
166
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 () ;
169
170
170
171
if (T->isPointerType ())
171
- return T->castAs <PointerType>()->getPointeeType (). getTypePtrOrNull () ;
172
+ return T->castAs <PointerType>()->getPointeeType ();
172
173
173
174
// Try to handle smart pointer types.
174
175
@@ -177,7 +178,7 @@ const Type *HeuristicResolverImpl::getPointeeType(const Type *T) {
177
178
auto ArrowOps = resolveDependentMember (
178
179
T, Ctx.DeclarationNames .getCXXOperatorName (OO_Arrow), NonStaticFilter);
179
180
if (ArrowOps.empty ())
180
- return nullptr ;
181
+ return QualType () ;
181
182
182
183
// Getting the return type of the found operator-> method decl isn't useful,
183
184
// because we discarded template arguments to perform lookup in the primary
@@ -187,13 +188,13 @@ const Type *HeuristicResolverImpl::getPointeeType(const Type *T) {
187
188
// form of SmartPtr<X, ...>, and assume X is the pointee type.
188
189
auto *TST = T->getAs <TemplateSpecializationType>();
189
190
if (!TST)
190
- return nullptr ;
191
+ return QualType () ;
191
192
if (TST->template_arguments ().size () == 0 )
192
- return nullptr ;
193
+ return QualType () ;
193
194
const TemplateArgument &FirstArg = TST->template_arguments ()[0 ];
194
195
if (FirstArg.getKind () != TemplateArgument::Type)
195
- return nullptr ;
196
- return FirstArg.getAsType (). getTypePtrOrNull () ;
196
+ return QualType () ;
197
+ return FirstArg.getAsType ();
197
198
}
198
199
199
200
std::vector<const NamedDecl *> HeuristicResolverImpl::resolveMemberExpr (
@@ -210,7 +211,8 @@ std::vector<const NamedDecl *> HeuristicResolverImpl::resolveMemberExpr(
210
211
// with `this` as the base expression as `X` as the qualifier
211
212
// (which could be valid if `X` names a base class after instantiation).
212
213
if (NestedNameSpecifier *NNS = ME->getQualifier ()) {
213
- if (const Type *QualifierType = resolveNestedNameSpecifierToType (NNS)) {
214
+ if (QualType QualifierType = resolveNestedNameSpecifierToType (NNS);
215
+ !QualifierType.isNull ()) {
214
216
auto Decls =
215
217
resolveDependentMember (QualifierType, ME->getMember (), NoFilter);
216
218
if (!Decls.empty ())
@@ -225,11 +227,11 @@ std::vector<const NamedDecl *> HeuristicResolverImpl::resolveMemberExpr(
225
227
}
226
228
227
229
// Try resolving the member inside the expression's base type.
228
- const Type * BaseType = ME->getBaseType (). getTypePtrOrNull ();
230
+ QualType BaseType = ME->getBaseType ();
229
231
if (ME->isArrow ()) {
230
232
BaseType = getPointeeType (BaseType);
231
233
}
232
- if (! BaseType)
234
+ if (BaseType. isNull () )
233
235
return {};
234
236
if (const auto *BT = BaseType->getAs <BuiltinType>()) {
235
237
// If BaseType is the type of a dependent expression, it's just
@@ -245,17 +247,17 @@ std::vector<const NamedDecl *> HeuristicResolverImpl::resolveMemberExpr(
245
247
246
248
std::vector<const NamedDecl *>
247
249
HeuristicResolverImpl::resolveDeclRefExpr (const DependentScopeDeclRefExpr *RE) {
248
- return resolveDependentMember (RE->getQualifier ()->getAsType (),
250
+ return resolveDependentMember (QualType ( RE->getQualifier ()->getAsType (), 0 ),
249
251
RE->getDeclName (), StaticFilter);
250
252
}
251
253
252
254
std::vector<const NamedDecl *>
253
255
HeuristicResolverImpl::resolveTypeOfCallExpr (const CallExpr *CE) {
254
- const auto * CalleeType = resolveExprToType (CE->getCallee ());
255
- if (! CalleeType)
256
+ QualType CalleeType = resolveExprToType (CE->getCallee ());
257
+ if (CalleeType. isNull () )
256
258
return {};
257
259
if (const auto *FnTypePtr = CalleeType->getAs <PointerType>())
258
- CalleeType = FnTypePtr->getPointeeType (). getTypePtr () ;
260
+ CalleeType = FnTypePtr->getPointeeType ();
259
261
if (const FunctionType *FnType = CalleeType->getAs <FunctionType>()) {
260
262
if (const auto *D =
261
263
resolveTypeToRecordDecl (FnType->getReturnType ().getTypePtr ())) {
@@ -276,7 +278,7 @@ HeuristicResolverImpl::resolveCalleeOfCallExpr(const CallExpr *CE) {
276
278
277
279
std::vector<const NamedDecl *> HeuristicResolverImpl::resolveUsingValueDecl (
278
280
const UnresolvedUsingValueDecl *UUVD) {
279
- return resolveDependentMember (UUVD->getQualifier ()->getAsType (),
281
+ return resolveDependentMember (QualType ( UUVD->getQualifier ()->getAsType (), 0 ),
280
282
UUVD->getNameInfo ().getName (), ValueFilter);
281
283
}
282
284
@@ -317,18 +319,18 @@ HeuristicResolverImpl::resolveExprToDecls(const Expr *E) {
317
319
return {};
318
320
}
319
321
320
- const Type * HeuristicResolverImpl::resolveExprToType (const Expr *E) {
322
+ QualType HeuristicResolverImpl::resolveExprToType (const Expr *E) {
321
323
std::vector<const NamedDecl *> Decls = resolveExprToDecls (E);
322
324
if (!Decls.empty ())
323
325
return resolveDeclsToType (Decls, Ctx);
324
326
325
- return E->getType (). getTypePtr () ;
327
+ return E->getType ();
326
328
}
327
329
328
- const Type * HeuristicResolverImpl::resolveNestedNameSpecifierToType (
330
+ QualType HeuristicResolverImpl::resolveNestedNameSpecifierToType (
329
331
const NestedNameSpecifier *NNS) {
330
332
if (!NNS)
331
- return nullptr ;
333
+ return QualType () ;
332
334
333
335
// The purpose of this function is to handle the dependent (Kind ==
334
336
// Identifier) case, but we need to recurse on the prefix because
@@ -337,7 +339,7 @@ const Type *HeuristicResolverImpl::resolveNestedNameSpecifierToType(
337
339
switch (NNS->getKind ()) {
338
340
case NestedNameSpecifier::TypeSpec:
339
341
case NestedNameSpecifier::TypeSpecWithTemplate:
340
- return NNS->getAsType ();
342
+ return QualType ( NNS->getAsType (), 0 );
341
343
case NestedNameSpecifier::Identifier: {
342
344
return resolveDeclsToType (
343
345
resolveDependentMember (
@@ -348,7 +350,7 @@ const Type *HeuristicResolverImpl::resolveNestedNameSpecifierToType(
348
350
default :
349
351
break ;
350
352
}
351
- return nullptr ;
353
+ return QualType () ;
352
354
}
353
355
354
356
bool isOrdinaryMember (const NamedDecl *ND) {
@@ -410,8 +412,9 @@ std::vector<const NamedDecl *> HeuristicResolverImpl::lookupDependentName(
410
412
}
411
413
412
414
std::vector<const NamedDecl *> HeuristicResolverImpl::resolveDependentMember (
413
- const Type *T , DeclarationName Name,
415
+ QualType QT , DeclarationName Name,
414
416
llvm::function_ref<bool (const NamedDecl *ND)> Filter) {
417
+ const Type *T = QT.getTypePtrOrNull ();
415
418
if (!T)
416
419
return {};
417
420
if (auto *ET = T->getAs <EnumType>()) {
@@ -422,7 +425,15 @@ std::vector<const NamedDecl *> HeuristicResolverImpl::resolveDependentMember(
422
425
if (!RD->hasDefinition ())
423
426
return {};
424
427
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
+ });
426
437
}
427
438
return {};
428
439
}
@@ -457,11 +468,11 @@ HeuristicResolver::resolveTemplateSpecializationType(
457
468
const DependentTemplateSpecializationType *DTST) const {
458
469
return HeuristicResolverImpl (Ctx).resolveTemplateSpecializationType (DTST);
459
470
}
460
- const Type * HeuristicResolver::resolveNestedNameSpecifierToType (
471
+ QualType HeuristicResolver::resolveNestedNameSpecifierToType (
461
472
const NestedNameSpecifier *NNS) const {
462
473
return HeuristicResolverImpl (Ctx).resolveNestedNameSpecifierToType (NNS);
463
474
}
464
- const Type * HeuristicResolver::getPointeeType (const Type * T) const {
475
+ const QualType HeuristicResolver::getPointeeType (QualType T) const {
465
476
return HeuristicResolverImpl (Ctx).getPointeeType (T);
466
477
}
467
478
0 commit comments