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