@@ -5283,6 +5283,17 @@ Sema::SetDelegatingInitializer(CXXConstructorDecl *Constructor,
5283
5283
return false;
5284
5284
}
5285
5285
5286
+ static CXXDestructorDecl *LookupDestructorIfRelevant(Sema &S,
5287
+ CXXRecordDecl *Class) {
5288
+ if (Class->isInvalidDecl())
5289
+ return nullptr;
5290
+ if (Class->hasIrrelevantDestructor())
5291
+ return nullptr;
5292
+
5293
+ // Dtor might still be missing, e.g because it's invalid.
5294
+ return S.LookupDestructor(Class);
5295
+ }
5296
+
5286
5297
static void MarkFieldDestructorReferenced(Sema &S, SourceLocation Location,
5287
5298
FieldDecl *Field) {
5288
5299
if (Field->isInvalidDecl())
@@ -5294,23 +5305,18 @@ static void MarkFieldDestructorReferenced(Sema &S, SourceLocation Location,
5294
5305
5295
5306
QualType FieldType = S.Context.getBaseElementType(Field->getType());
5296
5307
5297
- const RecordType *RT = FieldType->getAs<RecordType> ();
5298
- if (!RT )
5308
+ auto *FieldClassDecl = FieldType->getAsCXXRecordDecl ();
5309
+ if (!FieldClassDecl )
5299
5310
return;
5300
5311
5301
- CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
5302
- if (FieldClassDecl->isInvalidDecl())
5303
- return;
5304
- if (FieldClassDecl->hasIrrelevantDestructor())
5305
- return;
5306
5312
// The destructor for an implicit anonymous union member is never invoked.
5307
5313
if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
5308
5314
return;
5309
5315
5310
- CXXDestructorDecl *Dtor = S.LookupDestructor(FieldClassDecl);
5311
- // Dtor might still be missing, e.g because it's invalid.
5316
+ auto *Dtor = LookupDestructorIfRelevant(S, FieldClassDecl);
5312
5317
if (!Dtor)
5313
5318
return;
5319
+
5314
5320
S.CheckDestructorAccess(Field->getLocation(), Dtor,
5315
5321
S.PDiag(diag::err_access_dtor_field)
5316
5322
<< Field->getDeclName() << FieldType);
@@ -5337,30 +5343,22 @@ static void MarkBaseDestructorsReferenced(Sema &S, SourceLocation Location,
5337
5343
VisitVirtualBases = false;
5338
5344
}
5339
5345
5340
- llvm::SmallPtrSet<const RecordType *, 8> DirectVirtualBases;
5346
+ llvm::SmallPtrSet<const CXXRecordDecl *, 8> DirectVirtualBases;
5341
5347
5342
5348
// Bases.
5343
5349
for (const auto &Base : ClassDecl->bases()) {
5344
- const RecordType *RT = Base.getType()->getAs<RecordType> ();
5345
- if (!RT )
5350
+ auto *BaseClassDecl = Base.getType()->getAsCXXRecordDecl ();
5351
+ if (!BaseClassDecl )
5346
5352
continue;
5347
5353
5348
5354
// Remember direct virtual bases.
5349
5355
if (Base.isVirtual()) {
5350
5356
if (!VisitVirtualBases)
5351
5357
continue;
5352
- DirectVirtualBases.insert(RT );
5358
+ DirectVirtualBases.insert(BaseClassDecl );
5353
5359
}
5354
5360
5355
- CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
5356
- // If our base class is invalid, we probably can't get its dtor anyway.
5357
- if (BaseClassDecl->isInvalidDecl())
5358
- continue;
5359
- if (BaseClassDecl->hasIrrelevantDestructor())
5360
- continue;
5361
-
5362
- CXXDestructorDecl *Dtor = S.LookupDestructor(BaseClassDecl);
5363
- // Dtor might still be missing, e.g because it's invalid.
5361
+ auto *Dtor = LookupDestructorIfRelevant(S, BaseClassDecl);
5364
5362
if (!Dtor)
5365
5363
continue;
5366
5364
@@ -5559,8 +5557,7 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
5559
5557
// C++ [class.base.init]p12:
5560
5558
// In a non-delegating constructor, the destructor for each
5561
5559
// potentially constructed subobject of class type is potentially
5562
- // invoked
5563
- // ([class.dtor]).
5560
+ // invoked.
5564
5561
MarkFieldDestructorReferenced(*this, Location, Field);
5565
5562
}
5566
5563
@@ -5891,27 +5888,21 @@ void Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
5891
5888
5892
5889
void Sema::MarkVirtualBaseDestructorsReferenced(
5893
5890
SourceLocation Location, CXXRecordDecl *ClassDecl,
5894
- llvm::SmallPtrSetImpl<const RecordType *> *DirectVirtualBases) {
5891
+ llvm::SmallPtrSetImpl<const CXXRecordDecl *> *DirectVirtualBases) {
5895
5892
// Virtual bases.
5896
5893
for (const auto &VBase : ClassDecl->vbases()) {
5897
- // Bases are always records in a well-formed non-dependent class.
5898
- const RecordType *RT = VBase.getType()->castAs<RecordType>();
5899
-
5900
- // Ignore already visited direct virtual bases.
5901
- if (DirectVirtualBases && DirectVirtualBases->count(RT))
5894
+ auto *BaseClassDecl = VBase.getType()->getAsCXXRecordDecl();
5895
+ if (!BaseClassDecl)
5902
5896
continue;
5903
5897
5904
- CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
5905
- // If our base class is invalid, we probably can't get its dtor anyway.
5906
- if (BaseClassDecl->isInvalidDecl())
5907
- continue;
5908
- if (BaseClassDecl->hasIrrelevantDestructor())
5898
+ // Ignore already visited direct virtual bases.
5899
+ if (DirectVirtualBases && DirectVirtualBases->count(BaseClassDecl))
5909
5900
continue;
5910
5901
5911
- CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl);
5912
- // Dtor might still be missing, e.g because it's invalid.
5902
+ auto *Dtor = LookupDestructorIfRelevant(*this, BaseClassDecl);
5913
5903
if (!Dtor)
5914
5904
continue;
5905
+
5915
5906
if (CheckDestructorAccess(
5916
5907
ClassDecl->getLocation(), Dtor,
5917
5908
PDiag(diag::err_access_dtor_vbase)
0 commit comments