diff --git a/clang-tools-extra/clang-tidy/bugprone/TaggedUnionMemberCountCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/TaggedUnionMemberCountCheck.cpp index ddbb14e3ac62b..02f4421efdbf4 100644 --- a/clang-tools-extra/clang-tidy/bugprone/TaggedUnionMemberCountCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/TaggedUnionMemberCountCheck.cpp @@ -169,15 +169,8 @@ void TaggedUnionMemberCountCheck::check( if (!Root || !UnionField || !TagField) return; - const auto *UnionDef = - UnionField->getType().getCanonicalType().getTypePtr()->getAsRecordDecl(); - const auto *EnumDef = llvm::dyn_cast( - TagField->getType().getCanonicalType().getTypePtr()->getAsTagDecl()); - - assert(UnionDef && "UnionDef is missing!"); - assert(EnumDef && "EnumDef is missing!"); - if (!UnionDef || !EnumDef) - return; + const auto *UnionDef = UnionField->getType()->castAsRecordDecl(); + const auto *EnumDef = TagField->getType()->castAsEnumDecl(); const std::size_t UnionMemberCount = llvm::range_size(UnionDef->fields()); auto [TagCount, CountingEnumConstantDecl] = getNumberOfEnumValues(EnumDef); diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp index aa6aefcf0c493..4314817e4f69d 100644 --- a/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp +++ b/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp @@ -66,10 +66,7 @@ ExceptionSpecAnalyzer::analyzeBase(const CXXBaseSpecifier &Base, if (!RecType) return State::Unknown; - const auto *BaseClass = - cast(RecType->getOriginalDecl())->getDefinitionOrSelf(); - - return analyzeRecord(BaseClass, Kind); + return analyzeRecord(RecType->getAsCXXRecordDecl(), Kind); } ExceptionSpecAnalyzer::State diff --git a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp index 0df8e913100fc..0d0834dc38fc6 100644 --- a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp +++ b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp @@ -460,10 +460,9 @@ bool FormatStringConverter::emitIntegerArgument( // be passed as its underlying type. However, printf will have forced // the signedness based on the format string, so we need to do the // same. - if (const auto *ET = ArgType->getAs()) { - if (const std::optional MaybeCastType = castTypeForArgument( - ArgKind, - ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType())) + if (const auto *ED = ArgType->getAsEnumDecl()) { + if (const std::optional MaybeCastType = + castTypeForArgument(ArgKind, ED->getIntegerType())) ArgFixes.emplace_back( ArgIndex, (Twine("static_cast<") + *MaybeCastType + ">(").str()); else diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp index af00c8948a215..30c70ac02205b 100644 --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -454,8 +454,7 @@ std::optional printExprValue(const Expr *E, Constant.Val.getInt().getSignificantBits() <= 64) { // Compare to int64_t to avoid bit-width match requirements. int64_t Val = Constant.Val.getInt().getExtValue(); - for (const EnumConstantDecl *ECD : - T->castAs()->getOriginalDecl()->enumerators()) + for (const EnumConstantDecl *ECD : T->castAsEnumDecl()->enumerators()) if (ECD->getInitVal() == Val) return llvm::formatv("{0} ({1})", ECD->getNameAsString(), printHex(Constant.Val.getInt())) @@ -832,7 +831,7 @@ std::optional getThisExprHoverContents(const CXXThisExpr *CTE, ASTContext &ASTCtx, const PrintingPolicy &PP) { QualType OriginThisType = CTE->getType()->getPointeeType(); - QualType ClassType = declaredType(OriginThisType->getAsTagDecl()); + QualType ClassType = declaredType(OriginThisType->castAsTagDecl()); // For partial specialization class, origin `this` pointee type will be // parsed as `InjectedClassNameType`, which will ouput template arguments // like "type-parameter-0-0". So we retrieve user written class type in this diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index bebbde3661a33..79636a67dafba 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -3915,6 +3915,10 @@ class TagDecl : public TypeDecl, bool isUnion() const { return getTagKind() == TagTypeKind::Union; } bool isEnum() const { return getTagKind() == TagTypeKind::Enum; } + bool isStructureOrClass() const { + return isStruct() || isClass() || isInterface(); + } + /// Is this tag type named, either directly or via being defined in /// a typedef of this type? /// diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index adf5cb0462154..187e54f5cb54b 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2883,14 +2883,21 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { /// because the type is a RecordType or because it is the injected-class-name /// type of a class template or class template partial specialization. CXXRecordDecl *getAsCXXRecordDecl() const; + CXXRecordDecl *castAsCXXRecordDecl() const; /// Retrieves the RecordDecl this type refers to. RecordDecl *getAsRecordDecl() const; + RecordDecl *castAsRecordDecl() const; + + /// Retrieves the EnumDecl this type refers to. + EnumDecl *getAsEnumDecl() const; + EnumDecl *castAsEnumDecl() const; /// Retrieves the TagDecl that this type refers to, either /// because the type is a TagType or because it is the injected-class-name /// type of a class template or class template partial specialization. TagDecl *getAsTagDecl() const; + TagDecl *castAsTagDecl() const; /// If this is a pointer or reference to a RecordType, return the /// CXXRecordDecl that the type refers to. diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index 2d62209bbc28c..7173c2a0e1a2a 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -903,8 +903,7 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy, case APValue::Struct: { Out << '{'; bool First = true; - const RecordDecl *RD = - Ty->castAs()->getOriginalDecl()->getDefinitionOrSelf(); + const auto *RD = Ty->castAsRecordDecl(); if (unsigned N = getStructNumBases()) { const CXXRecordDecl *CD = cast(RD); CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin(); diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 5fc55b2675fd2..06e7a2d5b857b 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2001,8 +2001,7 @@ bool ASTContext::isPromotableIntegerType(QualType T) const { // Enumerated types are promotable to their compatible integer types // (C99 6.3.1.1) a.k.a. its underlying type (C++ [conv.prom]p2). - if (const auto *ET = T->getAs()) { - const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + if (const auto *ED = T->getAsEnumDecl()) { if (T->isDependentType() || ED->getPromotionType().isNull() || ED->isScoped()) return false; @@ -2712,11 +2711,8 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const { // possible. if (const auto *CT = T->getAs()) T = CT->getElementType().getTypePtr(); - if (const auto *ET = T->getAs()) - T = ET->getOriginalDecl() - ->getDefinitionOrSelf() - ->getIntegerType() - .getTypePtr(); + if (const auto *ED = T->getAsEnumDecl()) + T = ED->getIntegerType().getTypePtr(); if (T->isSpecificBuiltinType(BuiltinType::Double) || T->isSpecificBuiltinType(BuiltinType::LongLong) || T->isSpecificBuiltinType(BuiltinType::ULongLong) || @@ -3412,10 +3408,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx, // type, or an unsigned integer type. // // So we have to treat enum types as integers. - QualType UnderlyingType = cast(T) - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->getIntegerType(); + QualType UnderlyingType = T->castAsEnumDecl()->getIntegerType(); return encodeTypeForFunctionPointerAuth( Ctx, OS, UnderlyingType.isNull() ? Ctx.IntTy : UnderlyingType); } @@ -8351,8 +8344,8 @@ QualType ASTContext::isPromotableBitField(Expr *E) const { QualType ASTContext::getPromotedIntegerType(QualType Promotable) const { assert(!Promotable.isNull()); assert(isPromotableIntegerType(Promotable)); - if (const auto *ET = Promotable->getAs()) - return ET->getOriginalDecl()->getDefinitionOrSelf()->getPromotionType(); + if (const auto *ED = Promotable->getAsEnumDecl()) + return ED->getPromotionType(); if (const auto *BT = Promotable->getAs()) { // C++ [conv.prom]: A prvalue of type char16_t, char32_t, or wchar_t @@ -8571,10 +8564,9 @@ QualType ASTContext::getObjCSuperType() const { } void ASTContext::setCFConstantStringType(QualType T) { - const auto *TD = T->castAs(); - CFConstantStringTypeDecl = cast(TD->getDecl()); - const auto *TagType = TD->castAs(); - CFConstantStringTagDecl = TagType->getOriginalDecl()->getDefinitionOrSelf(); + const auto *TT = T->castAs(); + CFConstantStringTypeDecl = cast(TT->getDecl()); + CFConstantStringTagDecl = TT->castAsRecordDecl(); } QualType ASTContext::getBlockDescriptorType() const { @@ -11667,9 +11659,8 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, // Look at the converted type of enum types, since that is the type used // to pass enum values. - if (const auto *Enum = paramTy->getAs()) { - paramTy = - Enum->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = paramTy->getAsEnumDecl()) { + paramTy = ED->getIntegerType(); if (paramTy.isNull()) return {}; } @@ -12260,8 +12251,8 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) { //===----------------------------------------------------------------------===// unsigned ASTContext::getIntWidth(QualType T) const { - if (const auto *ET = T->getAs()) - T = ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = T->getAsEnumDecl()) + T = ED->getIntegerType(); if (T->isBooleanType()) return 1; if (const auto *EIT = T->getAs()) @@ -12286,8 +12277,8 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const { // For enums, get the underlying integer type of the enum, and let the general // integer type signchanging code handle it. - if (const auto *ETy = T->getAs()) - T = ETy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = T->getAsEnumDecl()) + T = ED->getIntegerType(); switch (T->castAs()->getKind()) { case BuiltinType::Char_U: @@ -12360,8 +12351,8 @@ QualType ASTContext::getCorrespondingSignedType(QualType T) const { // For enums, get the underlying integer type of the enum, and let the general // integer type signchanging code handle it. - if (const auto *ETy = T->getAs()) - T = ETy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = T->getAsEnumDecl()) + T = ED->getIntegerType(); switch (T->castAs()->getKind()) { case BuiltinType::Char_S: diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index e61d5e085a036..cb1a6b7eda93a 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -559,8 +559,7 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { // Possibly diagnose casts to enum types if the target type does not // have a fixed size. if (Ctx.getLangOpts().CPlusPlus && CE->getType()->isEnumeralType()) { - const auto *ET = CE->getType().getCanonicalType()->castAs(); - const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + const auto *ED = CE->getType()->castAsEnumDecl(); if (!ED->isFixed()) { if (!this->emitCheckEnumValue(*FromT, ED, CE)) return false; diff --git a/clang/lib/AST/ByteCode/Context.cpp b/clang/lib/AST/ByteCode/Context.cpp index 36eb7607e70bf..fbbb508ed226c 100644 --- a/clang/lib/AST/ByteCode/Context.cpp +++ b/clang/lib/AST/ByteCode/Context.cpp @@ -364,8 +364,7 @@ OptPrimType Context::classify(QualType T) const { return integralTypeToPrimTypeU(BT->getNumBits()); } - if (const auto *ET = T->getAs()) { - const auto *D = ET->getOriginalDecl()->getDefinitionOrSelf(); + if (const auto *D = T->getAsEnumDecl()) { if (!D->isComplete()) return std::nullopt; return classify(D->getIntegerType()); diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp index 139cae7afc87e..0892d1dc36595 100644 --- a/clang/lib/AST/ByteCode/Program.cpp +++ b/clang/lib/AST/ByteCode/Program.cpp @@ -347,11 +347,7 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) { } for (const CXXBaseSpecifier &Spec : CD->vbases()) { - const auto *RT = Spec.getType()->getAs(); - if (!RT) - return nullptr; - - const RecordDecl *BD = RT->getOriginalDecl()->getDefinitionOrSelf(); + const auto *BD = Spec.getType()->castAsCXXRecordDecl(); const Record *BR = getOrCreateRecord(BD); const Descriptor *Desc = GetBaseDesc(BD, BR); diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp index 0ced210900b1a..94f01c86a16ca 100644 --- a/clang/lib/AST/CXXInheritance.cpp +++ b/clang/lib/AST/CXXInheritance.cpp @@ -263,7 +263,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context, BaseRecord = nullptr; } } else { - BaseRecord = cast(BaseSpec.getType()->getAsRecordDecl()); + BaseRecord = BaseSpec.getType()->castAsCXXRecordDecl(); } if (BaseRecord && lookupInBases(Context, BaseRecord, BaseMatches, LookupInDependent)) { @@ -327,10 +327,7 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches, if (!PE.Base->isVirtual()) continue; - CXXRecordDecl *VBase = nullptr; - if (const RecordType *Record = PE.Base->getType()->getAs()) - VBase = cast(Record->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *VBase = PE.Base->getType()->getAsCXXRecordDecl(); if (!VBase) break; @@ -396,7 +393,7 @@ bool CXXRecordDecl::hasMemberName(DeclarationName Name) const { CXXBasePaths Paths(false, false, false); return lookupInBases( [Name](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { - return findOrdinaryMember(Specifier->getType()->getAsCXXRecordDecl(), + return findOrdinaryMember(Specifier->getType()->castAsCXXRecordDecl(), Path, Name); }, Paths); diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 62eb4de8c6a96..86d3b136ce0b5 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -216,9 +216,7 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, // Skip dependent types; we can't do any checking on them now. if (BaseType->isDependentType()) continue; - auto *BaseClassDecl = - cast(BaseType->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *BaseClassDecl = BaseType->castAsCXXRecordDecl(); // C++2a [class]p7: // A standard-layout class is a class that: @@ -3432,13 +3430,12 @@ SourceRange UsingDecl::getSourceRange() const { void UsingEnumDecl::anchor() {} UsingEnumDecl *UsingEnumDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation UL, - SourceLocation EL, + SourceLocation UL, SourceLocation EL, SourceLocation NL, TypeSourceInfo *EnumType) { - assert(isa(EnumType->getType()->getAsTagDecl())); return new (C, DC) - UsingEnumDecl(DC, EnumType->getType()->getAsTagDecl()->getDeclName(), UL, EL, NL, EnumType); + UsingEnumDecl(DC, EnumType->getType()->castAsEnumDecl()->getDeclName(), + UL, EL, NL, EnumType); } UsingEnumDecl *UsingEnumDecl::CreateDeserialized(ASTContext &C, diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 9d1490c2ef834..072d07cb81179 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -74,8 +74,7 @@ const CXXRecordDecl *Expr::getBestDynamicClassType() const { if (DerivedType->isDependentType()) return nullptr; - const RecordType *Ty = DerivedType->castAs(); - return cast(Ty->getOriginalDecl())->getDefinitionOrSelf(); + return DerivedType->castAsCXXRecordDecl(); } const Expr *Expr::skipRValueSubobjectAdjustments( @@ -90,10 +89,7 @@ const Expr *Expr::skipRValueSubobjectAdjustments( CE->getCastKind() == CK_UncheckedDerivedToBase) && E->getType()->isRecordType()) { E = CE->getSubExpr(); - const auto *Derived = - cast( - E->getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *Derived = E->getType()->castAsCXXRecordDecl(); Adjustments.push_back(SubobjectAdjustment(CE, Derived)); continue; } @@ -2032,9 +2028,7 @@ CXXBaseSpecifier **CastExpr::path_buffer() { const FieldDecl *CastExpr::getTargetFieldForToUnionCast(QualType unionType, QualType opType) { - auto RD = - unionType->castAs()->getOriginalDecl()->getDefinitionOrSelf(); - return getTargetFieldForToUnionCast(RD, opType); + return getTargetFieldForToUnionCast(unionType->castAsRecordDecl(), opType); } const FieldDecl *CastExpr::getTargetFieldForToUnionCast(const RecordDecl *RD, @@ -3396,10 +3390,7 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef, if (ILE->getType()->isRecordType()) { unsigned ElementNo = 0; - RecordDecl *RD = ILE->getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *RD = ILE->getType()->castAsRecordDecl(); // In C++17, bases were added to the list of members used by aggregate // initialization. diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index ee0ac4effab0e..107ce47b8a599 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2614,8 +2614,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, Value.getUnionValue(), Kind, Value.getUnionField(), CheckedTemps); } if (Value.isStruct()) { - RecordDecl *RD = - Type->castAs()->getOriginalDecl()->getDefinitionOrSelf(); + auto *RD = Type->castAsRecordDecl(); if (const CXXRecordDecl *CD = dyn_cast(RD)) { unsigned BaseIndex = 0; for (const CXXBaseSpecifier &BS : CD->bases()) { @@ -10769,8 +10768,7 @@ static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, } bool RecordExprEvaluator::ZeroInitialization(const Expr *E, QualType T) { - const RecordDecl *RD = - T->castAs()->getOriginalDecl()->getDefinitionOrSelf(); + const auto *RD = T->castAsRecordDecl(); if (RD->isInvalidDecl()) return false; if (RD->isUnion()) { // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the @@ -10839,10 +10837,7 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) { bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr( const Expr *ExprToVisit, ArrayRef Args) { - const RecordDecl *RD = ExprToVisit->getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + const auto *RD = ExprToVisit->getType()->castAsRecordDecl(); if (RD->isInvalidDecl()) return false; const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD); auto *CXXRD = dyn_cast(RD); @@ -11066,10 +11061,7 @@ bool RecordExprEvaluator::VisitCXXStdInitializerListExpr( Result = APValue(APValue::UninitStruct(), 0, 2); Array.moveInto(Result.getStructField(0)); - RecordDecl *Record = E->getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *Record = E->getType()->castAsRecordDecl(); RecordDecl::field_iterator Field = Record->field_begin(); assert(Field != Record->field_end() && Info.Ctx.hasSameType(Field->getType()->getPointeeType(), @@ -13113,10 +13105,7 @@ static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T, const LValue &LV, CharUnits &Size) { if (!T.isNull() && T->isStructureType() && - T->getAsStructureType() - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->hasFlexibleArrayMember()) + T->castAsRecordDecl()->hasFlexibleArrayMember()) if (const auto *V = LV.getLValueBase().dyn_cast()) if (const auto *VD = dyn_cast(V)) if (VD->hasInit()) @@ -15619,8 +15608,7 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) { } if (Info.Ctx.getLangOpts().CPlusPlus && DestType->isEnumeralType()) { - const EnumType *ET = dyn_cast(DestType.getCanonicalType()); - const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + const auto *ED = DestType->getAsEnumDecl(); // Check that the value is within the range of the enumeration values. // // This corressponds to [expr.static.cast]p10 which says: diff --git a/clang/lib/AST/FormatString.cpp b/clang/lib/AST/FormatString.cpp index a73c02734e558..d4cb89b43ae87 100644 --- a/clang/lib/AST/FormatString.cpp +++ b/clang/lib/AST/FormatString.cpp @@ -413,14 +413,13 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const { return Match; case AnyCharTy: { - if (const auto *ETy = argTy->getAs()) { + if (const auto *ED = argTy->getAsEnumDecl()) { // If the enum is incomplete we know nothing about the underlying type. // Assume that it's 'int'. Do not use the underlying type for a scoped // enumeration. - const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf(); if (!ED->isComplete()) return NoMatch; - if (ETy->isUnscopedEnumerationType()) + if (!ED->isScoped()) argTy = ED->getIntegerType(); } @@ -463,14 +462,13 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const { return matchesSizeTPtrdiffT(C, argTy, T); } - if (const EnumType *ETy = argTy->getAs()) { + if (const auto *ED = argTy->getAsEnumDecl()) { // If the enum is incomplete we know nothing about the underlying type. // Assume that it's 'int'. Do not use the underlying type for a scoped // enumeration as that needs an exact match. - const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf(); if (!ED->isComplete()) argTy = C.IntTy; - else if (ETy->isUnscopedEnumerationType()) + else if (!ED->isScoped()) argTy = ED->getIntegerType(); } diff --git a/clang/lib/AST/ItaniumCXXABI.cpp b/clang/lib/AST/ItaniumCXXABI.cpp index 43a8bcd9443ff..adef1584fd9b6 100644 --- a/clang/lib/AST/ItaniumCXXABI.cpp +++ b/clang/lib/AST/ItaniumCXXABI.cpp @@ -42,8 +42,7 @@ namespace { /// /// Returns the name of anonymous union VarDecl or nullptr if it is not found. static const IdentifierInfo *findAnonymousUnionVarDeclName(const VarDecl& VD) { - const auto *RT = VD.getType()->castAs(); - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + const auto *RD = VD.getType()->castAsRecordDecl(); assert(RD->isUnion() && "RecordType is expected to be a union."); if (const FieldDecl *FD = RD->findFirstNamedDataMember()) { return FD->getIdentifier(); diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index c7eaad47710df..1ba224b74a606 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -1580,10 +1580,7 @@ void CXXNameMangler::mangleUnqualifiedName( if (const VarDecl *VD = dyn_cast(ND)) { // We must have an anonymous union or struct declaration. - const RecordDecl *RD = VD->getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + const auto *RD = VD->getType()->castAsRecordDecl(); // Itanium C++ ABI 5.1.2: // diff --git a/clang/lib/AST/PrintfFormatString.cpp b/clang/lib/AST/PrintfFormatString.cpp index 687160c6116be..855550475721a 100644 --- a/clang/lib/AST/PrintfFormatString.cpp +++ b/clang/lib/AST/PrintfFormatString.cpp @@ -793,8 +793,8 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, } // If it's an enum, get its underlying type. - if (const EnumType *ETy = QT->getAs()) - QT = ETy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = QT->getAsEnumDecl()) + QT = ED->getIntegerType(); const BuiltinType *BT = QT->getAs(); if (!BT) { diff --git a/clang/lib/AST/ScanfFormatString.cpp b/clang/lib/AST/ScanfFormatString.cpp index 31c001d025fea..41cf71a3e042d 100644 --- a/clang/lib/AST/ScanfFormatString.cpp +++ b/clang/lib/AST/ScanfFormatString.cpp @@ -430,9 +430,8 @@ bool ScanfSpecifier::fixType(QualType QT, QualType RawQT, QualType PT = QT->getPointeeType(); // If it's an enum, get its underlying type. - if (const EnumType *ETy = PT->getAs()) { + if (const auto *ED = PT->getAsEnumDecl()) { // Don't try to fix incomplete enums. - const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf(); if (!ED->isComplete()) return false; PT = ED->getIntegerType(); diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index 76050ceeb35a7..76f96fb8c5dcc 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -56,8 +56,8 @@ static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out, const llvm::APSInt &Val = TemplArg.getAsIntegral(); if (Policy.UseEnumerators) { - if (const EnumType *ET = T->getAs()) { - for (const EnumConstantDecl *ECD : ET->getOriginalDecl()->enumerators()) { + if (const auto *ED = T->getAsEnumDecl()) { + for (const EnumConstantDecl *ECD : ED->enumerators()) { // In Sema::CheckTemplateArugment, enum template arguments value are // extended to the size of the integer underlying the enum type. This // may create a size difference between the enum value and template diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 63d808f631591..b0f865bab5d77 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -685,17 +685,15 @@ bool Type::isStructureTypeWithFlexibleArrayMember() const { const auto *RT = getAs(); if (!RT) return false; - const auto *Decl = RT->getOriginalDecl()->getDefinitionOrSelf(); + const auto *Decl = RT->getOriginalDecl(); if (!Decl->isStruct()) return false; - return Decl->hasFlexibleArrayMember(); + return Decl->getDefinitionOrSelf()->hasFlexibleArrayMember(); } bool Type::isObjCBoxableRecordType() const { - if (const auto *RT = getAs()) - return RT->getOriginalDecl() - ->getDefinitionOrSelf() - ->hasAttr(); + if (const auto *RD = getAsRecordDecl()) + return RD->hasAttr(); return false; } @@ -1918,12 +1916,7 @@ const CXXRecordDecl *Type::getPointeeCXXRecordDecl() const { PointeeType = RT->getPointeeType(); else return nullptr; - - if (const auto *RT = PointeeType->getAs()) - return dyn_cast( - RT->getOriginalDecl()->getDefinitionOrSelf()); - - return nullptr; + return PointeeType->getAsCXXRecordDecl(); } CXXRecordDecl *Type::getAsCXXRecordDecl() const { @@ -1936,6 +1929,11 @@ CXXRecordDecl *Type::getAsCXXRecordDecl() const { return cast(TD)->getDefinitionOrSelf(); } +CXXRecordDecl *Type::castAsCXXRecordDecl() const { + const auto *TT = cast(CanonicalType); + return cast(TT->getOriginalDecl())->getDefinitionOrSelf(); +} + RecordDecl *Type::getAsRecordDecl() const { const auto *TT = dyn_cast(CanonicalType); if (!isa_and_present(TT)) @@ -1943,12 +1941,33 @@ RecordDecl *Type::getAsRecordDecl() const { return cast(TT->getOriginalDecl())->getDefinitionOrSelf(); } +RecordDecl *Type::castAsRecordDecl() const { + const auto *TT = cast(CanonicalType); + return cast(TT->getOriginalDecl())->getDefinitionOrSelf(); +} + +EnumDecl *Type::getAsEnumDecl() const { + if (const auto *TT = dyn_cast(CanonicalType)) + return TT->getOriginalDecl()->getDefinitionOrSelf(); + return nullptr; +} + +EnumDecl *Type::castAsEnumDecl() const { + return cast(CanonicalType) + ->getOriginalDecl() + ->getDefinitionOrSelf(); +} + TagDecl *Type::getAsTagDecl() const { if (const auto *TT = dyn_cast(CanonicalType)) return TT->getOriginalDecl()->getDefinitionOrSelf(); return nullptr; } +TagDecl *Type::castAsTagDecl() const { + return cast(CanonicalType)->getOriginalDecl()->getDefinitionOrSelf(); +} + const TemplateSpecializationType * Type::getAsNonAliasTemplateSpecializationType() const { const auto *TST = getAs(); @@ -2242,10 +2261,9 @@ bool Type::isSignedIntegerType() const { if (const auto *BT = dyn_cast(CanonicalType)) return BT->isSignedInteger(); - if (const EnumType *ET = dyn_cast(CanonicalType)) { + if (const auto *ED = getAsEnumDecl()) { // Incomplete enum types are not treated as integer types. // FIXME: In C++, enum types are never integer types. - const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); if (!ED->isComplete() || ED->isScoped()) return false; return ED->getIntegerType()->isSignedIntegerType(); @@ -2263,8 +2281,7 @@ bool Type::isSignedIntegerOrEnumerationType() const { if (const auto *BT = dyn_cast(CanonicalType)) return BT->isSignedInteger(); - if (const auto *ET = dyn_cast(CanonicalType)) { - const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + if (const auto *ED = getAsEnumDecl()) { if (!ED->isComplete()) return false; return ED->getIntegerType()->isSignedIntegerType(); @@ -2292,10 +2309,9 @@ bool Type::isUnsignedIntegerType() const { if (const auto *BT = dyn_cast(CanonicalType)) return BT->isUnsignedInteger(); - if (const auto *ET = dyn_cast(CanonicalType)) { + if (const auto *ED = getAsEnumDecl()) { // Incomplete enum types are not treated as integer types. // FIXME: In C++, enum types are never integer types. - const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); if (!ED->isComplete() || ED->isScoped()) return false; return ED->getIntegerType()->isUnsignedIntegerType(); @@ -2313,8 +2329,7 @@ bool Type::isUnsignedIntegerOrEnumerationType() const { if (const auto *BT = dyn_cast(CanonicalType)) return BT->isUnsignedInteger(); - if (const auto *ET = dyn_cast(CanonicalType)) { - const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + if (const auto *ED = getAsEnumDecl()) { if (!ED->isComplete()) return false; return ED->getIntegerType()->isUnsignedIntegerType(); @@ -2394,10 +2409,8 @@ bool Type::isArithmeticType() const { bool Type::hasBooleanRepresentation() const { if (const auto *VT = dyn_cast(CanonicalType)) return VT->getElementType()->isBooleanType(); - if (const auto *ET = dyn_cast(CanonicalType)) { - const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + if (const auto *ED = getAsEnumDecl()) return ED->isComplete() && ED->getIntegerType()->isBooleanType(); - } if (const auto *IT = dyn_cast(CanonicalType)) return IT->getNumBits() == 1; return isBooleanType(); @@ -2428,10 +2441,7 @@ Type::ScalarTypeKind Type::getScalarTypeKind() const { } else if (isa(T)) { return STK_MemberPointer; } else if (isa(T)) { - assert(cast(T) - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->isComplete()); + assert(T->castAsEnumDecl()->isComplete()); return STK_Integral; } else if (const auto *CT = dyn_cast(T)) { if (CT->getElementType()->isRealFloatingType()) @@ -2490,8 +2500,7 @@ bool Type::isIncompleteType(NamedDecl **Def) const { // be completed. return isVoidType(); case Enum: { - EnumDecl *EnumD = - cast(CanonicalType)->getOriginalDecl()->getDefinitionOrSelf(); + auto *EnumD = castAsEnumDecl(); if (Def) *Def = EnumD; return !EnumD->isComplete(); @@ -2499,17 +2508,13 @@ bool Type::isIncompleteType(NamedDecl **Def) const { case Record: { // A tagged type (struct/union/enum/class) is incomplete if the decl is a // forward declaration, but not a full definition (C99 6.2.5p22). - RecordDecl *Rec = cast(CanonicalType) - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *Rec = castAsRecordDecl(); if (Def) *Def = Rec; return !Rec->isCompleteDefinition(); } case InjectedClassName: { - CXXRecordDecl *Rec = cast(CanonicalType) - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *Rec = castAsCXXRecordDecl(); if (!Rec->isBeingDefined()) return false; if (Def) diff --git a/clang/lib/AST/VTTBuilder.cpp b/clang/lib/AST/VTTBuilder.cpp index 85101aee97e66..89b58b557ddca 100644 --- a/clang/lib/AST/VTTBuilder.cpp +++ b/clang/lib/AST/VTTBuilder.cpp @@ -63,11 +63,7 @@ void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) { if (I.isVirtual()) continue; - const auto *BaseDecl = - cast( - I.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); - + const auto *BaseDecl = I.getType()->castAsCXXRecordDecl(); const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); CharUnits BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl); @@ -91,10 +87,7 @@ VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, return; for (const auto &I : RD->bases()) { - const auto *BaseDecl = - cast( - I.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *BaseDecl = I.getType()->castAsCXXRecordDecl(); // Itanium C++ ABI 2.6.2: // Secondary virtual pointers are present for all bases with either @@ -157,10 +150,7 @@ VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD, VisitedVirtualBasesSetTy &VBases) { for (const auto &I : RD->bases()) { - const auto *BaseDecl = - cast( - I.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *BaseDecl = I.getType()->castAsCXXRecordDecl(); // Check if this is a virtual base. if (I.isVirtual()) { diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index 8a15e5f96aea2..25859885296fa 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -287,10 +287,7 @@ void CIRGenFunction::emitDelegateCallArg(CallArgList &args, // Deactivate the cleanup for the callee-destructed param that was pushed. assert(!cir::MissingFeatures::thunks()); if (type->isRecordType() && - type->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->isParamDestroyedInCallee() && + type->castAsRecordDecl()->isParamDestroyedInCallee() && param->needsDestruction(getContext())) { cgm.errorNYI(param->getSourceRange(), "emitDelegateCallArg: callee-destructed param"); @@ -690,10 +687,8 @@ void CIRGenFunction::emitCallArg(CallArgList &args, const clang::Expr *e, // In the Microsoft C++ ABI, aggregate arguments are destructed by the callee. // However, we still have to push an EH-only cleanup in case we unwind before // we make it to the call. - if (argType->isRecordType() && argType->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->isParamDestroyedInCallee()) { + if (argType->isRecordType() && + argType->castAsRecordDecl()->isParamDestroyedInCallee()) { assert(!cir::MissingFeatures::msabi()); cgm.errorNYI(e->getSourceRange(), "emitCallArg: msabi is NYI"); } diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp index 3e5dc22426d8e..722027aa5631d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp @@ -120,9 +120,7 @@ static void emitMemberInitializer(CIRGenFunction &cgf, static bool isInitializerOfDynamicClass(const CXXCtorInitializer *baseInit) { const Type *baseType = baseInit->getBaseClass(); - const auto *baseClassDecl = - cast(baseType->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *baseClassDecl = baseType->castAsCXXRecordDecl(); return baseClassDecl->isDynamicClass(); } @@ -161,9 +159,7 @@ void CIRGenFunction::emitBaseInitializer(mlir::Location loc, Address thisPtr = loadCXXThisAddress(); const Type *baseType = baseInit->getBaseClass(); - const auto *baseClassDecl = - cast(baseType->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *baseClassDecl = baseType->castAsCXXRecordDecl(); bool isBaseVirtual = baseInit->isBaseVirtual(); @@ -568,9 +564,7 @@ void CIRGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &args) { void CIRGenFunction::destroyCXXObject(CIRGenFunction &cgf, Address addr, QualType type) { - const RecordType *rtype = type->castAs(); - const CXXRecordDecl *record = - cast(rtype->getOriginalDecl())->getDefinitionOrSelf(); + const auto *record = type->castAsCXXRecordDecl(); const CXXDestructorDecl *dtor = record->getDestructor(); // TODO(cir): Unlike traditional codegen, CIRGen should actually emit trivial // dtors which shall be removed on later CIR passes. However, only remove this diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index d679e1c1ff732..1afac6dd52c2d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -1092,11 +1092,7 @@ LValue CIRGenFunction::emitCastLValue(const CastExpr *e) { case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { - const auto *derivedClassTy = - e->getSubExpr()->getType()->castAs(); - auto *derivedClassDecl = - cast(derivedClassTy->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *derivedClassDecl = e->getSubExpr()->getType()->castAsCXXRecordDecl(); LValue lv = emitLValue(e->getSubExpr()); Address thisAddr = lv.getAddress(); diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp index 2a3c98c458256..bab9ac73d7e65 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp @@ -409,10 +409,7 @@ void AggExprEmitter::visitCXXParenListOrInitListExpr( // the disadvantage is that the generated code is more difficult for // the optimizer, especially with bitfields. unsigned numInitElements = args.size(); - RecordDecl *record = e->getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *record = e->getType()->castAsRecordDecl(); // We'll need to enter cleanup scopes in case any of the element // initializers throws an exception. diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index 23132eae3214e..262d2548d5c39 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -680,9 +680,7 @@ mlir::Attribute ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &d) { // assignments and whatnots). Since this is for globals shouldn't // be a problem for the near future. if (cd->isTrivial() && cd->isDefaultConstructor()) { - const auto *cxxrd = - cast(ty->getAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *cxxrd = ty->castAsCXXRecordDecl(); if (cxxrd->getNumBases() != 0) { // There may not be anything additional to do here, but this will // force us to pause and test this path when it is supported. diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 08b40e08c51de..c7f548498c5cb 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -2180,10 +2180,7 @@ CharUnits CIRGenModule::computeNonVirtualBaseClassOffset( // Get the layout. const ASTRecordLayout &layout = astContext.getASTRecordLayout(rd); - const auto *baseDecl = - cast( - base->getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *baseDecl = base->getType()->castAsCXXRecordDecl(); // Add the offset. offset += layout.getBaseClassOffset(baseDecl); diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index 44b631934ffaf..bb24933a22ed7 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -246,10 +246,7 @@ mlir::Type CIRGenTypes::convertRecordDeclType(const clang::RecordDecl *rd) { for (const auto &base : cxxRecordDecl->bases()) { if (base.isVirtual()) continue; - convertRecordDeclType(base.getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf()); + convertRecordDeclType(base.getType()->castAsRecordDecl()); } } @@ -465,8 +462,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) { } case Type::Enum: { - const EnumDecl *ed = - cast(ty)->getOriginalDecl()->getDefinitionOrSelf(); + const auto *ed = ty->castAsEnumDecl(); if (auto integerType = ed->getIntegerType(); !integerType.isNull()) return convertType(integerType); // Return a placeholder 'i32' type. This can be changed later when the diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index 989a3a4387cf4..72d359e4862b9 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -28,8 +28,8 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const { } // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); ASTContext &Context = getContext(); if (const auto *EIT = Ty->getAs()) @@ -52,8 +52,8 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const { return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace()); // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = RetTy->getAsEnumDecl()) + RetTy = ED->getIntegerType(); if (const auto *EIT = RetTy->getAs()) if (EIT->getNumBits() > diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp index c7f4bf8a21354..5090a0559eab2 100644 --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -1131,8 +1131,7 @@ void CGNVCUDARuntime::handleVarRegistration(const VarDecl *D, // Builtin surfaces and textures and their template arguments are // also registered with CUDA runtime. const auto *TD = cast( - D->getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + D->getType()->castAsCXXRecordDecl()); const TemplateArgumentList &Args = TD->getTemplateArgs(); if (TD->hasAttr()) { assert(Args.size() == 2 && diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index f9aff893eb0f0..59aeff6804b61 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -83,9 +83,7 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) { if (I.isVirtual()) continue; // Skip base classes with trivial destructors. - const auto *Base = cast( - I.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *Base = I.getType()->castAsCXXRecordDecl(); if (Base->hasTrivialDestructor()) continue; // If we've already found a base class with a non-trivial @@ -281,16 +279,8 @@ static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF, CGCallee CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD, NestedNameSpecifier Qual, llvm::Type *Ty) { - assert(Qual.getKind() == NestedNameSpecifier::Kind::Type && - "BuildAppleKextVirtualCall - bad Qual kind"); - - const Type *QTy = Qual.getAsType(); - QualType T = QualType(QTy, 0); - const RecordType *RT = T->getAs(); - assert(RT && "BuildAppleKextVirtualCall - Qual type must be record"); - const auto *RD = - cast(RT->getOriginalDecl())->getDefinitionOrSelf(); - + const CXXRecordDecl *RD = Qual.getAsRecordDecl(); + assert(RD && "BuildAppleKextVirtualCall - Qual must be record"); if (const auto *DD = dyn_cast(MD)) return BuildAppleKextVirtualDestructorCall(DD, Dtor_Complete, RD); diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 89eb6d2b393a3..f61d3d987b3c9 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2873,10 +2873,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, // whose destruction / clean-up is carried out within the callee // (e.g., Obj-C ARC-managed structs, MSVC callee-destroyed objects). if (!ParamType.isDestructedType() || !ParamType->isRecordType() || - ParamType->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->isParamDestroyedInCallee()) + ParamType->castAsRecordDecl()->isParamDestroyedInCallee()) Attrs.addAttribute(llvm::Attribute::DeadOnReturn); } } @@ -4307,10 +4304,7 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args, // Deactivate the cleanup for the callee-destructed param that was pushed. if (type->isRecordType() && !CurFuncIsThunk && - type->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->isParamDestroyedInCallee() && + type->castAsRecordDecl()->isParamDestroyedInCallee() && param->needsDestruction(getContext())) { EHScopeStack::stable_iterator cleanup = CalleeDestructedParamCleanups.lookup(cast(param)); @@ -4903,10 +4897,8 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E, // In the Microsoft C++ ABI, aggregate arguments are destructed by the callee. // However, we still have to push an EH-only cleanup in case we unwind before // we make it to the call. - if (type->isRecordType() && type->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->isParamDestroyedInCallee()) { + if (type->isRecordType() && + type->castAsRecordDecl()->isParamDestroyedInCallee()) { // If we're using inalloca, use the argument memory. Otherwise, use a // temporary. AggValueSlot Slot = args.isUsingInAlloca() diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 10e4543a6ab20..bae55aa1e1928 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -180,11 +180,7 @@ CharUnits CodeGenModule::computeNonVirtualBaseClassOffset( // Get the layout. const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); - const auto *BaseDecl = - cast( - Base->getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); - + const auto *BaseDecl = Base->getType()->castAsCXXRecordDecl(); // Add the offset. Offset += Layout.getBaseClassOffset(BaseDecl); @@ -302,9 +298,7 @@ Address CodeGenFunction::GetAddressOfBaseClass( // *start* with a step down to the correct virtual base subobject, // and hence will not require any further steps. if ((*Start)->isVirtual()) { - VBase = cast( - (*Start)->getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + VBase = (*Start)->getType()->castAsCXXRecordDecl(); ++Start; } @@ -559,10 +553,7 @@ static void EmitBaseInitializer(CodeGenFunction &CGF, Address ThisPtr = CGF.LoadCXXThisAddress(); - const Type *BaseType = BaseInit->getBaseClass(); - const auto *BaseClassDecl = - cast(BaseType->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *BaseClassDecl = BaseInit->getBaseClass()->castAsCXXRecordDecl(); bool isBaseVirtual = BaseInit->isBaseVirtual(); @@ -1267,10 +1258,7 @@ namespace { static bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit) { const Type *BaseType = BaseInit->getBaseClass(); - const auto *BaseClassDecl = - cast(BaseType->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); - return BaseClassDecl->isDynamicClass(); + return BaseType->castAsCXXRecordDecl()->isDynamicClass(); } /// EmitCtorPrologue - This routine generates necessary code to initialize @@ -1377,10 +1365,7 @@ HasTrivialDestructorBody(ASTContext &Context, if (I.isVirtual()) continue; - const CXXRecordDecl *NonVirtualBase = - cast( - I.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *NonVirtualBase = I.getType()->castAsCXXRecordDecl(); if (!HasTrivialDestructorBody(Context, NonVirtualBase, MostDerivedClassDecl)) return false; @@ -1389,10 +1374,7 @@ HasTrivialDestructorBody(ASTContext &Context, if (BaseClassDecl == MostDerivedClassDecl) { // Check virtual bases. for (const auto &I : BaseClassDecl->vbases()) { - const auto *VirtualBase = - cast( - I.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *VirtualBase = I.getType()->castAsCXXRecordDecl(); if (!HasTrivialDestructorBody(Context, VirtualBase, MostDerivedClassDecl)) return false; @@ -1904,11 +1886,7 @@ void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD, // We push them in the forward order so that they'll be popped in // the reverse order. for (const auto &Base : ClassDecl->vbases()) { - auto *BaseClassDecl = - cast( - Base.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); - + auto *BaseClassDecl = Base.getType()->castAsCXXRecordDecl(); if (BaseClassDecl->hasTrivialDestructor()) { // Under SanitizeMemoryUseAfterDtor, poison the trivial base class // memory. For non-trival base classes the same is done in the class @@ -2127,10 +2105,7 @@ void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, void CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF, Address addr, QualType type) { - const RecordType *rtype = type->castAs(); - const auto *record = - cast(rtype->getOriginalDecl())->getDefinitionOrSelf(); - const CXXDestructorDecl *dtor = record->getDestructor(); + const CXXDestructorDecl *dtor = type->castAsCXXRecordDecl()->getDestructor(); assert(!dtor->isTrivial()); CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false, /*Delegating=*/false, addr, type); @@ -2649,10 +2624,7 @@ void CodeGenFunction::getVTablePointers(BaseSubobject Base, // Traverse bases. for (const auto &I : RD->bases()) { - auto *BaseDecl = cast( - I.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); - + auto *BaseDecl = I.getType()->castAsCXXRecordDecl(); // Ignore classes without a vtable. if (!BaseDecl->isDynamicClass()) continue; diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index c44fea3e6383d..560749f8ab308 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5921,8 +5921,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, // variable for each member of the anonymous union so that it's possible // to find the name of any field in the union. if (T->isUnionType() && DeclName.empty()) { - const RecordDecl *RD = - T->castAs()->getOriginalDecl()->getDefinitionOrSelf(); + const auto *RD = T->castAsRecordDecl(); assert(RD->isAnonymousStructOrUnion() && "unnamed non-anonymous struct or union?"); GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 8693f3c71ea80..29193e0c541b9 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -2727,10 +2727,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg, // Don't push a cleanup in a thunk for a method that will also emit a // cleanup. if (Ty->isRecordType() && !CurFuncIsThunk && - Ty->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->isParamDestroyedInCallee()) { + Ty->castAsRecordDecl()->isParamDestroyedInCallee()) { if (QualType::DestructionKind DtorKind = D.needsDestruction(getContext())) { assert((DtorKind == QualType::DK_cxx_destructor || diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index e8942aceb9b09..eeaf68dfd0521 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1984,11 +1984,9 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue, static bool getRangeForType(CodeGenFunction &CGF, QualType Ty, llvm::APInt &Min, llvm::APInt &End, bool StrictEnums, bool IsBool) { - const EnumType *ET = Ty->getAs(); - const EnumDecl *ED = - ET ? ET->getOriginalDecl()->getDefinitionOrSelf() : nullptr; + const auto *ED = Ty->getAsEnumDecl(); bool IsRegularCPlusPlusEnum = - CGF.getLangOpts().CPlusPlus && StrictEnums && ET && !ED->isFixed(); + CGF.getLangOpts().CPlusPlus && StrictEnums && ED && !ED->isFixed(); if (!IsBool && !IsRegularCPlusPlusEnum) return false; @@ -5723,12 +5721,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { - const auto *DerivedClassTy = - E->getSubExpr()->getType()->castAs(); - auto *DerivedClassDecl = - cast(DerivedClassTy->getOriginalDecl()) - ->getDefinitionOrSelf(); - + auto *DerivedClassDecl = E->getSubExpr()->getType()->castAsCXXRecordDecl(); LValue LV = EmitLValue(E->getSubExpr()); Address This = LV.getAddress(); @@ -5746,11 +5739,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { case CK_ToUnion: return EmitAggExprToLValue(E); case CK_BaseToDerived: { - const auto *DerivedClassTy = E->getType()->castAs(); - auto *DerivedClassDecl = - cast(DerivedClassTy->getOriginalDecl()) - ->getDefinitionOrSelf(); - + auto *DerivedClassDecl = E->getType()->castAsCXXRecordDecl(); LValue LV = EmitLValue(E->getSubExpr()); // Perform the base-to-derived conversion diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index ed90e987b180d..50575362d304b 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -424,10 +424,7 @@ AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { Ctx.getAsConstantArrayType(E->getSubExpr()->getType()); assert(ArrayType && "std::initializer_list constructed from non-array"); - RecordDecl *Record = E->getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *Record = E->getType()->castAsRecordDecl(); RecordDecl::field_iterator Field = Record->field_begin(); assert(Field != Record->field_end() && Ctx.hasSameType(Field->getType()->getPointeeType(), @@ -1809,10 +1806,7 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr( // the disadvantage is that the generated code is more difficult for // the optimizer, especially with bitfields. unsigned NumInitElements = InitExprs.size(); - RecordDecl *record = ExprToVisit->getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + RecordDecl *record = ExprToVisit->getType()->castAsRecordDecl(); // We'll need to enter cleanup scopes in case any of the element // initializers throws an exception. diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index b6868c1fb1f42..810a2ab8c1fcd 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -180,8 +180,7 @@ static CXXRecordDecl *getCXXRecord(const Expr *E) { QualType T = E->getType(); if (const PointerType *PTy = T->getAs()) T = PTy->getPointeeType(); - const RecordType *Ty = T->castAs(); - return cast(Ty->getOriginalDecl())->getDefinitionOrSelf(); + return T->castAsCXXRecordDecl(); } // Note: This function also emit constructor calls to support a MSVC @@ -1687,11 +1686,8 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { QualType AlignValT = sizeType; if (allocatorType->getNumParams() > IndexOfAlignArg) { AlignValT = allocatorType->getParamType(IndexOfAlignArg); - assert(getContext().hasSameUnqualifiedType(AlignValT->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->getIntegerType(), - sizeType) && + assert(getContext().hasSameUnqualifiedType( + AlignValT->castAsEnumDecl()->getIntegerType(), sizeType) && "wrong type for alignment parameter"); ++ParamsToSkip; } else { diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index c4679bd734de9..b44dd9ecc717e 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -714,10 +714,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter, } bool ConstStructBuilder::Build(const InitListExpr *ILE, bool AllowOverwrite) { - RecordDecl *RD = ILE->getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *RD = ILE->getType()->castAsRecordDecl(); const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); unsigned FieldNo = -1; @@ -981,8 +978,7 @@ bool ConstStructBuilder::DoZeroInitPadding(const ASTRecordLayout &Layout, llvm::Constant *ConstStructBuilder::Finalize(QualType Type) { Type = Type.getNonReferenceType(); - RecordDecl *RD = - Type->castAs()->getOriginalDecl()->getDefinitionOrSelf(); + auto *RD = Type->castAsRecordDecl(); llvm::Type *ValTy = CGM.getTypes().ConvertType(Type); return Builder.build(ValTy, RD->hasFlexibleArrayMember()); } @@ -1005,8 +1001,7 @@ llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter, ConstantAggregateBuilder Const(Emitter.CGM); ConstStructBuilder Builder(Emitter, Const, CharUnits::Zero()); - const RecordDecl *RD = - ValTy->castAs()->getOriginalDecl()->getDefinitionOrSelf(); + const auto *RD = ValTy->castAsRecordDecl(); const CXXRecordDecl *CD = dyn_cast(RD); if (!Builder.Build(Val, RD, false, CD, CharUnits::Zero())) return nullptr; @@ -2645,11 +2640,7 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM, continue; } - const CXXRecordDecl *base = - cast( - I.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); - + const auto *base = I.getType()->castAsCXXRecordDecl(); // Ignore empty bases. if (isEmptyRecordForLayout(CGM.getContext(), I.getType()) || CGM.getContext() @@ -2687,11 +2678,7 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM, // Fill in the virtual bases, if we're working with the complete object. if (CXXR && asCompleteObject) { for (const auto &I : CXXR->vbases()) { - const auto *base = - cast( - I.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); - + const auto *base = I.getType()->castAsCXXRecordDecl(); // Ignore empty bases. if (isEmptyRecordForLayout(CGM.getContext(), I.getType())) continue; diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 1e23f45546748..43d295599c4c8 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -3515,9 +3515,7 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) { case OffsetOfNode::Field: { FieldDecl *MemberDecl = ON.getField(); - RecordDecl *RD = CurrentType->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *RD = CurrentType->castAsRecordDecl(); const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD); // Compute the index of the field in its parent. @@ -3557,9 +3555,7 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) { CurrentType = ON.getBase()->getType(); // Compute the offset to the base. - auto *BaseRT = CurrentType->castAs(); - auto *BaseRD = - cast(BaseRT->getOriginalDecl())->getDefinitionOrSelf(); + auto *BaseRD = CurrentType->castAsCXXRecordDecl(); CharUnits OffsetInt = RL.getBaseClassOffset(BaseRD); Offset = llvm::ConstantInt::get(ResultType, OffsetInt.getQuantity()); break; diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp index 1b941fff8b644..b78d89fd1e348 100644 --- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp +++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp @@ -39,8 +39,7 @@ template struct StructVisitor { template void visitStructFields(QualType QT, CharUnits CurStructOffset, Ts... Args) { - const RecordDecl *RD = - QT->castAs()->getOriginalDecl()->getDefinitionOrSelf(); + const auto *RD = QT->castAsRecordDecl(); // Iterate over the fields of the struct. for (const FieldDecl *FD : RD->fields()) { diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index f98339d472fa9..b66608319bb51 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -3006,10 +3006,10 @@ emitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc, CGF.GetAddrOfLocalVar(&TaskTypeArg), KmpTaskTWithPrivatesPtrQTy->castAs()); const auto *KmpTaskTWithPrivatesQTyRD = - cast(KmpTaskTWithPrivatesQTy->getAsTagDecl()); + KmpTaskTWithPrivatesQTy->castAsRecordDecl(); LValue Base = CGF.EmitLValueForField(TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin()); - const auto *KmpTaskTQTyRD = cast(KmpTaskTQTy->getAsTagDecl()); + const auto *KmpTaskTQTyRD = KmpTaskTQTy->castAsRecordDecl(); auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId); LValue PartIdLVal = CGF.EmitLValueForField(Base, *PartIdFI); llvm::Value *PartidParam = PartIdLVal.getPointer(CGF); @@ -3104,11 +3104,10 @@ static llvm::Value *emitDestructorsFunction(CodeGenModule &CGM, CGF.GetAddrOfLocalVar(&TaskTypeArg), KmpTaskTWithPrivatesPtrQTy->castAs()); const auto *KmpTaskTWithPrivatesQTyRD = - cast(KmpTaskTWithPrivatesQTy->getAsTagDecl()); + KmpTaskTWithPrivatesQTy->castAsRecordDecl(); auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin()); Base = CGF.EmitLValueForField(Base, *FI); - for (const auto *Field : - cast(FI->getType()->getAsTagDecl())->fields()) { + for (const auto *Field : FI->getType()->castAsRecordDecl()->fields()) { if (QualType::DestructionKind DtorKind = Field->getType().isDestructedType()) { LValue FieldLValue = CGF.EmitLValueForField(Base, Field); @@ -3212,7 +3211,7 @@ emitTaskPrivateMappingFunction(CodeGenModule &CGM, SourceLocation Loc, LValue Base = CGF.EmitLoadOfPointerLValue( CGF.GetAddrOfLocalVar(&TaskPrivatesArg), TaskPrivatesArg.getType()->castAs()); - const auto *PrivatesQTyRD = cast(PrivatesQTy->getAsTagDecl()); + const auto *PrivatesQTyRD = PrivatesQTy->castAsRecordDecl(); Counter = 0; for (const FieldDecl *Field : PrivatesQTyRD->fields()) { LValue FieldLVal = CGF.EmitLValueForField(Base, Field); @@ -3259,7 +3258,7 @@ static void emitPrivatesInit(CodeGenFunction &CGF, CGF.ConvertTypeForMem(SharedsTy)), SharedsTy); } - FI = cast(FI->getType()->getAsTagDecl())->field_begin(); + FI = FI->getType()->castAsRecordDecl()->field_begin(); for (const PrivateDataTy &Pair : Privates) { // Do not initialize private locals. if (Pair.second.isLocalPrivate()) { @@ -3655,7 +3654,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, } KmpTaskTQTy = SavedKmpTaskTQTy; } - const auto *KmpTaskTQTyRD = cast(KmpTaskTQTy->getAsTagDecl()); + const auto *KmpTaskTQTyRD = KmpTaskTQTy->castAsRecordDecl(); // Build particular struct kmp_task_t for the given task. const RecordDecl *KmpTaskTWithPrivatesQTyRD = createKmpTaskTWithPrivatesRecordDecl(CGM, KmpTaskTQTy, Privates); @@ -3915,10 +3914,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, // Fill the data in the resulting kmp_task_t record. // Copy shareds if there are any. Address KmpTaskSharedsPtr = Address::invalid(); - if (!SharedsTy->getAsStructureType() - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->field_empty()) { + if (!SharedsTy->castAsRecordDecl()->field_empty()) { KmpTaskSharedsPtr = Address( CGF.EmitLoadOfScalar( CGF.EmitLValueForField( @@ -3948,11 +3944,8 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, enum { Priority = 0, Destructors = 1 }; // Provide pointer to function with destructors for privates. auto FI = std::next(KmpTaskTQTyRD->field_begin(), Data1); - const RecordDecl *KmpCmplrdataUD = (*FI) - ->getType() - ->getAsUnionType() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + const auto *KmpCmplrdataUD = (*FI)->getType()->castAsRecordDecl(); + assert(KmpCmplrdataUD->isUnion()); if (NeedsCleanup) { llvm::Value *DestructorFn = emitDestructorsFunction( CGM, Loc, KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy, @@ -4032,8 +4025,7 @@ CGOpenMPRuntime::getDepobjElements(CodeGenFunction &CGF, LValue DepobjLVal, ASTContext &C = CGM.getContext(); QualType FlagsTy; getDependTypes(C, KmpDependInfoTy, FlagsTy); - RecordDecl *KmpDependInfoRD = - cast(KmpDependInfoTy->getAsTagDecl()); + auto *KmpDependInfoRD = KmpDependInfoTy->castAsRecordDecl(); QualType KmpDependInfoPtrTy = C.getPointerType(KmpDependInfoTy); LValue Base = CGF.EmitLoadOfPointerLValue( DepobjLVal.getAddress().withElementType( @@ -4061,8 +4053,7 @@ static void emitDependData(CodeGenFunction &CGF, QualType &KmpDependInfoTy, ASTContext &C = CGM.getContext(); QualType FlagsTy; getDependTypes(C, KmpDependInfoTy, FlagsTy); - RecordDecl *KmpDependInfoRD = - cast(KmpDependInfoTy->getAsTagDecl()); + auto *KmpDependInfoRD = KmpDependInfoTy->castAsRecordDecl(); llvm::Type *LLVMFlagsTy = CGF.ConvertTypeForMem(FlagsTy); OMPIteratorGeneratorScope IteratorScope( @@ -4333,8 +4324,7 @@ Address CGOpenMPRuntime::emitDepobjDependClause( unsigned NumDependencies = Dependencies.DepExprs.size(); QualType FlagsTy; getDependTypes(C, KmpDependInfoTy, FlagsTy); - RecordDecl *KmpDependInfoRD = - cast(KmpDependInfoTy->getAsTagDecl()); + auto *KmpDependInfoRD = KmpDependInfoTy->castAsRecordDecl(); llvm::Value *Size; // Define type kmp_depend_info[]; @@ -4442,8 +4432,7 @@ void CGOpenMPRuntime::emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal, ASTContext &C = CGM.getContext(); QualType FlagsTy; getDependTypes(C, KmpDependInfoTy, FlagsTy); - RecordDecl *KmpDependInfoRD = - cast(KmpDependInfoTy->getAsTagDecl()); + auto *KmpDependInfoRD = KmpDependInfoTy->castAsRecordDecl(); llvm::Type *LLVMFlagsTy = CGF.ConvertTypeForMem(FlagsTy); llvm::Value *NumDeps; LValue Base; @@ -11319,7 +11308,7 @@ void CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction &CGF, RD->completeDefinition(); KmpDimTy = C.getCanonicalTagType(RD); } else { - RD = cast(KmpDimTy->getAsTagDecl()); + RD = KmpDimTy->castAsRecordDecl(); } llvm::APInt Size(/*numBits=*/32, NumIterations.size()); QualType ArrayTy = C.getConstantArrayType(KmpDimTy, Size, nullptr, diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index d3fbb4a2a9364..3ffe999d01178 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -700,8 +700,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { break; case Type::Enum: { - const EnumDecl *ED = - cast(Ty)->getOriginalDecl()->getDefinitionOrSelf(); + const auto *ED = Ty->castAsEnumDecl(); if (ED->isCompleteDefinition() || ED->isFixed()) return ConvertType(ED->getIntegerType()); // Return a placeholder 'i32' type. This can be changed later when the @@ -814,10 +813,7 @@ llvm::StructType *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) { if (const CXXRecordDecl *CRD = dyn_cast(RD)) { for (const auto &I : CRD->bases()) { if (I.isVirtual()) continue; - ConvertRecordDeclType(I.getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf()); + ConvertRecordDeclType(I.getType()->castAsRecordDecl()); } } diff --git a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp index ac56dda74abb7..4e25e887c4133 100644 --- a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp +++ b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp @@ -85,24 +85,22 @@ llvm::TargetExtType *HLSLBufferLayoutBuilder::createLayoutType( Layout.push_back(0); // iterate over all fields of the record, including fields on base classes - llvm::SmallVector RecordTypes; - RecordTypes.push_back(RT); - while (RecordTypes.back()->getAsCXXRecordDecl()->getNumBases()) { - CXXRecordDecl *D = RecordTypes.back()->getAsCXXRecordDecl(); + llvm::SmallVector RecordDecls; + RecordDecls.push_back(RT->castAsCXXRecordDecl()); + while (RecordDecls.back()->getNumBases()) { + CXXRecordDecl *D = RecordDecls.back(); assert(D->getNumBases() == 1 && "HLSL doesn't support multiple inheritance"); - RecordTypes.push_back(D->bases_begin()->getType()->getAs()); + RecordDecls.push_back(D->bases_begin()->getType()->castAsCXXRecordDecl()); } unsigned FieldOffset; llvm::Type *FieldType; - while (!RecordTypes.empty()) { - const RecordType *RT = RecordTypes.back(); - RecordTypes.pop_back(); + while (!RecordDecls.empty()) { + const CXXRecordDecl *RD = RecordDecls.pop_back_val(); - for (const auto *FD : - RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) { + for (const auto *FD : RD->fields()) { assert((!PackOffsets || Index < PackOffsets->size()) && "number of elements in layout struct does not match number of " "packoffset annotations"); @@ -148,7 +146,7 @@ llvm::TargetExtType *HLSLBufferLayoutBuilder::createLayoutType( // create the layout struct type; anonymous struct have empty name but // non-empty qualified name - const CXXRecordDecl *Decl = RT->getAsCXXRecordDecl(); + const auto *Decl = RT->castAsCXXRecordDecl(); std::string Name = Decl->getName().empty() ? "anon" : Decl->getQualifiedNameAsString(); llvm::StructType *StructTy = diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 569fbe9e3bd3a..885b700ffa193 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1397,9 +1397,7 @@ void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF, // to pass to the deallocation function. // Grab the vtable pointer as an intptr_t*. - auto *ClassDecl = cast( - ElementType->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *ClassDecl = ElementType->castAsCXXRecordDecl(); llvm::Value *VTable = CGF.GetVTablePtr(Ptr, CGF.UnqualPtrTy, ClassDecl); // Track back to entry -2 and pull out the offset there. @@ -1609,9 +1607,7 @@ llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, Address ThisPtr, llvm::Type *StdTypeInfoPtrTy) { - auto *ClassDecl = - cast(SrcRecordTy->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *ClassDecl = SrcRecordTy->castAsCXXRecordDecl(); llvm::Value *Value = CGF.GetVTablePtr(ThisPtr, CGM.GlobalsInt8PtrTy, ClassDecl); @@ -1783,9 +1779,7 @@ llvm::Value *ItaniumCXXABI::emitExactDynamicCast( llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy) { - auto *ClassDecl = - cast(SrcRecordTy->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *ClassDecl = SrcRecordTy->castAsCXXRecordDecl(); llvm::Value *OffsetToTop; if (CGM.getItaniumVTableContext().isRelativeLayout()) { // Get the vtable pointer. @@ -3869,9 +3863,7 @@ static bool CanUseSingleInheritance(const CXXRecordDecl *RD) { return false; // Check that the class is dynamic iff the base is. - auto *BaseDecl = cast( - Base->getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *BaseDecl = Base->getType()->castAsCXXRecordDecl(); if (!BaseDecl->isEmpty() && BaseDecl->isDynamicClass() != RD->isDynamicClass()) return false; @@ -4391,10 +4383,7 @@ static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, unsigned Flags = 0; - auto *BaseDecl = cast( - Base->getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); - + auto *BaseDecl = Base->getType()->castAsCXXRecordDecl(); if (Base->isVirtual()) { // Mark the virtual base as seen. if (!Bases.VirtualBases.insert(BaseDecl).second) { @@ -4492,11 +4481,7 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { // The __base_type member points to the RTTI for the base type. Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType())); - auto *BaseDecl = - cast( - Base.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); - + auto *BaseDecl = Base.getType()->castAsCXXRecordDecl(); int64_t OffsetFlags = 0; // All but the lower 8 bits of __offset_flags are a signed offset. diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index 1a878222cde18..6bdfdbcf0e89a 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -374,8 +374,8 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn, if (!passAsAggregateType(Ty)) { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); if (const auto *EIT = Ty->getAs()) if (EIT->getNumBits() > 128) @@ -546,9 +546,8 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy, if (!passAsAggregateType(RetTy)) { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = - EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = RetTy->getAsEnumDecl()) + RetTy = ED->getIntegerType(); if (const auto *EIT = RetTy->getAs()) if (EIT->getNumBits() > 128) diff --git a/clang/lib/CodeGen/Targets/ARC.cpp b/clang/lib/CodeGen/Targets/ARC.cpp index ace524e1976d9..56bbae0eace94 100644 --- a/clang/lib/CodeGen/Targets/ARC.cpp +++ b/clang/lib/CodeGen/Targets/ARC.cpp @@ -105,8 +105,8 @@ ABIArgInfo ARCABIInfo::classifyArgumentType(QualType Ty, } // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); auto SizeInRegs = llvm::alignTo(getContext().getTypeSize(Ty), 32) / 32; diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp index c87a0ab52557d..d5c86e19fd358 100644 --- a/clang/lib/CodeGen/Targets/ARM.cpp +++ b/clang/lib/CodeGen/Targets/ARM.cpp @@ -382,8 +382,8 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, bool isVariadic, if (!isAggregateTypeForABI(Ty)) { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) { - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) { + Ty = ED->getIntegerType(); } if (const auto *EIT = Ty->getAs()) @@ -592,9 +592,8 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy, bool isVariadic, if (!isAggregateTypeForABI(RetTy)) { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = - EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = RetTy->getAsEnumDecl()) + RetTy = ED->getIntegerType(); if (const auto *EIT = RetTy->getAs()) if (EIT->getNumBits() > 64) diff --git a/clang/lib/CodeGen/Targets/BPF.cpp b/clang/lib/CodeGen/Targets/BPF.cpp index 87d50e671d251..3a7af346f1132 100644 --- a/clang/lib/CodeGen/Targets/BPF.cpp +++ b/clang/lib/CodeGen/Targets/BPF.cpp @@ -47,8 +47,8 @@ class BPFABIInfo : public DefaultABIInfo { } } - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); ASTContext &Context = getContext(); if (const auto *EIT = Ty->getAs()) @@ -69,9 +69,8 @@ class BPFABIInfo : public DefaultABIInfo { getDataLayout().getAllocaAddrSpace()); // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = - EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = RetTy->getAsEnumDecl()) + RetTy = ED->getIntegerType(); ASTContext &Context = getContext(); if (const auto *EIT = RetTy->getAs()) diff --git a/clang/lib/CodeGen/Targets/CSKY.cpp b/clang/lib/CodeGen/Targets/CSKY.cpp index 14deaf106e01e..b9254208f912a 100644 --- a/clang/lib/CodeGen/Targets/CSKY.cpp +++ b/clang/lib/CodeGen/Targets/CSKY.cpp @@ -115,8 +115,8 @@ ABIArgInfo CSKYABIInfo::classifyArgumentType(QualType Ty, int &ArgGPRsLeft, if (!isAggregateTypeForABI(Ty)) { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); // All integral types are promoted to XLen width, unless passed on the // stack. diff --git a/clang/lib/CodeGen/Targets/Hexagon.cpp b/clang/lib/CodeGen/Targets/Hexagon.cpp index 0c423429eda4f..97a9300a1b8cd 100644 --- a/clang/lib/CodeGen/Targets/Hexagon.cpp +++ b/clang/lib/CodeGen/Targets/Hexagon.cpp @@ -97,8 +97,8 @@ ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty, unsigned *RegsLeft) const { if (!isAggregateTypeForABI(Ty)) { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); uint64_t Size = getContext().getTypeSize(Ty); if (Size <= 64) @@ -160,9 +160,8 @@ ABIArgInfo HexagonABIInfo::classifyReturnType(QualType RetTy) const { if (!isAggregateTypeForABI(RetTy)) { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = - EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = RetTy->getAsEnumDecl()) + RetTy = ED->getIntegerType(); if (Size > 64 && RetTy->isBitIntType()) return getNaturalAlignIndirect( diff --git a/clang/lib/CodeGen/Targets/Lanai.cpp b/clang/lib/CodeGen/Targets/Lanai.cpp index 08cb36034f6fd..675009f0e5748 100644 --- a/clang/lib/CodeGen/Targets/Lanai.cpp +++ b/clang/lib/CodeGen/Targets/Lanai.cpp @@ -125,8 +125,8 @@ ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty, } // Treat an enum type as its underlying type. - if (const auto *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); bool InReg = shouldUseInReg(Ty, State); diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp index af863e6101e2c..0ea08ff533916 100644 --- a/clang/lib/CodeGen/Targets/LoongArch.cpp +++ b/clang/lib/CodeGen/Targets/LoongArch.cpp @@ -180,10 +180,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper( // If this is a C++ record, check the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) { for (const CXXBaseSpecifier &B : CXXRD->bases()) { - const auto *BDecl = - cast( - B.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *BDecl = B.getType()->castAsCXXRecordDecl(); if (!detectFARsEligibleStructHelper( B.getType(), CurOff + Layout.getBaseClassOffset(BDecl), Field1Ty, Field1Off, Field2Ty, Field2Off)) @@ -370,8 +367,8 @@ ABIArgInfo LoongArchABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, if (!isAggregateTypeForABI(Ty) && !Ty->isVectorType()) { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); // All integral types are promoted to GRLen width. if (Size < GRLen && Ty->isIntegralOrEnumerationType()) diff --git a/clang/lib/CodeGen/Targets/Mips.cpp b/clang/lib/CodeGen/Targets/Mips.cpp index e12a34ce07bbe..9c3016fa1f5a5 100644 --- a/clang/lib/CodeGen/Targets/Mips.cpp +++ b/clang/lib/CodeGen/Targets/Mips.cpp @@ -241,8 +241,8 @@ MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const { } // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); // Make sure we pass indirectly things that are too large. if (const auto *EIT = Ty->getAs()) @@ -332,8 +332,8 @@ ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const { } // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = RetTy->getAsEnumDecl()) + RetTy = ED->getIntegerType(); // Make sure we pass indirectly things that are too large. if (const auto *EIT = RetTy->getAs()) diff --git a/clang/lib/CodeGen/Targets/NVPTX.cpp b/clang/lib/CodeGen/Targets/NVPTX.cpp index 106251fb27024..400fa200bf7bc 100644 --- a/clang/lib/CodeGen/Targets/NVPTX.cpp +++ b/clang/lib/CodeGen/Targets/NVPTX.cpp @@ -172,8 +172,8 @@ ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const { return ABIArgInfo::getDirect(); // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = RetTy->getAsEnumDecl()) + RetTy = ED->getIntegerType(); return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy) : ABIArgInfo::getDirect()); @@ -181,8 +181,8 @@ ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const { ABIArgInfo NVPTXABIInfo::classifyArgumentType(QualType Ty) const { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); // Return aggregates type as indirect by value if (isAggregateTypeForABI(Ty)) { diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index a297833a57ef4..380e8c06c46f0 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -153,8 +153,8 @@ class AIXTargetCodeGenInfo : public TargetCodeGenInfo { // extended to 32/64 bits. bool AIXABIInfo::isPromotableTypeForABI(QualType Ty) const { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); // Promotable integer types are required to be promoted by the ABI. if (getContext().isPromotableIntegerType(Ty)) @@ -705,8 +705,8 @@ class PPC64TargetCodeGenInfo : public TargetCodeGenInfo { bool PPC64_SVR4_ABIInfo::isPromotableTypeForABI(QualType Ty) const { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); // Promotable integer types are required to be promoted by the ABI. if (isPromotableIntegerTypeForABI(Ty)) diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index 264595a6e4b76..049f61bb86b1e 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -264,10 +264,7 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff, // If this is a C++ record, check the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) { for (const CXXBaseSpecifier &B : CXXRD->bases()) { - const auto *BDecl = - cast( - B.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *BDecl = B.getType()->castAsCXXRecordDecl(); CharUnits BaseOff = Layout.getBaseClassOffset(BDecl); bool Ret = detectFPCCEligibleStructHelper(B.getType(), CurOff + BaseOff, Field1Ty, Field1Off, Field2Ty, @@ -680,8 +677,8 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, if (!isAggregateTypeForABI(Ty) && !Ty->isVectorType()) { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); // All integral types are promoted to XLen width if (Size < XLen && Ty->isIntegralOrEnumerationType()) { diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp b/clang/lib/CodeGen/Targets/Sparc.cpp index 13a42f66f5843..5f3c15d106eb6 100644 --- a/clang/lib/CodeGen/Targets/Sparc.cpp +++ b/clang/lib/CodeGen/Targets/Sparc.cpp @@ -237,8 +237,8 @@ SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit) const { /*ByVal=*/false); // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); // Integer types smaller than a register are extended. if (Size < 64 && Ty->isIntegerType()) diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index c3f0cba4cbef6..9b6b72b1dcc05 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -145,8 +145,8 @@ class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { bool SystemZABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); // Promotable integer types are required to be promoted by the ABI. if (ABIInfo::isPromotableIntegerTypeForABI(Ty)) @@ -208,10 +208,8 @@ llvm::Type *SystemZABIInfo::getFPArgumentType(QualType Ty, } QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const { - const RecordType *RT = Ty->getAs(); - - if (RT && RT->isStructureOrClassType()) { - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + const auto *RD = Ty->getAsRecordDecl(); + if (RD && RD->isStructureOrClass()) { QualType Found; // If this is a C++ record, check the bases first. diff --git a/clang/lib/CodeGen/Targets/WebAssembly.cpp b/clang/lib/CodeGen/Targets/WebAssembly.cpp index ac8dcd2a0540a..ebe996a4edd8d 100644 --- a/clang/lib/CodeGen/Targets/WebAssembly.cpp +++ b/clang/lib/CodeGen/Targets/WebAssembly.cpp @@ -115,11 +115,9 @@ ABIArgInfo WebAssemblyABIInfo::classifyArgumentType(QualType Ty) const { return ABIArgInfo::getDirect(CGT.ConvertType(QualType(SeltTy, 0))); // For the experimental multivalue ABI, fully expand all other aggregates if (Kind == WebAssemblyABIKind::ExperimentalMV) { - const RecordType *RT = Ty->getAs(); - assert(RT); + const auto *RD = Ty->castAsRecordDecl(); bool HasBitField = false; - for (auto *Field : - RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) { + for (auto *Field : RD->fields()) { if (Field->isBitField()) { HasBitField = true; break; diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index f04d24db26a25..386772a96c7ff 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -552,8 +552,8 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, } // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = RetTy->getAsEnumDecl()) + RetTy = ED->getIntegerType(); if (const auto *EIT = RetTy->getAs()) if (EIT->getNumBits() > 64) @@ -881,9 +881,8 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State, return ABIArgInfo::getDirect(); } - - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); bool InReg = shouldPrimitiveUseInReg(Ty, State); @@ -1846,10 +1845,9 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo, return; } - if (const EnumType *ET = Ty->getAs()) { + if (const auto *ED = Ty->getAsEnumDecl()) { // Classify the underlying integer type. - classify(ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(), - OffsetBase, Lo, Hi, isNamedArg); + classify(ED->getIntegerType(), OffsetBase, Lo, Hi, isNamedArg); return; } @@ -2071,11 +2069,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo, for (const auto &I : CXXRD->bases()) { assert(!I.isVirtual() && !I.getType()->isDependentType() && "Unexpected base class!"); - const auto *Base = - cast( - I.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); - + const auto *Base = I.getType()->castAsCXXRecordDecl(); // Classify this field. // // AMD64-ABI 3.2.3p2: Rule 3. If the size of the aggregate exceeds a @@ -2187,8 +2181,8 @@ ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty) const { // place naturally. if (!isAggregateTypeForABI(Ty)) { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); if (Ty->isBitIntType()) return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace()); @@ -2229,8 +2223,8 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty, if (!isAggregateTypeForABI(Ty) && !IsIllegalVectorType(Ty) && !Ty->isBitIntType()) { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) : ABIArgInfo::getDirect()); @@ -2358,10 +2352,7 @@ static bool BitsContainNoUserData(QualType Ty, unsigned StartBit, for (const auto &I : CXXRD->bases()) { assert(!I.isVirtual() && !I.getType()->isDependentType() && "Unexpected base class!"); - const auto *Base = - cast( - I.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *Base = I.getType()->castAsCXXRecordDecl(); // If the base is after the span we care about, ignore it. unsigned BaseOffset = Context.toBits(Layout.getBaseClassOffset(Base)); @@ -2641,9 +2632,8 @@ ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy) const { // so that the parameter gets the right LLVM IR attributes. if (Hi == NoClass && isa(ResType)) { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = - EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = RetTy->getAsEnumDecl()) + RetTy = ED->getIntegerType(); if (RetTy->isIntegralOrEnumerationType() && isPromotableIntegerTypeForABI(RetTy)) @@ -2792,8 +2782,8 @@ X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned freeIntRegs, // so that the parameter gets the right LLVM IR attributes. if (Hi == NoClass && isa(ResType)) { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = Ty->getAsEnumDecl()) + Ty = ED->getIntegerType(); if (Ty->isIntegralOrEnumerationType() && isPromotableIntegerTypeForABI(Ty)) diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp index f57ccd30c59b9..ad8916f817486 100644 --- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -3638,8 +3638,7 @@ bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type, return RewriteObjCFieldDeclType(ElemTy, Result); } else if (Type->isRecordType()) { - RecordDecl *RD = - Type->castAs()->getOriginalDecl()->getDefinitionOrSelf(); + auto *RD = Type->castAsRecordDecl(); if (RD->isCompleteDefinition()) { if (RD->isStruct()) Result += "\n\tstruct "; @@ -3660,28 +3659,26 @@ bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type, Result += "\t} "; return true; } - } - else if (Type->isEnumeralType()) { - EnumDecl *ED = - Type->castAs()->getOriginalDecl()->getDefinitionOrSelf(); - if (ED->isCompleteDefinition()) { - Result += "\n\tenum "; - Result += ED->getName(); - if (GlobalDefinedTags.count(ED)) { - // Enum is globall defined, use it. - Result += " "; - return true; - } - - Result += " {\n"; - for (const auto *EC : ED->enumerators()) { - Result += "\t"; Result += EC->getName(); Result += " = "; - Result += toString(EC->getInitVal(), 10); - Result += ",\n"; - } - Result += "\t} "; + } else if (auto *ED = Type->getAsEnumDecl(); + ED && ED->isCompleteDefinition()) { + Result += "\n\tenum "; + Result += ED->getName(); + if (GlobalDefinedTags.count(ED)) { + // Enum is globall defined, use it. + Result += " "; return true; } + + Result += " {\n"; + for (const auto *EC : ED->enumerators()) { + Result += "\t"; + Result += EC->getName(); + Result += " = "; + Result += toString(EC->getInitVal(), 10); + Result += ",\n"; + } + Result += "\t} "; + return true; } Result += "\t"; @@ -5715,10 +5712,7 @@ void RewriteModernObjC::HandleDeclInMainFile(Decl *D) { } } } else if (VD->getType()->isRecordType()) { - RecordDecl *RD = VD->getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *RD = VD->getType()->castAsRecordDecl(); if (RD->isCompleteDefinition()) RewriteRecordBody(RD); } diff --git a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp index 0242fc1f6e827..b9c025de87739 100644 --- a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp @@ -4835,10 +4835,7 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) { } } } else if (VD->getType()->isRecordType()) { - RecordDecl *RD = VD->getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *RD = VD->getType()->castAsRecordDecl(); if (RD->isCompleteDefinition()) RewriteRecordBody(RD); } diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp index 9a699c3c896de..74c6c116b274e 100644 --- a/clang/lib/Index/IndexTypeSourceInfo.cpp +++ b/clang/lib/Index/IndexTypeSourceInfo.cpp @@ -61,7 +61,7 @@ class TypeIndexer : public RecursiveASTVisitor { SourceLocation Loc = TL.getNameLoc(); TypedefNameDecl *ND = TL.getDecl(); if (ND->isTransparentTag()) { - TagDecl *Underlying = ND->getUnderlyingType()->getAsTagDecl(); + auto *Underlying = ND->getUnderlyingType()->castAsTagDecl(); return IndexCtx.handleReference(Underlying, Loc, Parent, ParentDC, SymbolRoleSet(), Relations); } diff --git a/clang/lib/Interpreter/InterpreterValuePrinter.cpp b/clang/lib/Interpreter/InterpreterValuePrinter.cpp index 4f5f43e1b3ade..fbbed6c095c5b 100644 --- a/clang/lib/Interpreter/InterpreterValuePrinter.cpp +++ b/clang/lib/Interpreter/InterpreterValuePrinter.cpp @@ -101,15 +101,11 @@ static std::string EnumToString(const Value &V) { llvm::raw_string_ostream SS(Str); ASTContext &Ctx = const_cast(V.getASTContext()); - QualType DesugaredTy = V.getType().getDesugaredType(Ctx); - const EnumType *EnumTy = DesugaredTy.getNonReferenceType()->getAs(); - assert(EnumTy && "Fail to cast to enum type"); - - EnumDecl *ED = EnumTy->getOriginalDecl()->getDefinitionOrSelf(); uint64_t Data = V.convertTo(); bool IsFirst = true; - llvm::APSInt AP = Ctx.MakeIntValue(Data, DesugaredTy); + llvm::APSInt AP = Ctx.MakeIntValue(Data, V.getType()); + auto *ED = V.getType()->castAsEnumDecl(); for (auto I = ED->enumerator_begin(), E = ED->enumerator_end(); I != E; ++I) { if (I->getInitVal() == AP) { if (!IsFirst) @@ -665,8 +661,8 @@ __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, if (VRef.getKind() == Value::K_PtrOrObj) { VRef.setPtr(va_arg(args, void *)); } else { - if (const auto *ET = QT->getAs()) - QT = ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = QT->getAsEnumDecl()) + QT = ED->getIntegerType(); switch (QT->castAs()->getKind()) { default: llvm_unreachable("unknown type kind!"); diff --git a/clang/lib/Interpreter/Value.cpp b/clang/lib/Interpreter/Value.cpp index 2ef057bc5d0a5..d4c9d51ffcb61 100644 --- a/clang/lib/Interpreter/Value.cpp +++ b/clang/lib/Interpreter/Value.cpp @@ -101,8 +101,8 @@ static Value::Kind ConvertQualTypeToKind(const ASTContext &Ctx, QualType QT) { if (Ctx.hasSameType(QT, Ctx.VoidTy)) return Value::K_Void; - if (const auto *ET = QT->getAs()) - QT = ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = QT->getAsEnumDecl()) + QT = ED->getIntegerType(); const auto *BT = QT->getAs(); if (!BT || BT->isNullPtrType()) diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index 7ceea76012e0c..17415b4185eff 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/lib/Sema/SemaAccess.cpp @@ -1784,10 +1784,7 @@ Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, if (!getLangOpts().AccessControl || Found.getAccess() == AS_public) return AR_accessible; - const RecordType *RT = ObjectExpr->getType()->castAs(); - CXXRecordDecl *NamingClass = - cast(RT->getOriginalDecl())->getDefinitionOrSelf(); - + auto *NamingClass = ObjectExpr->getType()->castAsCXXRecordDecl(); AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found, ObjectExpr->getType()); Entity.setDiag(diag::err_access) << ObjectExpr->getSourceRange() << Range; diff --git a/clang/lib/Sema/SemaBPF.cpp b/clang/lib/Sema/SemaBPF.cpp index 6428435ed9d2a..c5e97484dab78 100644 --- a/clang/lib/Sema/SemaBPF.cpp +++ b/clang/lib/Sema/SemaBPF.cpp @@ -99,13 +99,12 @@ static bool isValidPreserveEnumValueArg(Expr *Arg) { return false; // The type must be EnumType. - const Type *Ty = ArgType->getUnqualifiedDesugaredType(); - const auto *ET = Ty->getAs(); - if (!ET) + const auto *ED = ArgType->getAsEnumDecl(); + if (!ED) return false; // The enum value must be supported. - return llvm::is_contained(ET->getOriginalDecl()->enumerators(), Enumerator); + return llvm::is_contained(ED->enumerators(), Enumerator); } bool SemaBPF::CheckBPFBuiltinFunctionCall(unsigned BuiltinID, diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index 45de8ff3ba264..ef14dde5203a6 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -133,11 +133,8 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS, return const_cast( NNS.getAsNamespaceAndPrefix().Namespace->getNamespace()); - case NestedNameSpecifier::Kind::Type: { - auto *TD = NNS.getAsType()->getAsTagDecl(); - assert(TD && "Non-tag type in nested-name-specifier"); - return TD; - } + case NestedNameSpecifier::Kind::Type: + return NNS.getAsType()->castAsTagDecl(); case NestedNameSpecifier::Kind::Global: return Context.getTranslationUnitDecl(); diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 933a6c558e7ac..de22419ee35de 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -1484,8 +1484,7 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, if (SrcType->isIntegralOrEnumerationType()) { // [expr.static.cast]p10 If the enumeration type has a fixed underlying // type, the value is first converted to that type by integral conversion - const EnumType *Enum = DestType->castAs(); - const EnumDecl *ED = Enum->getOriginalDecl()->getDefinitionOrSelf(); + const auto *ED = DestType->castAsEnumDecl(); Kind = ED->isFixed() && ED->getIntegerType()->isBooleanType() ? CK_IntegralToBoolean : CK_IntegralCast; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 908ac31c6ac98..e647fbca61355 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5278,13 +5278,10 @@ bool Sema::BuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall) { // extra checking to see what their promotable type actually is. if (!Context.isPromotableIntegerType(Type)) return false; - if (!Type->isEnumeralType()) + const auto *ED = Type->getAsEnumDecl(); + if (!ED) return true; - const EnumDecl *ED = Type->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); - return !(ED && - Context.typesAreCompatible(ED->getPromotionType(), Type)); + return !Context.typesAreCompatible(ED->getPromotionType(), Type); }()) { unsigned Reason = 0; if (Type->isReferenceType()) Reason = 1; @@ -8432,10 +8429,9 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, bool IsEnum = false; bool IsScopedEnum = false; QualType IntendedTy = ExprTy; - if (auto EnumTy = ExprTy->getAs()) { - IntendedTy = - EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); - if (EnumTy->isUnscopedEnumerationType()) { + if (const auto *ED = ExprTy->getAsEnumDecl()) { + IntendedTy = ED->getIntegerType(); + if (!ED->isScoped()) { ExprTy = IntendedTy; // This controls whether we're talking about the underlying type or not, // which we only want to do when it's an unscoped enum. @@ -9735,10 +9731,7 @@ struct SearchNonTrivialToInitializeField S.DiagRuntimeBehavior(SL, E, S.PDiag(diag::note_nontrivial_field) << 1); } void visitStruct(QualType FT, SourceLocation SL) { - for (const FieldDecl *FD : FT->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->fields()) + for (const FieldDecl *FD : FT->castAsRecordDecl()->fields()) visit(FD->getType(), FD->getLocation()); } void visitArray(QualType::PrimitiveDefaultInitializeKind PDIK, @@ -9783,10 +9776,7 @@ struct SearchNonTrivialToCopyField S.DiagRuntimeBehavior(SL, E, S.PDiag(diag::note_nontrivial_field) << 0); } void visitStruct(QualType FT, SourceLocation SL) { - for (const FieldDecl *FD : FT->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->fields()) + for (const FieldDecl *FD : FT->castAsRecordDecl()->fields()) visit(FD->getType(), FD->getLocation()); } void visitArray(QualType::PrimitiveCopyKind PCK, const ArrayType *AT, @@ -10586,20 +10576,15 @@ struct IntRange { if (!C.getLangOpts().CPlusPlus) { // For enum types in C code, use the underlying datatype. - if (const auto *ET = dyn_cast(T)) - T = ET->getOriginalDecl() - ->getDefinitionOrSelf() - ->getIntegerType() - .getDesugaredType(C) - .getTypePtr(); - } else if (const auto *ET = dyn_cast(T)) { + if (const auto *ED = T->getAsEnumDecl()) + T = ED->getIntegerType().getDesugaredType(C).getTypePtr(); + } else if (auto *Enum = T->getAsEnumDecl()) { // For enum types in C++, use the known bit width of the enumerators. - EnumDecl *Enum = ET->getOriginalDecl()->getDefinitionOrSelf(); // In C++11, enums can have a fixed underlying type. Use this type to // compute the range. if (Enum->isFixed()) { return IntRange(C.getIntWidth(QualType(T, 0)), - !ET->isSignedIntegerOrEnumerationType()); + !Enum->getIntegerType()->isSignedIntegerType()); } unsigned NumPositive = Enum->getNumPositiveBits(); @@ -10635,10 +10620,8 @@ struct IntRange { T = CT->getElementType().getTypePtr(); if (const AtomicType *AT = dyn_cast(T)) T = AT->getValueType().getTypePtr(); - if (const EnumType *ET = dyn_cast(T)) - T = C.getCanonicalType( - ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType()) - .getTypePtr(); + if (const auto *ED = T->getAsEnumDecl()) + T = C.getCanonicalType(ED->getIntegerType()).getTypePtr(); if (const auto *EIT = dyn_cast(T)) return IntRange(EIT->getNumBits(), EIT->isUnsigned()); @@ -11609,10 +11592,7 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, if (BitfieldType->isBooleanType()) return false; - if (BitfieldType->isEnumeralType()) { - EnumDecl *BitfieldEnumDecl = BitfieldType->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + if (auto *BitfieldEnumDecl = BitfieldType->getAsEnumDecl()) { // If the underlying enum type was not explicitly specified as an unsigned // type and the enum contain only positive values, MSVC++ will cause an // inconsistency by storing this as a signed type. @@ -11641,15 +11621,14 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, // The RHS is not constant. If the RHS has an enum type, make sure the // bitfield is wide enough to hold all the values of the enum without // truncation. - const auto *EnumTy = OriginalInit->getType()->getAs(); + const auto *ED = OriginalInit->getType()->getAsEnumDecl(); const PreferredTypeAttr *PTAttr = nullptr; - if (!EnumTy) { + if (!ED) { PTAttr = Bitfield->getAttr(); if (PTAttr) - EnumTy = PTAttr->getType()->getAs(); + ED = PTAttr->getType()->getAsEnumDecl(); } - if (EnumTy) { - EnumDecl *ED = EnumTy->getOriginalDecl()->getDefinitionOrSelf(); + if (ED) { bool SignedBitfield = BitfieldType->isSignedIntegerOrEnumerationType(); // Enum types are implicitly signed on Windows, so check if there are any @@ -15354,17 +15333,14 @@ static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2) { if (TC1 != TC2) return false; - if (TC1 == Type::Enum) { - return isLayoutCompatible( - C, cast(T1)->getOriginalDecl()->getDefinitionOrSelf(), - cast(T2)->getOriginalDecl()->getDefinitionOrSelf()); - } else if (TC1 == Type::Record) { + if (TC1 == Type::Enum) + return isLayoutCompatible(C, T1->castAsEnumDecl(), T2->castAsEnumDecl()); + if (TC1 == Type::Record) { if (!T1->isStandardLayoutType() || !T2->isStandardLayoutType()) return false; - return isLayoutCompatible( - C, cast(T1)->getOriginalDecl()->getDefinitionOrSelf(), - cast(T2)->getOriginalDecl()->getDefinitionOrSelf()); + return isLayoutCompatible(C, T1->castAsRecordDecl(), + T2->castAsRecordDecl()); } return false; @@ -15721,9 +15697,7 @@ void Sema::RefersToMemberWithReducedAlignment( return; if (ME->isArrow()) BaseType = BaseType->getPointeeType(); - RecordDecl *RD = BaseType->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *RD = BaseType->castAsRecordDecl(); if (RD->isInvalidDecl()) return; diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index c6adead5a65f5..03bf4b3690b13 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -5113,10 +5113,7 @@ void SemaCodeCompletion::CodeCompleteExpression( PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType() || Data.PreferredType->isMemberPointerType() || Data.PreferredType->isBlockPointerType(); - if (Data.PreferredType->isEnumeralType()) { - EnumDecl *Enum = Data.PreferredType->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + if (auto *Enum = Data.PreferredType->getAsEnumDecl()) { // FIXME: collect covered enumerators in cases like: // if (x == my_enum::one) { ... } else if (x == ^) {} AddEnumerators(Results, getASTContext(), Enum, SemaRef.CurContext, @@ -6240,18 +6237,14 @@ void SemaCodeCompletion::CodeCompleteCase(Scope *S) { if (!Switch->getCond()) return; QualType type = Switch->getCond()->IgnoreImplicit()->getType(); - if (!type->isEnumeralType()) { + EnumDecl *Enum = type->getAsEnumDecl(); + if (!Enum) { CodeCompleteExpressionData Data(type); Data.IntegralConstantExpression = true; CodeCompleteExpression(S, Data); return; } - // Code-complete the cases of a switch statement over an enumeration type - // by providing the list of - EnumDecl *Enum = - type->castAs()->getOriginalDecl()->getDefinitionOrSelf(); - // Determine which enumerators we have already seen in the switch statement. // FIXME: Ideally, we would also be able to look *past* the code-completion // token, in case we are code-completing in the middle of the switch and not diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 8a5b9fc19cd1f..a825fdc1748c6 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9811,8 +9811,7 @@ static void checkIsValidOpenCLKernelParameter( // At this point we already handled everything except of a RecordType. assert(PT->isRecordType() && "Unexpected type."); - const RecordDecl *PD = - PT->castAs()->getOriginalDecl()->getDefinitionOrSelf(); + const auto *PD = PT->castAsRecordDecl(); VisitStack.push_back(PD); assert(VisitStack.back() && "First decl null?"); @@ -9840,9 +9839,7 @@ static void checkIsValidOpenCLKernelParameter( "Unexpected type."); const Type *FieldRecTy = FieldTy->getPointeeOrArrayElementType(); - RD = FieldRecTy->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + RD = FieldRecTy->castAsRecordDecl(); } else { RD = cast(Next); } @@ -13370,8 +13367,7 @@ struct DiagNonTrivalCUnionDefaultInitializeVisitor } void visitStruct(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) { - const RecordDecl *RD = - QT->castAs()->getOriginalDecl()->getDefinitionOrSelf(); + const auto *RD = QT->castAsRecordDecl(); if (RD->isUnion()) { if (OrigLoc.isValid()) { bool IsUnion = false; @@ -13437,8 +13433,7 @@ struct DiagNonTrivalCUnionDestructedTypeVisitor } void visitStruct(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) { - const RecordDecl *RD = - QT->castAs()->getOriginalDecl()->getDefinitionOrSelf(); + const auto *RD = QT->castAsRecordDecl(); if (RD->isUnion()) { if (OrigLoc.isValid()) { bool IsUnion = false; @@ -13503,8 +13498,7 @@ struct DiagNonTrivalCUnionCopyVisitor } void visitStruct(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) { - const RecordDecl *RD = - QT->castAs()->getOriginalDecl()->getDefinitionOrSelf(); + const auto *RD = QT->castAsRecordDecl(); if (RD->isUnion()) { if (OrigLoc.isValid()) { bool IsUnion = false; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 34e46fba8250f..5dc0a7eb4c29d 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() - ->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. @@ -10471,11 +10468,7 @@ struct FindHiddenVirtualMethod { /// 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() - ->getOriginalDecl() - ->getDefinitionOrSelf(); - + auto *BaseRecord = Specifier->getType()->castAsRecordDecl(); DeclarationName Name = Method->getDeclName(); assert(Name.getNameKind() == DeclarationName::Identifier); @@ -12651,15 +12644,12 @@ Decl *Sema::ActOnUsingEnumDeclaration(Scope *S, AccessSpecifier AS, return nullptr; } - auto *Enum = dyn_cast_if_present(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); @@ -19152,9 +19142,7 @@ void Sema::MarkVirtualMembersReferenced(SourceLocation Loc, return; for (const auto &I : RD->bases()) { - const auto *Base = cast( - I.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *Base = I.getType()->castAsCXXRecordDecl(); if (Base->getNumVBases() == 0) continue; MarkVirtualMembersReferenced(Loc, Base); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6e5cc7837ecc1..6797353db14bf 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -12382,10 +12382,7 @@ static QualType checkArithmeticOrEnumeralThreeWayCompare(Sema &S, S.InvalidOperands(Loc, LHS, RHS); return QualType(); } - QualType IntType = LHSStrippedType->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->getIntegerType(); + QualType IntType = LHSStrippedType->castAsEnumDecl()->getIntegerType(); assert(IntType->isArithmeticType()); // We can't use `CK_IntegralCast` when the underlying type is 'bool', so we @@ -16882,9 +16879,8 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, // va_arg. Instead, get the underlying type of the enumeration and pass // that. QualType UnderlyingType = TInfo->getType(); - if (const auto *ET = UnderlyingType->getAs()) - UnderlyingType = - ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = UnderlyingType->getAsEnumDecl()) + UnderlyingType = ED->getIntegerType(); if (Context.typesAreCompatible(PromoteType, UnderlyingType, /*CompareUnqualified*/ true)) PromoteType = QualType(); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index b257df438c019..763fc0747eb82 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -3052,9 +3052,7 @@ bool Sema::FindAllocationFunctions( LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName); if (AllocElemType->isRecordType() && DeleteScope != AllocationFunctionScope::Global) { - auto *RD = cast( - AllocElemType->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *RD = AllocElemType->castAsCXXRecordDecl(); LookupQualifiedName(FoundDelete, RD); } if (FoundDelete.isAmbiguous()) @@ -4835,10 +4833,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, if (FromType->isVectorType() || ToType->isVectorType()) StepTy = adjustVectorType(Context, FromType, ToType, &ElTy); if (ElTy->isBooleanType()) { - assert(FromType->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->isFixed() && + assert(FromType->castAsEnumDecl()->isFixed() && SCS.Second == ICK_Integral_Promotion && "only enums with fixed underlying type can promote to bool"); From = ImpCastExprToType(From, StepTy, CK_IntegralToBoolean, VK_PRValue, @@ -7523,12 +7518,10 @@ ExprResult Sema::IgnoredValueConversions(Expr *E) { } // GCC seems to also exclude expressions of incomplete enum type. - if (const EnumType *T = E->getType()->getAs()) { - if (!T->getOriginalDecl()->getDefinitionOrSelf()->isComplete()) { - // FIXME: stupid workaround for a codegen bug! - E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).get(); - return E; - } + if (const auto *ED = E->getType()->getAsEnumDecl(); ED && !ED->isComplete()) { + // FIXME: stupid workaround for a codegen bug! + E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).get(); + return E; } ExprResult Res = DefaultFunctionArrayLvalueConversion(E); diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 03b5c79cf70e3..5684e53a6bcaa 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -638,8 +638,7 @@ ExprResult SemaObjC::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { // Look for the appropriate method within NSNumber. BoxingMethod = getNSNumberFactoryMethod(*this, Loc, ValueType); BoxedType = NSNumberPointer; - } else if (const EnumType *ET = ValueType->getAs()) { - const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + } else if (const auto *ED = ValueType->getAsEnumDecl()) { if (!ED->isComplete()) { Diag(Loc, diag::err_objc_incomplete_boxed_expression_type) << ValueType << ValueExpr->getSourceRange(); diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index b89aa9793c98c..6a68fa2ed7a8b 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -386,14 +386,14 @@ static bool requiresImplicitBufferLayoutStructure(const CXXRecordDecl *RD) { QualType Ty = Field->getType(); if (isInvalidConstantBufferLeafElementType(Ty.getTypePtr())) return true; - if (Ty->isRecordType() && - requiresImplicitBufferLayoutStructure(Ty->getAsCXXRecordDecl())) + if (const auto *RD = Ty->getAsCXXRecordDecl(); + RD && requiresImplicitBufferLayoutStructure(RD)) return true; } // check bases for (const CXXBaseSpecifier &Base : RD->bases()) if (requiresImplicitBufferLayoutStructure( - Base.getType()->getAsCXXRecordDecl())) + Base.getType()->castAsCXXRecordDecl())) return true; return false; } @@ -509,7 +509,7 @@ static CXXRecordDecl *createHostLayoutStruct(Sema &S, assert(NumBases == 1 && "HLSL supports only one base type"); (void)NumBases; CXXBaseSpecifier Base = *StructDecl->bases_begin(); - CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); + CXXRecordDecl *BaseDecl = Base.getType()->castAsCXXRecordDecl(); if (requiresImplicitBufferLayoutStructure(BaseDecl)) { BaseDecl = createHostLayoutStruct(S, BaseDecl); if (BaseDecl) { @@ -3979,19 +3979,19 @@ class InitListTransformer { return true; } - if (auto *RTy = Ty->getAs()) { - llvm::SmallVector RecordTypes; - RecordTypes.push_back(RTy); - while (RecordTypes.back()->getAsCXXRecordDecl()->getNumBases()) { - CXXRecordDecl *D = RecordTypes.back()->getAsCXXRecordDecl(); + if (auto *RD = Ty->getAsCXXRecordDecl()) { + llvm::SmallVector RecordDecls; + RecordDecls.push_back(RD); + while (RecordDecls.back()->getNumBases()) { + CXXRecordDecl *D = RecordDecls.back(); assert(D->getNumBases() == 1 && "HLSL doesn't support multiple inheritance"); - RecordTypes.push_back(D->bases_begin()->getType()->getAs()); + RecordDecls.push_back( + D->bases_begin()->getType()->castAsCXXRecordDecl()); } - while (!RecordTypes.empty()) { - const RecordType *RT = RecordTypes.pop_back_val(); - for (auto *FD : - RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) { + while (!RecordDecls.empty()) { + CXXRecordDecl *RD = RecordDecls.pop_back_val(); + for (auto *FD : RD->fields()) { DeclAccessPair Found = DeclAccessPair::make(FD, FD->getAccess()); DeclarationNameInfo NameInfo(FD->getDeclName(), E->getBeginLoc()); ExprResult Res = S.BuildFieldReferenceExpr( @@ -4028,21 +4028,20 @@ class InitListTransformer { for (uint64_t I = 0; I < Size; ++I) Inits.push_back(generateInitListsImpl(ElTy)); } - if (auto *RTy = Ty->getAs()) { - llvm::SmallVector RecordTypes; - RecordTypes.push_back(RTy); - while (RecordTypes.back()->getAsCXXRecordDecl()->getNumBases()) { - CXXRecordDecl *D = RecordTypes.back()->getAsCXXRecordDecl(); + if (auto *RD = Ty->getAsCXXRecordDecl()) { + llvm::SmallVector RecordDecls; + RecordDecls.push_back(RD); + while (RecordDecls.back()->getNumBases()) { + CXXRecordDecl *D = RecordDecls.back(); assert(D->getNumBases() == 1 && "HLSL doesn't support multiple inheritance"); - RecordTypes.push_back(D->bases_begin()->getType()->getAs()); + RecordDecls.push_back( + D->bases_begin()->getType()->castAsCXXRecordDecl()); } - while (!RecordTypes.empty()) { - const RecordType *RT = RecordTypes.pop_back_val(); - for (auto *FD : - RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) { + while (!RecordDecls.empty()) { + CXXRecordDecl *RD = RecordDecls.pop_back_val(); + for (auto *FD : RD->fields()) Inits.push_back(generateInitListsImpl(FD->getType())); - } } } auto *NewInit = new (Ctx) InitListExpr(Ctx, Inits.front()->getBeginLoc(), diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 0242671aecdb3..4dfeebdea7919 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -1125,8 +1125,7 @@ int InitListChecker::numArrayElements(QualType DeclType) { } int InitListChecker::numStructUnionElements(QualType DeclType) { - RecordDecl *structDecl = - DeclType->castAs()->getOriginalDecl()->getDefinitionOrSelf(); + auto *structDecl = DeclType->castAsRecordDecl(); int InitializableMembers = 0; if (auto *CXXRD = dyn_cast(structDecl)) InitializableMembers += CXXRD->getNumBases(); @@ -1155,22 +1154,14 @@ static bool isIdiomaticBraceElisionEntity(const InitializedEntity &Entity) { // Allows elide brace initialization for aggregates with empty base. if (Entity.getKind() == InitializedEntity::EK_Base) { - auto *ParentRD = Entity.getParent() - ->getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *ParentRD = Entity.getParent()->getType()->castAsRecordDecl(); CXXRecordDecl *CXXRD = cast(ParentRD); return CXXRD->getNumBases() == 1 && CXXRD->field_empty(); } // Allow brace elision if the only subobject is a field. if (Entity.getKind() == InitializedEntity::EK_Member) { - auto *ParentRD = Entity.getParent() - ->getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *ParentRD = Entity.getParent()->getType()->castAsRecordDecl(); if (CXXRecordDecl *CXXRD = dyn_cast(ParentRD)) { if (CXXRD->getNumBases()) { return false; @@ -2347,7 +2338,9 @@ void InitListChecker::CheckStructUnionTypes( Field != FieldEnd; ++Field) { if (Field->hasInClassInitializer() || (Field->isAnonymousStructOrUnion() && - Field->getType()->getAsCXXRecordDecl()->hasInClassInitializer())) { + Field->getType() + ->castAsCXXRecordDecl() + ->hasInClassInitializer())) { StructuredList->setInitializedFieldInUnion(*Field); // FIXME: Actually build a CXXDefaultInitExpr? return; @@ -4534,11 +4527,7 @@ static void TryConstructorInitialization(Sema &S, } } - const RecordType *DestRecordType = DestType->getAs(); - assert(DestRecordType && "Constructor initialization requires record type"); - auto *DestRecordDecl = cast(DestRecordType->getOriginalDecl()) - ->getDefinitionOrSelf(); - + auto *DestRecordDecl = DestType->castAsCXXRecordDecl(); // Build the candidate set directly in the initialization sequence // structure, so that it will persist if we fail. OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet(); @@ -5025,7 +5014,7 @@ static void TryListInitialization(Sema &S, // class type with a default constructor, the object is // value-initialized. if (InitList->getNumInits() == 0) { - CXXRecordDecl *RD = DestType->getAsCXXRecordDecl(); + CXXRecordDecl *RD = DestType->castAsCXXRecordDecl(); if (S.LookupDefaultConstructor(RD)) { TryValueInitialization(S, Entity, Kind, Sequence, InitList); return; @@ -5056,10 +5045,9 @@ static void TryListInitialization(Sema &S, // is direct-list-initialization, the object is initialized with the // value T(v); if a narrowing conversion is required to convert v to // the underlying type of T, the program is ill-formed. - auto *ET = DestType->getAs(); if (S.getLangOpts().CPlusPlus17 && - Kind.getKind() == InitializationKind::IK_DirectList && ET && - ET->getOriginalDecl()->getDefinitionOrSelf()->isFixed() && + Kind.getKind() == InitializationKind::IK_DirectList && + DestType->isEnumeralType() && DestType->castAsEnumDecl()->isFixed() && !S.Context.hasSameUnqualifiedType(E->getType(), DestType) && (E->getType()->isIntegralOrUnscopedEnumerationType() || E->getType()->isFloatingType())) { @@ -5164,14 +5152,13 @@ static OverloadingResult TryRefInitWithConversionFunction( bool AllowExplicitCtors = false; bool AllowExplicitConvs = Kind.allowExplicitConversionFunctionsInRefBinding(); - const RecordType *T1RecordType = nullptr; - if (AllowRValues && (T1RecordType = T1->getAs()) && + if (AllowRValues && T1->isRecordType() && S.isCompleteType(Kind.getLocation(), T1)) { + auto *T1RecordDecl = T1->castAsCXXRecordDecl(); + if (T1RecordDecl->isInvalidDecl()) + return OR_No_Viable_Function; // The type we're converting to is a class type. Enumerate its constructors // to see if there is a suitable conversion. - auto *T1RecordDecl = cast(T1RecordType->getOriginalDecl()) - ->getDefinitionOrSelf(); - for (NamedDecl *D : S.LookupConstructors(T1RecordDecl)) { auto Info = getConstructorInfo(D); if (!Info.Constructor) @@ -5193,18 +5180,13 @@ static OverloadingResult TryRefInitWithConversionFunction( } } } - if (T1RecordType && - T1RecordType->getOriginalDecl()->getDefinitionOrSelf()->isInvalidDecl()) - return OR_No_Viable_Function; - const RecordType *T2RecordType = nullptr; - if ((T2RecordType = T2->getAs()) && - S.isCompleteType(Kind.getLocation(), T2)) { + if (T2->isRecordType() && S.isCompleteType(Kind.getLocation(), T2)) { + const auto *T2RecordDecl = T2->castAsCXXRecordDecl(); + if (T2RecordDecl->isInvalidDecl()) + return OR_No_Viable_Function; // The type we're converting from is a class type, enumerate its conversion // functions. - auto *T2RecordDecl = cast(T2RecordType->getOriginalDecl()) - ->getDefinitionOrSelf(); - const auto &Conversions = T2RecordDecl->getVisibleConversionFunctions(); for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { NamedDecl *D = *I; @@ -5239,9 +5221,6 @@ static OverloadingResult TryRefInitWithConversionFunction( } } } - if (T2RecordType && - T2RecordType->getOriginalDecl()->getDefinitionOrSelf()->isInvalidDecl()) - return OR_No_Viable_Function; SourceLocation DeclLoc = Initializer->getBeginLoc(); @@ -6099,15 +6078,12 @@ static void TryUserDefinedConversion(Sema &S, // explicit conversion operators. bool AllowExplicit = Kind.AllowExplicit(); - if (const RecordType *DestRecordType = DestType->getAs()) { + if (DestType->isRecordType()) { // The type we're converting to is a class type. Enumerate its constructors // to see if there is a suitable conversion. - auto *DestRecordDecl = - cast(DestRecordType->getOriginalDecl()) - ->getDefinitionOrSelf(); - // Try to complete the type we're converting to. if (S.isCompleteType(Kind.getLocation(), DestType)) { + auto *DestRecordDecl = DestType->castAsCXXRecordDecl(); for (NamedDecl *D : S.LookupConstructors(DestRecordDecl)) { auto Info = getConstructorInfo(D); if (!Info.Constructor) @@ -6133,17 +6109,14 @@ static void TryUserDefinedConversion(Sema &S, SourceLocation DeclLoc = Initializer->getBeginLoc(); - if (const RecordType *SourceRecordType = SourceType->getAs()) { + if (SourceType->isRecordType()) { // The type we're converting from is a class type, enumerate its conversion // functions. // We can only enumerate the conversion functions for a complete type; if // the type isn't complete, simply skip this step. if (S.isCompleteType(DeclLoc, SourceType)) { - auto *SourceRecordDecl = - cast(SourceRecordType->getOriginalDecl()) - ->getDefinitionOrSelf(); - + auto *SourceRecordDecl = SourceType->castAsCXXRecordDecl(); const auto &Conversions = SourceRecordDecl->getVisibleConversionFunctions(); for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { @@ -8158,10 +8131,8 @@ ExprResult InitializationSequence::Perform(Sema &S, // FIXME: It makes no sense to do this here. This should happen // regardless of how we initialized the entity. QualType T = CurInit.get()->getType(); - if (const RecordType *Record = T->getAs()) { - CXXDestructorDecl *Destructor = - S.LookupDestructor(cast(Record->getOriginalDecl()) - ->getDefinitionOrSelf()); + if (auto *Record = T->castAsCXXRecordDecl()) { + CXXDestructorDecl *Destructor = S.LookupDestructor(Record); S.CheckDestructorAccess(CurInit.get()->getBeginLoc(), Destructor, S.PDiag(diag::err_access_dtor_temp) << T); S.MarkFunctionReferenced(CurInit.get()->getBeginLoc(), Destructor); @@ -8549,9 +8520,8 @@ ExprResult InitializationSequence::Perform(Sema &S, S.isStdInitializerList(Step->Type, &ElementType); assert(IsStdInitializerList && "StdInitializerList step to non-std::initializer_list"); - const CXXRecordDecl *Record = - Step->Type->getAsCXXRecordDecl()->getDefinition(); - assert(Record && Record->isCompleteDefinition() && + const auto *Record = Step->Type->castAsCXXRecordDecl(); + assert(Record->isCompleteDefinition() && "std::initializer_list should have already be " "complete/instantiated by this point"); @@ -9214,11 +9184,8 @@ bool InitializationSequence::Diagnose(Sema &S, << S.Context.getCanonicalTagType(Constructor->getParent()) << /*base=*/0 << Entity.getType() << InheritedFrom; - RecordDecl *BaseDecl = Entity.getBaseSpecifier() - ->getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *BaseDecl = + Entity.getBaseSpecifier()->getType()->castAsRecordDecl(); S.Diag(BaseDecl->getLocation(), diag::note_previous_decl) << S.Context.getCanonicalTagType(BaseDecl); } else { diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 8a81cbe2623d8..fbc2e7eb30676 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -641,9 +641,8 @@ static EnumDecl *findEnumForBlockReturn(Expr *E) { } // - it is an expression of that formal enum type. - if (const EnumType *ET = E->getType()->getAs()) { - return ET->getOriginalDecl()->getDefinitionOrSelf(); - } + if (auto *ED = E->getType()->getAsEnumDecl()) + return ED; // Otherwise, nope. return nullptr; diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 42519a52b57ac..86ffae9363beb 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -2770,10 +2770,7 @@ bool Sema::LookupInSuper(LookupResult &R, CXXRecordDecl *Class) { // members of Class itself. That is, the naming class is Class, and the // access includes the access of the base. for (const auto &BaseSpec : Class->bases()) { - CXXRecordDecl *RD = - cast( - BaseSpec.getType()->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *RD = BaseSpec.getType()->castAsCXXRecordDecl(); LookupResult Result(*this, R.getLookupNameInfo(), R.getLookupKind()); Result.setBaseObjectType(Context.getCanonicalTagType(Class)); LookupQualifiedName(Result, RD); @@ -3207,8 +3204,7 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) { // member’s class; else it has no associated class. case Type::Enum: { // FIXME: This should use the original decl. - EnumDecl *Enum = - cast(T)->getOriginalDecl()->getDefinitionOrSelf(); + auto *Enum = T->castAsEnumDecl(); DeclContext *Ctx = Enum->getDeclContext(); if (CXXRecordDecl *EnclosingClass = dyn_cast(Ctx)) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 7d800c446b595..8f666cee72937 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -18628,12 +18628,12 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, // the set of member candidates is empty. LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); Lookup.suppressDiagnostics(); - if (const auto *TyRec = Ty->getAs()) { + if (Ty->isRecordType()) { // Complete the type if it can be completed. // If the type is neither complete nor being defined, bail out now. bool IsComplete = SemaRef.isCompleteType(Loc, Ty); - RecordDecl *RD = TyRec->getOriginalDecl()->getDefinition(); - if (IsComplete || RD) { + auto *RD = Ty->castAsRecordDecl(); + if (IsComplete || RD->isBeingDefined()) { Lookup.clear(); SemaRef.LookupQualifiedName(Lookup, RD); if (Lookup.empty()) { diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 5678804d87f1f..d24550060893b 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -369,8 +369,8 @@ NarrowingKind StandardConversionSequence::getNarrowingKind( // A conversion to an enumeration type is narrowing if the conversion to // the underlying type is narrowing. This only arises for expressions of // the form 'Enum{init}'. - if (auto *ET = ToType->getAs()) - ToType = ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = ToType->getAsEnumDecl()) + ToType = ED->getIntegerType(); switch (Second) { // 'bool' is an integral type; dispatch to the right place to handle it. @@ -2661,11 +2661,9 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) { // integral promotion can be applied to its underlying type, a prvalue of an // unscoped enumeration type whose underlying type is fixed can also be // converted to a prvalue of the promoted underlying type. - if (const EnumType *FromEnumType = FromType->getAs()) { + if (const auto *FromED = FromType->getAsEnumDecl()) { // C++0x 7.2p9: Note that this implicit enum to int conversion is not // provided for a scoped enumeration. - const EnumDecl *FromED = - FromEnumType->getOriginalDecl()->getDefinitionOrSelf(); if (FromED->isScoped()) return false; @@ -4508,12 +4506,10 @@ getFixedEnumPromtion(Sema &S, const StandardConversionSequence &SCS) { if (SCS.Second != ICK_Integral_Promotion) return FixedEnumPromotion::None; - QualType FromType = SCS.getFromType(); - if (!FromType->isEnumeralType()) + const auto *Enum = SCS.getFromType()->getAsEnumDecl(); + if (!Enum) return FixedEnumPromotion::None; - EnumDecl *Enum = - FromType->castAs()->getOriginalDecl()->getDefinitionOrSelf(); if (!Enum->isFixed()) return FixedEnumPromotion::None; @@ -5149,10 +5145,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS, Expr *Init, QualType T2, bool AllowRvalues, bool AllowExplicit) { assert(T2->isRecordType() && "Can only find conversions of record types."); - auto *T2RecordDecl = - cast(T2->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); - + auto *T2RecordDecl = T2->castAsCXXRecordDecl(); OverloadCandidateSet CandidateSet( DeclLoc, OverloadCandidateSet::CSK_InitByUserDefinedConversion); const auto &Conversions = T2RecordDecl->getVisibleConversionFunctions(); @@ -8340,10 +8333,7 @@ void Sema::AddConversionCandidate( QualType ObjectType = From->getType(); if (const auto *FromPtrType = ObjectType->getAs()) ObjectType = FromPtrType->getPointeeType(); - const auto *ConversionContext = - cast(ObjectType->castAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); - + const auto *ConversionContext = ObjectType->castAsCXXRecordDecl(); // C++23 [over.best.ics.general] // However, if the target is [...] // - the object parameter of a user-defined conversion function @@ -9093,9 +9083,7 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty, if (!SemaRef.isCompleteType(Loc, Ty)) return; - auto *ClassDecl = - cast(Ty->getAs()->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *ClassDecl = Ty->castAsCXXRecordDecl(); for (NamedDecl *D : ClassDecl->getVisibleConversionFunctions()) { if (isa(D)) D = cast(D)->getTargetDecl(); @@ -10154,7 +10142,7 @@ class BuiltinOperatorOverloadBuilder { continue; for (QualType MemPtrTy : CandidateTypes[1].member_pointer_types()) { const MemberPointerType *mptr = cast(MemPtrTy); - CXXRecordDecl *D1 = C1->getAsCXXRecordDecl(), + CXXRecordDecl *D1 = C1->castAsCXXRecordDecl(), *D2 = mptr->getMostRecentCXXRecordDecl(); if (!declaresSameEntity(D1, D2) && !S.IsDerivedFrom(CandidateSet.getLocation(), D1, D2)) @@ -16352,9 +16340,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, diag::err_incomplete_object_call, Object.get())) return true; - const auto *Record = Object.get()->getType()->castAs(); + auto *Record = Object.get()->getType()->castAsCXXRecordDecl(); LookupResult R(*this, OpName, LParenLoc, LookupOrdinaryName); - LookupQualifiedName(R, Record->getOriginalDecl()->getDefinitionOrSelf()); + LookupQualifiedName(R, Record); R.suppressAccessDiagnostics(); for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); @@ -16373,8 +16361,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, // we filter them out to produce better error diagnostics, ie to avoid // showing 2 failed overloads instead of one. bool IgnoreSurrogateFunctions = false; - if (CandidateSet.nonDeferredCandidatesCount() == 1 && - Record->getAsCXXRecordDecl()->isLambda()) { + if (CandidateSet.nonDeferredCandidatesCount() == 1 && Record->isLambda()) { const OverloadCandidate &Candidate = *CandidateSet.begin(); if (!Candidate.Viable && Candidate.FailureKind == ovl_fail_constraints_not_satisfied) @@ -16398,9 +16385,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, // functions for each conversion function declared in an // accessible base class provided the function is not hidden // within T by another intervening declaration. - const auto &Conversions = cast(Record->getOriginalDecl()) - ->getDefinitionOrSelf() - ->getVisibleConversionFunctions(); + const auto &Conversions = Record->getVisibleConversionFunctions(); for (auto I = Conversions.begin(), E = Conversions.end(); !IgnoreSurrogateFunctions && I != E; ++I) { NamedDecl *D = *I; @@ -16621,10 +16606,7 @@ ExprResult Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, return ExprError(); LookupResult R(*this, OpName, OpLoc, LookupOrdinaryName); - LookupQualifiedName(R, Base->getType() - ->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf()); + LookupQualifiedName(R, Base->getType()->castAsRecordDecl()); R.suppressAccessDiagnostics(); for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); diff --git a/clang/lib/Sema/SemaPPC.cpp b/clang/lib/Sema/SemaPPC.cpp index 46d7372dd056b..bfa458d207b46 100644 --- a/clang/lib/Sema/SemaPPC.cpp +++ b/clang/lib/Sema/SemaPPC.cpp @@ -41,10 +41,7 @@ void SemaPPC::checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg) { return; QualType ArgType = Arg->getType(); - for (const FieldDecl *FD : ArgType->castAs() - ->getOriginalDecl() - ->getDefinitionOrSelf() - ->fields()) { + for (const FieldDecl *FD : ArgType->castAsRecordDecl()->fields()) { if (const auto *AA = FD->getAttr()) { CharUnits Alignment = getASTContext().toCharUnitsFromBits( AA->getAlignment(getASTContext())); diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index bc1ddb80961a2..dda4e00119212 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -1590,12 +1590,10 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, // we still do the analysis to preserve this information in the AST // (which can be used by flow-based analyes). // - const EnumType *ET = CondTypeBeforePromotion->getAs(); - // If switch has default case, then ignore it. if (!CaseListIsErroneous && !CaseListIsIncomplete && !HasConstantCond && - ET) { - const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + CondTypeBeforePromotion->isEnumeralType()) { + const auto *ED = CondTypeBeforePromotion->castAsEnumDecl(); if (!ED->isCompleteDefinition() || ED->enumerators().empty()) goto enum_out; @@ -1730,8 +1728,7 @@ void Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, Expr *SrcExpr) { - const auto *ET = DstType->getAs(); - if (!ET) + if (!DstType->isEnumeralType()) return; if (!SrcType->isIntegerType() || @@ -1741,7 +1738,7 @@ Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, if (SrcExpr->isTypeDependent() || SrcExpr->isValueDependent()) return; - const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + const auto *ED = DstType->castAsEnumDecl(); if (!ED->isClosed()) return; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index ff273ab6fd2f5..e7d981a3210d1 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -7411,9 +7411,8 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, // always a no-op, except when the parameter type is bool. In // that case, this may extend the argument from 1 bit to 8 bits. QualType IntegerType = ParamType; - if (const EnumType *Enum = IntegerType->getAs()) - IntegerType = - Enum->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = IntegerType->getAsEnumDecl()) + IntegerType = ED->getIntegerType(); Value = Value.extOrTrunc(IntegerType->isBitIntType() ? Context.getIntWidth(IntegerType) : Context.getTypeSize(IntegerType)); @@ -7510,9 +7509,8 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, } QualType IntegerType = ParamType; - if (const EnumType *Enum = IntegerType->getAs()) { - IntegerType = - Enum->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = IntegerType->getAsEnumDecl()) { + IntegerType = ED->getIntegerType(); } if (ParamType->isBooleanType()) { @@ -8028,8 +8026,8 @@ static Expr *BuildExpressionFromIntegralTemplateArgumentValue( // any integral type with C++11 enum classes, make sure we create the right // type of literal for it. QualType T = OrigT; - if (const EnumType *ET = OrigT->getAs()) - T = ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + if (const auto *ED = OrigT->getAsEnumDecl()) + T = ED->getIntegerType(); Expr *E; if (T->isAnyCharacterType()) { diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 015fb0577df39..3f31a05d382a6 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -9617,19 +9617,16 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T, if (T->isVariableArrayType()) return true; - const RecordType *RT = ElemType->getAs(); - if (!RT) + if (!ElemType->isRecordType()) return true; - const CXXRecordDecl *RD = - cast(RT->getOriginalDecl())->getDefinitionOrSelf(); - // A partially-defined class type can't be a literal type, because a literal // class type must have a trivial destructor (which can't be checked until // the class definition is complete). if (RequireCompleteType(Loc, ElemType, diag::note_non_literal_incomplete, T)) return true; + const auto *RD = ElemType->castAsCXXRecordDecl(); // [expr.prim.lambda]p3: // This class type is [not] a literal type. if (RD->isLambda() && !getLangOpts().CPlusPlus17) { diff --git a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp index 054b2e96bd13b..76a1470aaac44 100644 --- a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp @@ -139,18 +139,11 @@ void EnumCastOutOfRangeChecker::checkPreStmt(const CastExpr *CE, if (!ValueToCast) return; - const QualType T = CE->getType(); // Check whether the cast type is an enum. - if (!T->isEnumeralType()) + const auto *ED = CE->getType()->getAsEnumDecl(); + if (!ED) return; - // If the cast is an enum, get its declaration. - // If the isEnumeralType() returned true, then the declaration must exist - // even if it is a stub declaration. It is up to the getDeclValuesForEnum() - // function to handle this. - const EnumDecl *ED = - T->castAs()->getOriginalDecl()->getDefinitionOrSelf(); - // [[clang::flag_enum]] annotated enums are by definition should be ignored. if (ED->hasAttr()) return; diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 02375b0c3469a..6a82aa7ba3936 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -2844,9 +2844,7 @@ RegionStoreManager::bindStruct(LimitedRegionBindingsConstRef B, QualType T = R->getValueType(); assert(T->isStructureOrClassType()); - const RecordType* RT = T->castAs(); - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); - + const auto *RD = T->castAsRecordDecl(); if (!RD->isCompleteDefinition()) return B;