summaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp112
1 files changed, 43 insertions, 69 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index bb57968830a6..63ce87b9b060 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2187,10 +2187,7 @@ static bool CheckConstexprCtorInitializer(Sema &SemaRef,
return false;
}
} else if (Field->isAnonymousStructOrUnion()) {
- const RecordDecl *RD = Field->getType()
- ->castAs<RecordType>()
- ->getOriginalDecl()
- ->getDefinitionOrSelf();
+ const auto *RD = Field->getType()->castAsRecordDecl();
for (auto *I : RD->fields())
// If an anonymous union contains an anonymous struct of which any member
// is initialized, all members must be initialized.
@@ -2925,9 +2922,7 @@ NoteIndirectBases(ASTContext &Context, IndirectBaseSet &Set,
{
// Even though the incoming type is a base, it might not be
// a class -- it could be a template parm, for instance.
- if (auto Rec = Type->getAs<RecordType>()) {
- auto Decl = Rec->getAsCXXRecordDecl();
-
+ if (const auto *Decl = Type->getAsCXXRecordDecl()) {
// Iterate over its bases.
for (const auto &BaseSpec : Decl->bases()) {
QualType Base = Context.getCanonicalType(BaseSpec.getType())
@@ -2986,9 +2981,7 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class,
if (Bases.size() > 1)
NoteIndirectBases(Context, IndirectBaseTypes, NewBaseType);
- if (const RecordType *Record = NewBaseType->getAs<RecordType>()) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getOriginalDecl())
- ->getDefinitionOrSelf();
+ if (const auto *RD = NewBaseType->getAsCXXRecordDecl()) {
if (Class->isInterface() &&
(!RD->isInterfaceLike() ||
KnownBase->getAccessSpecifier() != AS_public)) {
@@ -5479,7 +5472,8 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
CXXCtorInitializer *Member = Initializers[i];
if (Member->isBaseInitializer())
- Info.AllBaseFields[Member->getBaseClass()->getAs<RecordType>()] = Member;
+ Info.AllBaseFields[Member->getBaseClass()->getAsCanonical<RecordType>()] =
+ Member;
else {
Info.AllBaseFields[Member->getAnyMember()->getCanonicalDecl()] = Member;
@@ -5507,8 +5501,8 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
// Push virtual bases before others.
for (auto &VBase : ClassDecl->vbases()) {
- if (CXXCtorInitializer *Value
- = Info.AllBaseFields.lookup(VBase.getType()->getAs<RecordType>())) {
+ if (CXXCtorInitializer *Value = Info.AllBaseFields.lookup(
+ VBase.getType()->getAsCanonical<RecordType>())) {
// [class.base.init]p7, per DR257:
// A mem-initializer where the mem-initializer-id names a virtual base
// class is ignored during execution of a constructor of any class that
@@ -5546,8 +5540,8 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
if (Base.isVirtual())
continue;
- if (CXXCtorInitializer *Value
- = Info.AllBaseFields.lookup(Base.getType()->getAs<RecordType>())) {
+ if (CXXCtorInitializer *Value = Info.AllBaseFields.lookup(
+ Base.getType()->getAsCanonical<RecordType>())) {
Info.AllToInit.push_back(Value);
} else if (!AnyErrors) {
CXXCtorInitializer *CXXBaseInit;
@@ -5635,7 +5629,7 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
}
static void PopulateKeysForFields(FieldDecl *Field, SmallVectorImpl<const void*> &IdealInits) {
- if (const RecordType *RT = Field->getType()->getAs<RecordType>()) {
+ if (const RecordType *RT = Field->getType()->getAsCanonical<RecordType>()) {
const RecordDecl *RD = RT->getOriginalDecl();
if (RD->isAnonymousStructOrUnion()) {
for (auto *Field : RD->getDefinitionOrSelf()->fields())
@@ -7611,12 +7605,9 @@ static bool defaultedSpecialMemberIsConstexpr(
// class is a constexpr function, and
if (!S.getLangOpts().CPlusPlus23) {
for (const auto &B : ClassDecl->bases()) {
- const RecordType *BaseType = B.getType()->getAs<RecordType>();
- if (!BaseType)
+ auto *BaseClassDecl = B.getType()->getAsCXXRecordDecl();
+ if (!BaseClassDecl)
continue;
- CXXRecordDecl *BaseClassDecl =
- cast<CXXRecordDecl>(BaseType->getOriginalDecl())
- ->getDefinitionOrSelf();
if (!specialMemberIsConstexpr(S, BaseClassDecl, CSM, 0, ConstArg,
InheritedCtor, Inherited))
return false;
@@ -7638,7 +7629,7 @@ static bool defaultedSpecialMemberIsConstexpr(
F->hasInClassInitializer())
continue;
QualType BaseType = S.Context.getBaseElementType(F->getType());
- if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) {
+ if (const RecordType *RecordTy = BaseType->getAsCanonical<RecordType>()) {
CXXRecordDecl *FieldRecDecl =
cast<CXXRecordDecl>(RecordTy->getOriginalDecl())
->getDefinitionOrSelf();
@@ -10478,11 +10469,7 @@ public:
/// method overloads virtual methods in a base class without overriding any,
/// to be used with CXXRecordDecl::lookupInBases().
bool operator()(const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
- RecordDecl *BaseRecord = Specifier->getType()
- ->castAs<RecordType>()
- ->getOriginalDecl()
- ->getDefinitionOrSelf();
-
+ auto *BaseRecord = Specifier->getType()->castAsRecordDecl();
DeclarationName Name = Method->getDeclName();
assert(Name.getNameKind() == DeclarationName::Identifier);
@@ -10637,7 +10624,8 @@ void Sema::checkIllFormedTrivialABIStruct(CXXRecordDecl &RD) {
return;
}
- if (const auto *RT = FT->getBaseElementTypeUnsafe()->getAs<RecordType>())
+ if (const auto *RT =
+ FT->getBaseElementTypeUnsafe()->getAsCanonical<RecordType>())
if (!RT->isDependentType() &&
!cast<CXXRecordDecl>(RT->getOriginalDecl()->getDefinitionOrSelf())
->canPassInRegisters()) {
@@ -12640,16 +12628,17 @@ Decl *Sema::ActOnUsingEnumDeclaration(Scope *S, AccessSpecifier AS,
SourceLocation UsingLoc,
SourceLocation EnumLoc, SourceRange TyLoc,
const IdentifierInfo &II, ParsedType Ty,
- CXXScopeSpec *SS) {
- assert(SS && !SS->isInvalid() && "ScopeSpec is invalid");
+ const CXXScopeSpec &SS) {
TypeSourceInfo *TSI = nullptr;
SourceLocation IdentLoc = TyLoc.getBegin();
QualType EnumTy = GetTypeFromParser(Ty, &TSI);
if (EnumTy.isNull()) {
- Diag(IdentLoc, isDependentScopeSpecifier(*SS)
+ Diag(IdentLoc, isDependentScopeSpecifier(SS)
? diag::err_using_enum_is_dependent
: diag::err_unknown_typename)
- << II.getName() << SourceRange(SS->getBeginLoc(), TyLoc.getEnd());
+ << II.getName()
+ << SourceRange(SS.isValid() ? SS.getBeginLoc() : IdentLoc,
+ TyLoc.getEnd());
return nullptr;
}
@@ -12658,15 +12647,12 @@ Decl *Sema::ActOnUsingEnumDeclaration(Scope *S, AccessSpecifier AS,
return nullptr;
}
- auto *Enum = dyn_cast_if_present<EnumDecl>(EnumTy->getAsTagDecl());
+ auto *Enum = EnumTy->getAsEnumDecl();
if (!Enum) {
Diag(IdentLoc, diag::err_using_enum_not_enum) << EnumTy;
return nullptr;
}
- if (auto *Def = Enum->getDefinition())
- Enum = Def;
-
if (TSI == nullptr)
TSI = Context.getTrivialTypeSourceInfo(EnumTy, IdentLoc);
@@ -13937,12 +13923,10 @@ struct SpecialMemberExceptionSpecInfo
}
bool SpecialMemberExceptionSpecInfo::visitBase(CXXBaseSpecifier *Base) {
- auto *RT = Base->getType()->getAs<RecordType>();
- if (!RT)
+ auto *BaseClass = Base->getType()->getAsCXXRecordDecl();
+ if (!BaseClass)
return false;
- auto *BaseClass =
- cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
Sema::SpecialMemberOverloadResult SMOR = lookupInheritedCtor(BaseClass);
if (auto *BaseCtor = SMOR.getMethod()) {
visitSubobjectCall(Base, BaseCtor);
@@ -13966,11 +13950,9 @@ bool SpecialMemberExceptionSpecInfo::visitField(FieldDecl *FD) {
E = S.BuildCXXDefaultInitExpr(Loc, FD).get();
if (E)
ExceptSpec.CalledExpr(E);
- } else if (auto *RT = S.Context.getBaseElementType(FD->getType())
- ->getAs<RecordType>()) {
- visitClassSubobject(
- cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf(), FD,
- FD->getType().getCVRQualifiers());
+ } else if (auto *RD = S.Context.getBaseElementType(FD->getType())
+ ->getAsCXXRecordDecl()) {
+ visitClassSubobject(RD, FD, FD->getType().getCVRQualifiers());
}
return false;
}
@@ -14785,11 +14767,9 @@ buildMemcpyForAssignmentOp(Sema &S, SourceLocation Loc, QualType T,
S.Context, To, UO_AddrOf, S.Context.getPointerType(To->getType()),
VK_PRValue, OK_Ordinary, Loc, false, S.CurFPFeatureOverrides());
- const Type *E = T->getBaseElementTypeUnsafe();
- bool NeedsCollectableMemCpy = E->isRecordType() && E->castAs<RecordType>()
- ->getOriginalDecl()
- ->getDefinitionOrSelf()
- ->hasObjectMember();
+ bool NeedsCollectableMemCpy = false;
+ if (auto *RD = T->getBaseElementTypeUnsafe()->getAsRecordDecl())
+ NeedsCollectableMemCpy = RD->hasObjectMember();
// Create a reference to the __builtin_objc_memmove_collectable function
StringRef MemCpyName = NeedsCollectableMemCpy ?
@@ -14865,10 +14845,7 @@ buildSingleCopyAssignRecursively(Sema &S, SourceLocation Loc, QualType T,
// the class is used (as if by explicit qualification; that is,
// ignoring any possible virtual overriding functions in more derived
// classes);
- if (const RecordType *RecordTy = T->getAs<RecordType>()) {
- CXXRecordDecl *ClassDecl =
- cast<CXXRecordDecl>(RecordTy->getOriginalDecl())->getDefinitionOrSelf();
-
+ if (auto *ClassDecl = T->getAsCXXRecordDecl()) {
// Look for operator=.
DeclarationName Name
= S.Context.DeclarationNames.getCXXOperatorName(OO_Equal);
@@ -15340,7 +15317,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
// Check for members of const-qualified, non-class type.
QualType BaseType = Context.getBaseElementType(Field->getType());
- if (!BaseType->getAs<RecordType>() && BaseType.isConstQualified()) {
+ if (!BaseType->isRecordType() && BaseType.isConstQualified()) {
Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign)
<< Context.getCanonicalTagType(ClassDecl) << 1
<< Field->getDeclName();
@@ -15729,7 +15706,7 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation,
// Check for members of const-qualified, non-class type.
QualType BaseType = Context.getBaseElementType(Field->getType());
- if (!BaseType->getAs<RecordType>() && BaseType.isConstQualified()) {
+ if (!BaseType->isRecordType() && BaseType.isConstQualified()) {
Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign)
<< Context.getCanonicalTagType(ClassDecl) << 1
<< Field->getDeclName();
@@ -16322,15 +16299,14 @@ ExprResult Sema::BuildCXXConstructExpr(
Constructor);
}
-void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) {
+void Sema::FinalizeVarWithDestructor(VarDecl *VD, CXXRecordDecl *ClassDecl) {
if (VD->isInvalidDecl()) return;
// If initializing the variable failed, don't also diagnose problems with
// the destructor, they're likely related.
if (VD->getInit() && VD->getInit()->containsErrors())
return;
- CXXRecordDecl *ClassDecl =
- cast<CXXRecordDecl>(Record->getOriginalDecl())->getDefinitionOrSelf();
+ ClassDecl = ClassDecl->getDefinitionOrSelf();
if (ClassDecl->isInvalidDecl()) return;
if (ClassDecl->hasIrrelevantDestructor()) return;
if (ClassDecl->isDependentContext()) return;
@@ -16988,9 +16964,9 @@ checkLiteralOperatorTemplateParameterList(Sema &SemaRef,
// first template parameter as its type.
if (PmType && PmArgs && !PmType->isTemplateParameterPack() &&
PmArgs->isTemplateParameterPack()) {
- const TemplateTypeParmType *TArgs =
- PmArgs->getType()->getAs<TemplateTypeParmType>();
- if (TArgs && TArgs->getDepth() == PmType->getDepth() &&
+ if (const auto *TArgs =
+ PmArgs->getType()->getAsCanonical<TemplateTypeParmType>();
+ TArgs && TArgs->getDepth() == PmType->getDepth() &&
TArgs->getIndex() == PmType->getIndex()) {
if (!SemaRef.inTemplateInstantiation())
SemaRef.Diag(TpDecl->getLocation(),
@@ -17337,7 +17313,7 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo,
Invalid = true;
if (!Invalid && !ExDeclType->isDependentType()) {
- if (const RecordType *recordType = ExDeclType->getAs<RecordType>()) {
+ if (auto *ClassDecl = ExDeclType->getAsCXXRecordDecl()) {
// Insulate this from anything else we might currently be parsing.
EnterExpressionEvaluationContext scope(
*this, ExpressionEvaluationContext::PotentiallyEvaluated);
@@ -17374,7 +17350,7 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo,
}
// And make sure it's destructable.
- FinalizeVarWithDestructor(ExDecl, recordType);
+ FinalizeVarWithDestructor(ExDecl, ClassDecl);
}
}
}
@@ -18813,8 +18789,8 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
// that of B::f, the class type in the return type of D::f shall be
// complete at the point of declaration of D::f or shall be the class
// type D.
- if (const RecordType *RT = NewClassTy->getAs<RecordType>()) {
- if (!RT->getOriginalDecl()->isEntityBeingDefined() &&
+ if (const auto *RD = NewClassTy->getAsCXXRecordDecl()) {
+ if (!RD->isBeingDefined() &&
RequireCompleteType(New->getLocation(), NewClassTy,
diag::err_covariant_return_incomplete,
New->getDeclName()))
@@ -19169,9 +19145,7 @@ void Sema::MarkVirtualMembersReferenced(SourceLocation Loc,
return;
for (const auto &I : RD->bases()) {
- const auto *Base = cast<CXXRecordDecl>(
- I.getType()->castAs<RecordType>()->getOriginalDecl())
- ->getDefinitionOrSelf();
+ const auto *Base = I.getType()->castAsCXXRecordDecl();
if (Base->getNumVBases() == 0)
continue;
MarkVirtualMembersReferenced(Loc, Base);