Skip to content

Commit fd9a337

Browse files
committed
Extract duplicated destructor lookups
1 parent 3acb02a commit fd9a337

File tree

2 files changed

+30
-38
lines changed

2 files changed

+30
-38
lines changed

clang/include/clang/Sema/Sema.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -5445,7 +5445,8 @@ class Sema final : public SemaBase {
54455445
/// destructor is referenced.
54465446
void MarkVirtualBaseDestructorsReferenced(
54475447
SourceLocation Location, CXXRecordDecl *ClassDecl,
5448-
llvm::SmallPtrSetImpl<const RecordType *> *DirectVirtualBases = nullptr);
5448+
llvm::SmallPtrSetImpl<const CXXRecordDecl *> *DirectVirtualBases =
5449+
nullptr);
54495450

54505451
/// Do semantic checks to allow the complete destructor variant to be emitted
54515452
/// when the destructor is defined in another translation unit. In the Itanium

clang/lib/Sema/SemaDeclCXX.cpp

+28-37
Original file line numberDiff line numberDiff line change
@@ -5283,6 +5283,17 @@ Sema::SetDelegatingInitializer(CXXConstructorDecl *Constructor,
52835283
return false;
52845284
}
52855285

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+
52865297
static void MarkFieldDestructorReferenced(Sema &S, SourceLocation Location,
52875298
FieldDecl *Field) {
52885299
if (Field->isInvalidDecl())
@@ -5294,23 +5305,18 @@ static void MarkFieldDestructorReferenced(Sema &S, SourceLocation Location,
52945305

52955306
QualType FieldType = S.Context.getBaseElementType(Field->getType());
52965307

5297-
const RecordType *RT = FieldType->getAs<RecordType>();
5298-
if (!RT)
5308+
auto *FieldClassDecl = FieldType->getAsCXXRecordDecl();
5309+
if (!FieldClassDecl)
52995310
return;
53005311

5301-
CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
5302-
if (FieldClassDecl->isInvalidDecl())
5303-
return;
5304-
if (FieldClassDecl->hasIrrelevantDestructor())
5305-
return;
53065312
// The destructor for an implicit anonymous union member is never invoked.
53075313
if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
53085314
return;
53095315

5310-
CXXDestructorDecl *Dtor = S.LookupDestructor(FieldClassDecl);
5311-
// Dtor might still be missing, e.g because it's invalid.
5316+
auto *Dtor = LookupDestructorIfRelevant(S, FieldClassDecl);
53125317
if (!Dtor)
53135318
return;
5319+
53145320
S.CheckDestructorAccess(Field->getLocation(), Dtor,
53155321
S.PDiag(diag::err_access_dtor_field)
53165322
<< Field->getDeclName() << FieldType);
@@ -5337,30 +5343,22 @@ static void MarkBaseDestructorsReferenced(Sema &S, SourceLocation Location,
53375343
VisitVirtualBases = false;
53385344
}
53395345

5340-
llvm::SmallPtrSet<const RecordType *, 8> DirectVirtualBases;
5346+
llvm::SmallPtrSet<const CXXRecordDecl *, 8> DirectVirtualBases;
53415347

53425348
// Bases.
53435349
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)
53465352
continue;
53475353

53485354
// Remember direct virtual bases.
53495355
if (Base.isVirtual()) {
53505356
if (!VisitVirtualBases)
53515357
continue;
5352-
DirectVirtualBases.insert(RT);
5358+
DirectVirtualBases.insert(BaseClassDecl);
53535359
}
53545360

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);
53645362
if (!Dtor)
53655363
continue;
53665364

@@ -5559,8 +5557,7 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
55595557
// C++ [class.base.init]p12:
55605558
// In a non-delegating constructor, the destructor for each
55615559
// potentially constructed subobject of class type is potentially
5562-
// invoked
5563-
// ([class.dtor]).
5560+
// invoked.
55645561
MarkFieldDestructorReferenced(*this, Location, Field);
55655562
}
55665563

@@ -5891,27 +5888,21 @@ void Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
58915888

58925889
void Sema::MarkVirtualBaseDestructorsReferenced(
58935890
SourceLocation Location, CXXRecordDecl *ClassDecl,
5894-
llvm::SmallPtrSetImpl<const RecordType *> *DirectVirtualBases) {
5891+
llvm::SmallPtrSetImpl<const CXXRecordDecl *> *DirectVirtualBases) {
58955892
// Virtual bases.
58965893
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)
59025896
continue;
59035897

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))
59095900
continue;
59105901

5911-
CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl);
5912-
// Dtor might still be missing, e.g because it's invalid.
5902+
auto *Dtor = LookupDestructorIfRelevant(*this, BaseClassDecl);
59135903
if (!Dtor)
59145904
continue;
5905+
59155906
if (CheckDestructorAccess(
59165907
ClassDecl->getLocation(), Dtor,
59175908
PDiag(diag::err_access_dtor_vbase)

0 commit comments

Comments
 (0)