diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp index 7a0e00c6d9c2d..2b1f0f3c90c0c 100644 --- a/clang-tools-extra/clang-doc/Serialize.cpp +++ b/clang-tools-extra/clang-doc/Serialize.cpp @@ -895,8 +895,8 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir, return; for (const CXXBaseSpecifier &B : D->bases()) { if (const RecordType *Ty = B.getType()->getAs()) { - if (const CXXRecordDecl *Base = - cast_or_null(Ty->getDecl()->getDefinition())) { + if (const CXXRecordDecl *Base = cast_or_null( + Ty->getOriginalDecl()->getDefinition())) { // Initialized without USR and name, this will be set in the following // if-else stmt. BaseRecordInfo BI( diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp index b413b12cd37ab..40607597297b5 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp @@ -190,7 +190,7 @@ struct InitializerInsertion { // Convenience utility to get a RecordDecl from a QualType. const RecordDecl *getCanonicalRecordDecl(const QualType &Type) { if (const auto *RT = Type.getCanonicalType()->getAs()) - return RT->getDecl(); + return RT->getOriginalDecl(); return nullptr; } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp index 76754394de760..40fd15c08f0a1 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp @@ -92,7 +92,7 @@ void SlicingCheck::diagnoseSlicedOverriddenMethods( for (const auto &Base : DerivedDecl.bases()) { if (const auto *BaseRecordType = Base.getType()->getAs()) { if (const auto *BaseRecord = cast_or_null( - BaseRecordType->getDecl()->getDefinition())) + BaseRecordType->getOriginalDecl()->getDefinition())) diagnoseSlicedOverriddenMethods(Call, *BaseRecord, BaseDecl); } } diff --git a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp index 80ff97a762134..0302a5ad4957c 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp +++ b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp @@ -74,7 +74,7 @@ bool MultipleInheritanceCheck::isInterface(const CXXRecordDecl *Node) { const auto *Ty = I.getType()->getAs(); if (!Ty) continue; - const RecordDecl *D = Ty->getDecl()->getDefinition(); + const RecordDecl *D = Ty->getOriginalDecl()->getDefinition(); if (!D) continue; const auto *Base = cast(D); @@ -106,7 +106,8 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) { const auto *Ty = I.getType()->getAs(); if (!Ty) continue; - const auto *Base = cast(Ty->getDecl()->getDefinition()); + const auto *Base = + cast(Ty->getOriginalDecl()->getDefinition()); if (!isInterface(Base)) NumConcrete++; } @@ -117,7 +118,8 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) { const auto *Ty = V.getType()->getAs(); if (!Ty) continue; - const auto *Base = cast(Ty->getDecl()->getDefinition()); + const auto *Base = + cast(Ty->getOriginalDecl()->getDefinition()); if (!isInterface(Base)) NumConcrete++; } diff --git a/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp index 3deea0620514b..68233ec6bd441 100644 --- a/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp @@ -72,7 +72,7 @@ static bool isStdInitializerList(QualType Type) { } if (const auto *RT = Type->getAs()) { if (const auto *Specialization = - dyn_cast(RT->getDecl())) + dyn_cast(RT->getOriginalDecl())) return declIsStdInitializerList(Specialization->getSpecializedTemplate()); } return false; diff --git a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp index e5e8c91a9da30..8211a0ec6a5e1 100644 --- a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp @@ -132,7 +132,7 @@ void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) { } if (const auto *ECD = dyn_cast(Used)) { if (const auto *ET = ECD->getType()->getAs()) - removeFromFoundDecls(ET->getDecl()); + removeFromFoundDecls(ET->getOriginalDecl()); } }; // We rely on the fact that the clang AST is walked in order, usages are only diff --git a/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp index 7329b99e4b915..5310f2fd25381 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp @@ -29,7 +29,7 @@ static bool isLockGuardDecl(const NamedDecl *Decl) { static bool isLockGuard(const QualType &Type) { if (const auto *Record = Type->getAs()) - if (const RecordDecl *Decl = Record->getDecl()) + if (const RecordDecl *Decl = Record->getOriginalDecl()) return isLockGuardDecl(Decl); if (const auto *TemplateSpecType = Type->getAs()) diff --git a/clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp b/clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp index 5a04029e4a6fa..447c2437666cf 100644 --- a/clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp @@ -414,9 +414,9 @@ static bool areTypesCompatible(QualType ArgType, QualType ParamType, // Arithmetic types are interconvertible, except scoped enums. if (ParamType->isArithmeticType() && ArgType->isArithmeticType()) { if ((ParamType->isEnumeralType() && - ParamType->castAs()->getDecl()->isScoped()) || + ParamType->castAs()->getOriginalDecl()->isScoped()) || (ArgType->isEnumeralType() && - ArgType->castAs()->getDecl()->isScoped())) + ArgType->castAs()->getOriginalDecl()->isScoped())) return false; return true; diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp index 0637d0eff688c..aa6aefcf0c493 100644 --- a/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp +++ b/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp @@ -66,7 +66,8 @@ ExceptionSpecAnalyzer::analyzeBase(const CXXBaseSpecifier &Base, if (!RecType) return State::Unknown; - const auto *BaseClass = cast(RecType->getDecl()); + const auto *BaseClass = + cast(RecType->getOriginalDecl())->getDefinitionOrSelf(); return analyzeRecord(BaseClass, Kind); } diff --git a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp index 7f4ccca84faa5..3229efb957067 100644 --- a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp +++ b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp @@ -465,8 +465,9 @@ bool FormatStringConverter::emitIntegerArgument( // 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->getDecl()->getIntegerType())) + if (const std::optional MaybeCastType = castTypeForArgument( + ArgKind, + ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType())) ArgFixes.emplace_back( ArgIndex, (Twine("static_cast<") + *MaybeCastType + ">(").str()); else diff --git a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp index 44db0c2aed607..96d3a5bbd86a2 100644 --- a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp +++ b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp @@ -124,7 +124,8 @@ bool isTriviallyDefaultConstructible(QualType Type, const ASTContext &Context) { return true; if (const auto *RT = CanonicalType->getAs()) { - return recordIsTriviallyDefaultConstructible(*RT->getDecl(), Context); + return recordIsTriviallyDefaultConstructible( + *RT->getOriginalDecl()->getDefinitionOrSelf(), Context); } // No other types can match. diff --git a/clang-tools-extra/clangd/DumpAST.cpp b/clang-tools-extra/clangd/DumpAST.cpp index 54e15b2f553c6..14e14a5e9f544 100644 --- a/clang-tools-extra/clangd/DumpAST.cpp +++ b/clang-tools-extra/clangd/DumpAST.cpp @@ -261,7 +261,7 @@ class DumpVisitor : public RecursiveASTVisitor { return TL.getType().getLocalQualifiers().getAsString( Ctx.getPrintingPolicy()); if (const auto *TT = dyn_cast(TL.getTypePtr())) - return getDetail(TT->getDecl()); + return getDetail(TT->getOriginalDecl()); if (const auto *DT = dyn_cast(TL.getTypePtr())) if (DT->isDeduced()) return DT->getDeducedType().getAsString(Ctx.getPrintingPolicy()); diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp index d9b684b3952aa..a5ab40e4221f1 100644 --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -878,7 +878,7 @@ refInTypeLoc(TypeLoc L, const HeuristicResolver *Resolver) { Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(), L.getNameLoc(), /*IsDecl=*/false, - {L.getDecl()}}); + {L.getOriginalDecl()}}); } void VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc L) { diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp index 3aac570f33478..f4b312cde6349 100644 --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -452,7 +452,7 @@ std::optional printExprValue(const Expr *E, // Compare to int64_t to avoid bit-width match requirements. int64_t Val = Constant.Val.getInt().getExtValue(); for (const EnumConstantDecl *ECD : - T->castAs()->getDecl()->enumerators()) + T->castAs()->getOriginalDecl()->enumerators()) if (ECD->getInitVal() == Val) return llvm::formatv("{0} ({1})", ECD->getNameAsString(), printHex(Constant.Val.getInt())) diff --git a/clang-tools-extra/clangd/IncludeFixer.cpp b/clang-tools-extra/clangd/IncludeFixer.cpp index 50bc2bd7ccb94..cc1125e705674 100644 --- a/clang-tools-extra/clangd/IncludeFixer.cpp +++ b/clang-tools-extra/clangd/IncludeFixer.cpp @@ -173,7 +173,7 @@ std::vector IncludeFixer::fix(DiagnosticsEngine::Level DiagLevel, // `enum x : int;' is not formally an incomplete type. // We may need a full definition anyway. if (auto * ET = llvm::dyn_cast(T)) - if (!ET->getDecl()->getDefinition()) + if (!ET->getOriginalDecl()->getDefinition()) return fixIncompleteType(*T); } } diff --git a/clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp b/clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp index 43cfc769f7f71..7e616968c6046 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp @@ -116,7 +116,7 @@ bool PopulateSwitch::prepare(const Selection &Sel) { EnumT = Cond->getType().getCanonicalType()->getAsAdjusted(); if (!EnumT) return false; - EnumD = EnumT->getDecl(); + EnumD = EnumT->getOriginalDecl(); if (!EnumD || EnumD->isDependentType()) return false; diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index 6f51fa68f45b8..ff64b0b257572 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -337,17 +337,17 @@ class ASTWalker : public RecursiveASTVisitor { } bool VisitUsingTypeLoc(UsingTypeLoc TL) { - reportType(TL.getNameLoc(), TL.getFoundDecl()); + reportType(TL.getNameLoc(), TL.getDecl()); return true; } bool VisitTagTypeLoc(TagTypeLoc TTL) { - reportType(TTL.getNameLoc(), TTL.getDecl()); + reportType(TTL.getNameLoc(), TTL.getOriginalDecl()); return true; } bool VisitTypedefTypeLoc(TypedefTypeLoc TTL) { - reportType(TTL.getNameLoc(), TTL.getTypedefNameDecl()); + reportType(TTL.getNameLoc(), TTL.getDecl()); return true; } diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index ca50227b2426a..23a683ededa87 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -8867,8 +8867,8 @@ inline bool Type::isIntegerType() const { if (const EnumType *ET = dyn_cast(CanonicalType)) { // Incomplete enum types are not treated as integer types. // FIXME: In C++, enum types are never integer types. - return IsEnumDeclComplete(ET->getDecl()) && - !IsEnumDeclScoped(ET->getDecl()); + return IsEnumDeclComplete(ET->getOriginalDecl()) && + !IsEnumDeclScoped(ET->getOriginalDecl()); } return isBitIntType(); } @@ -8926,7 +8926,7 @@ inline bool Type::isScalarType() const { if (const EnumType *ET = dyn_cast(CanonicalType)) // Enums are scalar types, but only if they are defined. Incomplete enums // are not treated as scalar types. - return IsEnumDeclComplete(ET->getDecl()); + return IsEnumDeclComplete(ET->getOriginalDecl()); return isa(CanonicalType) || isa(CanonicalType) || isa(CanonicalType) || @@ -8942,7 +8942,7 @@ inline bool Type::isIntegralOrEnumerationType() const { // Check for a complete enum type; incomplete enum types are not properly an // enumeration type in the sense required here. if (const auto *ET = dyn_cast(CanonicalType)) - return IsEnumDeclComplete(ET->getDecl()); + return IsEnumDeclComplete(ET->getOriginalDecl()); return isBitIntType(); } diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index ee3dc84479fd9..2d62209bbc28c 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -902,8 +902,9 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy, } case APValue::Struct: { Out << '{'; - const RecordDecl *RD = Ty->castAs()->getDecl(); bool First = true; + const RecordDecl *RD = + Ty->castAs()->getOriginalDecl()->getDefinitionOrSelf(); 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 ae8ad43a931ad..399e993bfc9f5 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -653,7 +653,7 @@ comments::FullComment *ASTContext::getCommentForDecl( // does not have one of its own. QualType QT = TD->getUnderlyingType(); if (const auto *TT = QT->getAs()) - if (const Decl *TD = TT->getDecl()) + if (const Decl *TD = TT->getOriginalDecl()) if (comments::FullComment *FC = getCommentForDecl(TD, PP)) return cloneFullComment(FC, D); } @@ -1931,10 +1931,12 @@ TypeInfoChars ASTContext::getTypeInfoDataSizeInChars(QualType T) const { // of a base-class subobject. We decide whether that's possible // during class layout, so here we can just trust the layout results. if (getLangOpts().CPlusPlus) { - if (const auto *RT = T->getAs(); - RT && !RT->getDecl()->isInvalidDecl()) { - const ASTRecordLayout &layout = getASTRecordLayout(RT->getDecl()); - Info.Width = layout.getDataSize(); + if (const auto *RT = T->getAs()) { + const auto *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + if (!RD->isInvalidDecl()) { + const ASTRecordLayout &layout = getASTRecordLayout(RD); + Info.Width = layout.getDataSize(); + } } } @@ -2001,8 +2003,9 @@ 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()) { - if (T->isDependentType() || ET->getDecl()->getPromotionType().isNull() || - ET->getDecl()->isScoped()) + const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + if (T->isDependentType() || ED->getPromotionType().isNull() || + ED->isScoped()) return false; return true; @@ -2470,15 +2473,16 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { case Type::Record: case Type::Enum: { const auto *TT = cast(T); + const TagDecl *TD = TT->getOriginalDecl()->getDefinitionOrSelf(); - if (TT->getDecl()->isInvalidDecl()) { + if (TD->isInvalidDecl()) { Width = 8; Align = 8; break; } - if (const auto *ET = dyn_cast(TT)) { - const EnumDecl *ED = ET->getDecl(); + if (isa(TT)) { + const EnumDecl *ED = cast(TD); TypeInfo Info = getTypeInfo(ED->getIntegerType()->getUnqualifiedDesugaredType()); if (unsigned AttrAlign = ED->getMaxAlignment()) { @@ -2613,8 +2617,7 @@ unsigned ASTContext::getTypeUnadjustedAlign(const Type *T) const { unsigned UnadjustedAlign; if (const auto *RT = T->getAs()) { - const RecordDecl *RD = RT->getDecl(); - const ASTRecordLayout &Layout = getASTRecordLayout(RD); + const ASTRecordLayout &Layout = getASTRecordLayout(RT->getOriginalDecl()); UnadjustedAlign = toBits(Layout.getUnadjustedAlignment()); } else if (const auto *ObjCI = T->getAs()) { const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl()); @@ -2690,7 +2693,7 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const { return ABIAlign; if (const auto *RT = T->getAs()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); // When used as part of a typedef, or together with a 'packed' attribute, // the 'aligned' attribute can be used to decrease alignment. Note that the @@ -2713,7 +2716,10 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const { if (const auto *CT = T->getAs()) T = CT->getElementType().getTypePtr(); if (const auto *ET = T->getAs()) - T = ET->getDecl()->getIntegerType().getTypePtr(); + T = ET->getOriginalDecl() + ->getDefinitionOrSelf() + ->getIntegerType() + .getTypePtr(); if (T->isSpecificBuiltinType(BuiltinType::Double) || T->isSpecificBuiltinType(BuiltinType::LongLong) || T->isSpecificBuiltinType(BuiltinType::ULongLong) || @@ -3040,7 +3046,8 @@ bool ASTContext::hasUniqueObjectRepresentations( return !ABI->getMemberPointerInfo(MPT).HasPadding; if (Ty->isRecordType()) { - const RecordDecl *Record = Ty->castAs()->getDecl(); + const RecordDecl *Record = + Ty->castAs()->getOriginalDecl()->getDefinitionOrSelf(); if (Record->isInvalidDecl()) return false; @@ -3413,7 +3420,10 @@ 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)->getDecl()->getIntegerType(); + QualType UnderlyingType = cast(T) + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->getIntegerType(); return encodeTypeForFunctionPointerAuth( Ctx, OS, UnderlyingType.isNull() ? Ctx.IntTy : UnderlyingType); } @@ -3557,7 +3567,8 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx, llvm_unreachable("should never get here"); } case Type::Record: { - const RecordDecl *RD = T->castAs()->getDecl(); + const RecordDecl *RD = + T->castAs()->getOriginalDecl()->getDefinitionOrSelf(); const IdentifierInfo *II = RD->getIdentifier(); // In C++, an immediate typedef of an anonymous struct or union @@ -8381,7 +8392,7 @@ QualType ASTContext::getPromotedIntegerType(QualType Promotable) const { assert(!Promotable.isNull()); assert(isPromotableIntegerType(Promotable)); if (const auto *ET = Promotable->getAs()) - return ET->getDecl()->getPromotionType(); + return ET->getOriginalDecl()->getDefinitionOrSelf()->getPromotionType(); if (const auto *BT = Promotable->getAs()) { // C++ [conv.prom]: A prvalue of type char16_t, char32_t, or wchar_t @@ -8440,8 +8451,9 @@ Qualifiers::ObjCLifetime ASTContext::getInnerObjCOwnership(QualType T) const { static const Type *getIntegerTypeForEnum(const EnumType *ET) { // Incomplete enum types are not treated as integer types. // FIXME: In C++, enum types are never integer types. - if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped()) - return ET->getDecl()->getIntegerType().getTypePtr(); + const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + if (ED->isComplete() && !ED->isScoped()) + return ED->getIntegerType().getTypePtr(); return nullptr; } @@ -8602,7 +8614,7 @@ void ASTContext::setCFConstantStringType(QualType T) { const auto *TD = T->castAs(); CFConstantStringTypeDecl = cast(TD->getDecl()); const auto *TagType = TD->castAs(); - CFConstantStringTagDecl = TagType->getDecl(); + CFConstantStringTagDecl = TagType->getOriginalDecl()->getDefinitionOrSelf(); } QualType ASTContext::getBlockDescriptorType() const { @@ -9314,7 +9326,7 @@ static char getObjCEncodingForPrimitiveType(const ASTContext *C, } static char ObjCEncodingForEnumType(const ASTContext *C, const EnumType *ET) { - EnumDecl *Enum = ET->getDecl(); + EnumDecl *Enum = ET->getOriginalDecl()->getDefinitionOrSelf(); // The encoding of an non-fixed enum type is always 'i', regardless of size. if (!Enum->isFixed()) @@ -9483,13 +9495,14 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S, return; } } else if (const auto *RTy = PointeeTy->getAs()) { + const IdentifierInfo *II = RTy->getOriginalDecl()->getIdentifier(); // GCC binary compat: Need to convert "struct objc_class *" to "#". - if (RTy->getDecl()->getIdentifier() == &Idents.get("objc_class")) { + if (II == &Idents.get("objc_class")) { S += '#'; return; } // GCC binary compat: Need to convert "struct objc_object *" to "@". - if (RTy->getDecl()->getIdentifier() == &Idents.get("objc_object")) { + if (II == &Idents.get("objc_object")) { S += '@'; return; } @@ -9554,7 +9567,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S, return; case Type::Record: { - RecordDecl *RDecl = cast(CT)->getDecl(); + RecordDecl *RDecl = cast(CT)->getOriginalDecl(); S += RDecl->isUnion() ? '(' : '{'; // Anonymous structures print as '?' if (const IdentifierInfo *II = RDecl->getIdentifier()) { @@ -11452,7 +11465,7 @@ QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType, bool OfBlockPointer, bool Unqualified) { if (const RecordType *UT = T->getAsUnionType()) { - RecordDecl *UD = UT->getDecl(); + RecordDecl *UD = UT->getOriginalDecl()->getMostRecentDecl(); if (UD->hasAttr()) { for (const auto *I : UD->fields()) { QualType ET = I->getType().getUnqualifiedType(); @@ -11684,7 +11697,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->getDecl()->getIntegerType(); + paramTy = + Enum->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); if (paramTy.isNull()) return {}; } @@ -11716,7 +11730,8 @@ static QualType mergeEnumWithInteger(ASTContext &Context, const EnumType *ET, // a signed integer type, or an unsigned integer type. // Compatibility is based on the underlying type, not the promotion // type. - QualType underlyingType = ET->getDecl()->getIntegerType(); + QualType underlyingType = + ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); if (underlyingType.isNull()) return {}; if (Context.hasSameType(underlyingType, other)) @@ -12275,7 +12290,7 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) { unsigned ASTContext::getIntWidth(QualType T) const { if (const auto *ET = T->getAs()) - T = ET->getDecl()->getIntegerType(); + T = ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); if (T->isBooleanType()) return 1; if (const auto *EIT = T->getAs()) @@ -12301,7 +12316,7 @@ 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->getDecl()->getIntegerType(); + T = ETy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); switch (T->castAs()->getKind()) { case BuiltinType::Char_U: @@ -12375,7 +12390,7 @@ 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->getDecl()->getIntegerType(); + T = ETy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); switch (T->castAs()->getKind()) { case BuiltinType::Char_S: @@ -14360,13 +14375,15 @@ static QualType getCommonNonSugarTypeNode(const ASTContext &Ctx, const Type *X, getCommonElementType(Ctx, VX, VY), getCommonSizeExpr(Ctx, VX, VY), getCommonAttrLoc(VX, VY), VX->getVectorKind()); } + case Type::Enum: + case Type::Record: case Type::InjectedClassName: { - const auto *IX = cast(X), - *IY = cast(Y); - return Ctx.getInjectedClassNameType( - getCommonDeclChecked(IX->getDecl(), IY->getDecl()), - Ctx.getCommonSugaredType(IX->getInjectedSpecializationType(), - IY->getInjectedSpecializationType())); + const auto *TX = cast(X), *TY = cast(Y); + return Ctx.getTagType( + ::getCommonTypeKeyword(TX, TY, /*IsSame=*/false), + ::getCommonQualifier(Ctx, TX, TY, /*IsSame=*/false), + ::getCommonDeclChecked(TX->getOriginalDecl(), TY->getOriginalDecl()), + /*OwnedTag=*/false); } case Type::TemplateSpecialization: { const auto *TX = cast(X), diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index 6049bfb64ebbe..ee09b92715b93 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -196,7 +196,8 @@ break; \ // Don't desugar through the primary typedef of an anonymous type. if (const TagType *UTT = Underlying->getAs()) if (const TypedefType *QTT = dyn_cast(QT)) - if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl()) + if (UTT->getOriginalDecl()->getTypedefNameForAnonDecl() == + QTT->getDecl()) break; // Record that we actually looked through an opaque type here. @@ -1153,7 +1154,7 @@ class TemplateDiff { return nullptr; const ClassTemplateSpecializationDecl *CTSD = - dyn_cast(RT->getDecl()); + dyn_cast(RT->getOriginalDecl()); if (!CTSD) return nullptr; diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 5191c19b7258c..46d64b16a7624 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -2157,7 +2157,7 @@ Error ASTNodeImporter::ImportDeclParts( const Type *LeafT = getLeafPointeeType(P->getType().getCanonicalType().getTypePtr()); auto *RT = dyn_cast(LeafT); - if (RT && RT->getDecl() == D) { + if (RT && RT->getOriginalDecl() == D) { Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node) << D->getDeclKindName(); return make_error(ASTImportError::UnsupportedConstruct); @@ -2410,8 +2410,8 @@ Error ASTNodeImporter::ImportFieldDeclDefinition(const FieldDecl *From, const RecordType *RecordTo = ToType->getAs(); if (RecordFrom && RecordTo) { - FromRecordDecl = RecordFrom->getDecl(); - ToRecordDecl = RecordTo->getDecl(); + FromRecordDecl = RecordFrom->getOriginalDecl(); + ToRecordDecl = RecordTo->getOriginalDecl(); } } @@ -3207,7 +3207,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) { if (auto *Typedef = dyn_cast(FoundDecl)) { if (const auto *Tag = Typedef->getUnderlyingType()->getAs()) - FoundDecl = Tag->getDecl(); + FoundDecl = Tag->getOriginalDecl(); } if (auto *FoundEnum = dyn_cast(FoundDecl)) { @@ -3338,7 +3338,7 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) { Decl *Found = FoundDecl; if (auto *Typedef = dyn_cast(Found)) { if (const auto *Tag = Typedef->getUnderlyingType()->getAs()) - Found = Tag->getDecl(); + Found = Tag->getOriginalDecl(); } if (auto *FoundRecord = dyn_cast(Found)) { @@ -3759,11 +3759,12 @@ class IsTypeDeclaredInsideVisitor } std::optional VisitTagType(const TagType *T) { - if (auto *Spec = dyn_cast(T->getDecl())) + if (auto *Spec = + dyn_cast(T->getOriginalDecl())) for (const auto &Arg : Spec->getTemplateArgs().asArray()) if (checkTemplateArgument(Arg)) return true; - return isAncestorDeclContextOf(ParentDC, T->getDecl()); + return isAncestorDeclContextOf(ParentDC, T->getOriginalDecl()); } std::optional VisitPointerType(const PointerType *T) { diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp index abf40660bd3f9..f7c8c14d071e4 100644 --- a/clang/lib/AST/ASTStructuralEquivalence.cpp +++ b/clang/lib/AST/ASTStructuralEquivalence.cpp @@ -1522,8 +1522,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, // types if (Field1->isAnonymousStructOrUnion() && Field2->isAnonymousStructOrUnion()) { - RecordDecl *D1 = Field1->getType()->castAs()->getDecl(); - RecordDecl *D2 = Field2->getType()->castAs()->getDecl(); + RecordDecl *D1 = Field1->getType()->castAs()->getOriginalDecl(); + RecordDecl *D2 = Field2->getType()->castAs()->getOriginalDecl(); return IsStructurallyEquivalent(Context, D1, D2); } @@ -2548,7 +2548,7 @@ StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl *Anon) { // struct { ... } A; QualType FieldType = F->getType(); if (const auto *RecType = dyn_cast(FieldType)) { - const RecordDecl *RecDecl = RecType->getDecl(); + const RecordDecl *RecDecl = RecType->getOriginalDecl(); if (RecDecl->getDeclContext() == Owner && !RecDecl->getIdentifier()) { if (Context.hasSameType(FieldType, AnonTy)) break; diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 65ad7caf8913b..59aa9654abd25 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -537,9 +537,10 @@ 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()) { - if (const auto *ET = CE->getType().getCanonicalType()->castAs(); - !ET->getDecl()->isFixed()) { - if (!this->emitCheckEnumValue(*FromT, ET->getDecl(), CE)) + const auto *ET = CE->getType().getCanonicalType()->castAs(); + const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + if (!ED->isFixed()) { + if (!this->emitCheckEnumValue(*FromT, ED, CE)) return false; } } @@ -4564,7 +4565,7 @@ const RecordType *Compiler::getRecordTy(QualType Ty) { template Record *Compiler::getRecord(QualType Ty) { if (const auto *RecordTy = getRecordTy(Ty)) - return getRecord(RecordTy->getDecl()); + return getRecord(RecordTy->getOriginalDecl()->getDefinitionOrSelf()); return nullptr; } diff --git a/clang/lib/AST/ByteCode/Context.cpp b/clang/lib/AST/ByteCode/Context.cpp index ead6e4af5d403..7b8523c7665e2 100644 --- a/clang/lib/AST/ByteCode/Context.cpp +++ b/clang/lib/AST/ByteCode/Context.cpp @@ -327,7 +327,7 @@ std::optional Context::classify(QualType T) const { } if (const auto *ET = T->getAs()) { - const auto *D = ET->getDecl(); + const auto *D = ET->getOriginalDecl()->getDefinitionOrSelf(); if (!D->isComplete()) return std::nullopt; return classify(D->getIntegerType()); diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 462b9a11e0a5c..636219f536a9c 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -2757,7 +2757,7 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, const RecordType *RT = CurrentType->getAs(); if (!RT) return false; - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->isInvalidDecl()) return false; const ASTRecordLayout &RL = S.getASTContext().getASTRecordLayout(RD); @@ -2790,7 +2790,7 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, const RecordType *RT = CurrentType->getAs(); if (!RT) return false; - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->isInvalidDecl()) return false; const ASTRecordLayout &RL = S.getASTContext().getASTRecordLayout(RD); @@ -2802,7 +2802,8 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, return false; // Add the offset to the base. - Result += RL.getBaseClassOffset(cast(BaseRT->getDecl())); + Result += RL.getBaseClassOffset(cast( + BaseRT->getOriginalDecl()->getDefinitionOrSelf())); break; } case OffsetOfNode::Identifier: diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp index 5b2fcb11f3b08..bf6365b89c9f1 100644 --- a/clang/lib/AST/ByteCode/Pointer.cpp +++ b/clang/lib/AST/ByteCode/Pointer.cpp @@ -675,7 +675,7 @@ std::optional Pointer::toRValue(const Context &Ctx, assert(Record && "Missing record descriptor"); bool Ok = true; - if (RT->getDecl()->isUnion()) { + if (RT->getOriginalDecl()->isUnion()) { const FieldDecl *ActiveField = nullptr; APValue Value; for (const auto &F : Record->fields()) { diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp index 5ac0f59f32d4e..47dd6f082bc48 100644 --- a/clang/lib/AST/ByteCode/Program.cpp +++ b/clang/lib/AST/ByteCode/Program.cpp @@ -326,7 +326,7 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) { const auto *RT = Spec.getType()->getAs(); if (!RT) return nullptr; - const RecordDecl *BD = RT->getDecl(); + const RecordDecl *BD = RT->getOriginalDecl()->getDefinitionOrSelf(); const Record *BR = getOrCreateRecord(BD); const Descriptor *Desc = GetBaseDesc(BD, BR); @@ -343,7 +343,7 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) { if (!RT) return nullptr; - const RecordDecl *BD = RT->getDecl(); + const RecordDecl *BD = RT->getOriginalDecl()->getDefinitionOrSelf(); const Record *BR = getOrCreateRecord(BD); const Descriptor *Desc = GetBaseDesc(BD, BR); @@ -400,7 +400,8 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty, // Classes and structures. if (const auto *RT = Ty->getAs()) { - if (const auto *Record = getOrCreateRecord(RT->getDecl())) + if (const auto *Record = + getOrCreateRecord(RT->getOriginalDecl()->getDefinitionOrSelf())) return allocateDescriptor(D, Record, MDSize, IsConst, IsTemporary, IsMutable, IsVolatile); return allocateDescriptor(D, MDSize); diff --git a/clang/lib/AST/ByteCode/Record.cpp b/clang/lib/AST/ByteCode/Record.cpp index 1d4ac7103cb76..a7934ccb4e55e 100644 --- a/clang/lib/AST/ByteCode/Record.cpp +++ b/clang/lib/AST/ByteCode/Record.cpp @@ -51,7 +51,7 @@ const Record::Base *Record::getBase(const RecordDecl *FD) const { const Record::Base *Record::getBase(QualType T) const { if (auto *RT = T->getAs()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); return BaseMap.lookup(RD); } return nullptr; diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp index f0376168e43a2..e4b77edc063dc 100644 --- a/clang/lib/AST/CXXInheritance.cpp +++ b/clang/lib/AST/CXXInheritance.cpp @@ -132,8 +132,8 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches) const { if (!Ty) return false; - CXXRecordDecl *Base = - cast_if_present(Ty->getDecl()->getDefinition()); + CXXRecordDecl *Base = cast_if_present( + Ty->getOriginalDecl()->getDefinition()); if (!Base || (Base->isDependentContext() && !Base->isCurrentInstantiation(Record))) { @@ -256,7 +256,8 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context, BaseSpec.getType()->getAs(); if (!TST) { if (auto *RT = BaseSpec.getType()->getAs()) - BaseRecord = cast(RT->getDecl()); + BaseRecord = cast(RT->getOriginalDecl()) + ->getDefinitionOrSelf(); } else { TemplateName TN = TST->getTemplateName(); if (auto *TD = @@ -336,7 +337,8 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches, CXXRecordDecl *VBase = nullptr; if (const RecordType *Record = PE.Base->getType()->getAs()) - VBase = cast(Record->getDecl()); + VBase = cast(Record->getOriginalDecl()) + ->getDefinitionOrSelf(); if (!VBase) break; @@ -348,7 +350,8 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches, CXXRecordDecl *HidingClass = nullptr; if (const RecordType *Record = HidingP.back().Base->getType()->getAs()) - HidingClass = cast(Record->getDecl()); + HidingClass = cast(Record->getOriginalDecl()) + ->getDefinitionOrSelf(); if (!HidingClass) break; @@ -468,7 +471,8 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD, for (const auto &Base : RD->bases()) { if (const RecordType *RT = Base.getType()->getAs()) { - const CXXRecordDecl *BaseDecl = cast(RT->getDecl()); + const CXXRecordDecl *BaseDecl = + cast(RT->getOriginalDecl())->getDefinitionOrSelf(); if (!BaseDecl->isPolymorphic()) continue; diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index d3b05b6a80fe6..891f0f3a0b45b 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2861,7 +2861,8 @@ VarDecl::needsDestruction(const ASTContext &Ctx) const { bool VarDecl::hasFlexibleArrayInit(const ASTContext &Ctx) const { assert(hasInit() && "Expect initializer to check for flexible array init"); auto *Ty = getType()->getAs(); - if (!Ty || !Ty->getDecl()->hasFlexibleArrayMember()) + if (!Ty || + !Ty->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember()) return false; auto *List = dyn_cast(getInit()->IgnoreParens()); if (!List) @@ -2876,7 +2877,10 @@ bool VarDecl::hasFlexibleArrayInit(const ASTContext &Ctx) const { CharUnits VarDecl::getFlexibleArrayInitChars(const ASTContext &Ctx) const { assert(hasInit() && "Expect initializer to check for flexible array init"); auto *Ty = getType()->getAs(); - if (!Ty || !Ty->getDecl()->hasFlexibleArrayMember()) + if (!Ty) + return CharUnits::Zero(); + const RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf(); + if (!Ty || !RD->hasFlexibleArrayMember()) return CharUnits::Zero(); auto *List = dyn_cast(getInit()->IgnoreParens()); if (!List || List->getNumInits() == 0) @@ -2988,7 +2992,10 @@ bool ParmVarDecl::isDestroyedInCallee() const { // FIXME: isParamDestroyedInCallee() should probably imply // isDestructedType() const auto *RT = getType()->getAs(); - if (RT && RT->getDecl()->isParamDestroyedInCallee() && + if (RT && + RT->getOriginalDecl() + ->getDefinitionOrSelf() + ->isParamDestroyedInCallee() && getType().isDestructedType()) return true; @@ -3499,7 +3506,7 @@ bool FunctionDecl::isUsableAsGlobalAllocationFunctionInConstantEvaluation( while (const auto *TD = T->getAs()) T = TD->getDecl()->getUnderlyingType(); const IdentifierInfo *II = - T->castAs()->getDecl()->getIdentifier(); + T->castAs()->getOriginalDecl()->getIdentifier(); if (II && II->isStr("__hot_cold_t")) Consume(); } @@ -4650,7 +4657,7 @@ bool FieldDecl::isAnonymousStructOrUnion() const { return false; if (const auto *Record = getType()->getAs()) - return Record->getDecl()->isAnonymousStructOrUnion(); + return Record->getOriginalDecl()->isAnonymousStructOrUnion(); return false; } @@ -4710,7 +4717,7 @@ bool FieldDecl::isZeroSize(const ASTContext &Ctx) const { const auto *RT = getType()->getAs(); if (!RT) return false; - const RecordDecl *RD = RT->getDecl()->getDefinition(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinition(); if (!RD) { assert(isInvalidDecl() && "valid field has incomplete type"); return false; @@ -5135,7 +5142,7 @@ bool RecordDecl::isOrContainsUnion() const { if (const RecordDecl *Def = getDefinition()) { for (const FieldDecl *FD : Def->fields()) { const RecordType *RT = FD->getType()->getAs(); - if (RT && RT->getDecl()->isOrContainsUnion()) + if (RT && RT->getOriginalDecl()->isOrContainsUnion()) return true; } } @@ -5267,8 +5274,9 @@ const FieldDecl *RecordDecl::findFirstNamedDataMember() const { return I; if (const auto *RT = I->getType()->getAs()) - if (const FieldDecl *NamedDataMember = - RT->getDecl()->findFirstNamedDataMember()) + if (const FieldDecl *NamedDataMember = RT->getOriginalDecl() + ->getDefinitionOrSelf() + ->findFirstNamedDataMember()) return NamedDataMember; } @@ -5630,14 +5638,14 @@ void TypedefNameDecl::anchor() {} TagDecl *TypedefNameDecl::getAnonDeclWithTypedefName(bool AnyRedecl) const { if (auto *TT = getTypeSourceInfo()->getType()->getAs()) { - auto *OwningTypedef = TT->getDecl()->getTypedefNameForAnonDecl(); + auto *OwningTypedef = TT->getOriginalDecl()->getTypedefNameForAnonDecl(); auto *ThisTypedef = this; if (AnyRedecl && OwningTypedef) { OwningTypedef = OwningTypedef->getCanonicalDecl(); ThisTypedef = ThisTypedef->getCanonicalDecl(); } if (OwningTypedef == ThisTypedef) - return TT->getDecl(); + return TT->getOriginalDecl()->getDefinitionOrSelf(); } return nullptr; @@ -5646,7 +5654,7 @@ TagDecl *TypedefNameDecl::getAnonDeclWithTypedefName(bool AnyRedecl) const { bool TypedefNameDecl::isTransparentTagSlow() const { auto determineIsTransparent = [&]() { if (auto *TT = getUnderlyingType()->getAs()) { - if (auto *TD = TT->getDecl()) { + if (auto *TD = TT->getOriginalDecl()) { if (TD->getName() != getName()) return false; SourceLocation TTLoc = getLocation(); diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 6029590cf06a5..6ab0650171301 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -217,7 +217,8 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, if (BaseType->isDependentType()) continue; auto *BaseClassDecl = - cast(BaseType->castAs()->getDecl()); + cast(BaseType->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); // C++2a [class]p7: // A standard-layout class is a class that: @@ -1207,7 +1208,7 @@ void CXXRecordDecl::addedMember(Decl *D) { bool IsZeroSize = Field->isZeroSize(Context); if (const auto *RecordTy = T->getAs()) { - auto *FieldRec = cast(RecordTy->getDecl()); + auto *FieldRec = cast(RecordTy->getOriginalDecl()); if (FieldRec->getDefinition()) { addedClassSubobject(FieldRec); @@ -1914,7 +1915,8 @@ static void CollectVisibleConversions( = CXXRecordDecl::MergeAccess(Access, I.getAccessSpecifier()); bool BaseInVirtual = InVirtual || I.isVirtual(); - auto *Base = cast(RT->getDecl()); + auto *Base = + cast(RT->getOriginalDecl())->getDefinitionOrSelf(); CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess, *HiddenTypes, Output, VOutput, HiddenVBaseCs); } @@ -1952,9 +1954,11 @@ static void CollectVisibleConversions(ASTContext &Context, const auto *RT = I.getType()->getAs(); if (!RT) continue; - CollectVisibleConversions(Context, cast(RT->getDecl()), - I.isVirtual(), I.getAccessSpecifier(), - HiddenTypes, Output, VBaseCs, HiddenVBaseCs); + CollectVisibleConversions( + Context, + cast(RT->getOriginalDecl())->getDefinitionOrSelf(), + I.isVirtual(), I.getAccessSpecifier(), HiddenTypes, Output, VBaseCs, + HiddenVBaseCs); } // Add any unhidden conversions provided by virtual bases. @@ -2307,8 +2311,8 @@ bool CXXRecordDecl::mayBeAbstract() const { return false; for (const auto &B : bases()) { - const auto *BaseDecl = - cast(B.getType()->castAs()->getDecl()); + const auto *BaseDecl = cast( + B.getType()->castAs()->getOriginalDecl()); if (BaseDecl->isAbstract()) return true; } @@ -2471,7 +2475,8 @@ CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD, const RecordType *RT = I.getType()->getAs(); if (!RT) continue; - const auto *Base = cast(RT->getDecl()); + const auto *Base = + cast(RT->getOriginalDecl())->getDefinitionOrSelf(); if (CXXMethodDecl *D = this->getCorrespondingMethodInClass(Base)) AddFinalOverrider(D); } diff --git a/clang/lib/AST/DeclarationName.cpp b/clang/lib/AST/DeclarationName.cpp index ae5fcf6e86adf..6c7b995d57567 100644 --- a/clang/lib/AST/DeclarationName.cpp +++ b/clang/lib/AST/DeclarationName.cpp @@ -115,12 +115,12 @@ static void printCXXConstructorDestructorName(QualType ClassType, Policy.adjustForCPlusPlus(); if (const RecordType *ClassRec = ClassType->getAs()) { - ClassRec->getDecl()->printName(OS, Policy); + ClassRec->getOriginalDecl()->printName(OS, Policy); return; } if (Policy.SuppressTemplateArgsInCXXConstructors) { if (auto *InjTy = ClassType->getAs()) { - InjTy->getDecl()->printName(OS, Policy); + InjTy->getOriginalDecl()->printName(OS, Policy); return; } } @@ -184,7 +184,7 @@ void DeclarationName::print(raw_ostream &OS, OS << "operator "; QualType Type = getCXXNameType(); if (const RecordType *Rec = Type->getAs()) { - OS << *Rec->getDecl(); + OS << *Rec->getOriginalDecl(); return; } // We know we're printing C++ here, ensure we print 'bool' properly. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index c6d6c391f8f0f..0b869e1a55b22 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -75,8 +75,7 @@ const CXXRecordDecl *Expr::getBestDynamicClassType() const { return nullptr; const RecordType *Ty = DerivedType->castAs(); - Decl *D = Ty->getDecl(); - return cast(D); + return cast(Ty->getOriginalDecl())->getDefinitionOrSelf(); } const Expr *Expr::skipRValueSubobjectAdjustments( @@ -92,7 +91,9 @@ const Expr *Expr::skipRValueSubobjectAdjustments( E->getType()->isRecordType()) { E = CE->getSubExpr(); const auto *Derived = - cast(E->getType()->castAs()->getDecl()); + cast( + E->getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); Adjustments.push_back(SubobjectAdjustment(CE, Derived)); continue; } @@ -2031,7 +2032,8 @@ CXXBaseSpecifier **CastExpr::path_buffer() { const FieldDecl *CastExpr::getTargetFieldForToUnionCast(QualType unionType, QualType opType) { - auto RD = unionType->castAs()->getDecl(); + auto RD = + unionType->castAs()->getOriginalDecl()->getDefinitionOrSelf(); return getTargetFieldForToUnionCast(RD, opType); } @@ -3408,7 +3410,10 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef, if (ILE->getType()->isRecordType()) { unsigned ElementNo = 0; - RecordDecl *RD = ILE->getType()->castAs()->getDecl(); + RecordDecl *RD = ILE->getType() + ->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); // In C++17, bases were added to the list of members used by aggregate // initialization. @@ -4051,8 +4056,10 @@ Expr::isNullPointerConstant(ASTContext &Ctx, return NPCK_CXX11_nullptr; if (const RecordType *UT = getType()->getAsUnionType()) - if (!Ctx.getLangOpts().CPlusPlus11 && - UT && UT->getDecl()->hasAttr()) + if (!Ctx.getLangOpts().CPlusPlus11 && UT && + UT->getOriginalDecl() + ->getMostRecentDecl() + ->hasAttr()) if (const CompoundLiteralExpr *CLE = dyn_cast(this)){ const Expr *InitExpr = CLE->getInitializer(); if (const InitListExpr *ILE = dyn_cast(InitExpr)) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index fc690a3cbec0f..be923ecf7f381 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2623,7 +2623,8 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, Value.getUnionValue(), Kind, Value.getUnionField(), CheckedTemps); } if (Value.isStruct()) { - RecordDecl *RD = Type->castAs()->getDecl(); + RecordDecl *RD = + Type->castAs()->getOriginalDecl()->getDefinitionOrSelf(); if (const CXXRecordDecl *CD = dyn_cast(RD)) { unsigned BaseIndex = 0; for (const CXXBaseSpecifier &BS : CD->bases()) { @@ -4109,7 +4110,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, } // Next subobject is a class, struct or union field. - RecordDecl *RD = ObjType->castAs()->getDecl(); + RecordDecl *RD = ObjType->castAs()->getOriginalDecl(); if (RD->isUnion()) { const FieldDecl *UnionField = O->getUnionField(); if (!UnionField || @@ -7773,7 +7774,8 @@ class BufferToAPValueConverter { } std::optional visit(const EnumType *Ty, CharUnits Offset) { - QualType RepresentationType = Ty->getDecl()->getIntegerType(); + QualType RepresentationType = + Ty->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); assert(!RepresentationType.isNull() && "enum forward decl should be caught by Sema"); const auto *AsBuiltin = @@ -8568,8 +8570,10 @@ class ExprEvaluatorBase const FieldDecl *FD = dyn_cast(E->getMemberDecl()); if (!FD) return Error(E); assert(!FD->getType()->isReferenceType() && "prvalue reference?"); - assert(BaseTy->castAs()->getDecl()->getCanonicalDecl() == - FD->getParent()->getCanonicalDecl() && "record / field mismatch"); + assert( + BaseTy->castAs()->getOriginalDecl()->getCanonicalDecl() == + FD->getParent()->getCanonicalDecl() && + "record / field mismatch"); // Note: there is no lvalue base here. But this case should only ever // happen in C or in C++98, where we cannot be evaluating a constexpr @@ -8796,8 +8800,10 @@ class LValueExprEvaluatorBase const ValueDecl *MD = E->getMemberDecl(); if (const FieldDecl *FD = dyn_cast(E->getMemberDecl())) { - assert(BaseTy->castAs()->getDecl()->getCanonicalDecl() == - FD->getParent()->getCanonicalDecl() && "record / field mismatch"); + assert( + BaseTy->castAs()->getOriginalDecl()->getCanonicalDecl() == + FD->getParent()->getCanonicalDecl() && + "record / field mismatch"); (void)BaseTy; if (!HandleLValueMember(this->Info, E, Result, FD)) return false; @@ -10780,7 +10786,8 @@ static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, } bool RecordExprEvaluator::ZeroInitialization(const Expr *E, QualType T) { - const RecordDecl *RD = T->castAs()->getDecl(); + const RecordDecl *RD = + T->castAs()->getOriginalDecl()->getDefinitionOrSelf(); if (RD->isInvalidDecl()) return false; if (RD->isUnion()) { // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the @@ -10849,8 +10856,10 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) { bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr( const Expr *ExprToVisit, ArrayRef Args) { - const RecordDecl *RD = - ExprToVisit->getType()->castAs()->getDecl(); + const RecordDecl *RD = ExprToVisit->getType() + ->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); if (RD->isInvalidDecl()) return false; const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD); auto *CXXRD = dyn_cast(RD); @@ -11078,7 +11087,10 @@ bool RecordExprEvaluator::VisitCXXStdInitializerListExpr( Result = APValue(APValue::UninitStruct(), 0, 2); Array.moveInto(Result.getStructField(0)); - RecordDecl *Record = E->getType()->castAs()->getDecl(); + RecordDecl *Record = E->getType() + ->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); RecordDecl::field_iterator Field = Record->field_begin(); assert(Field != Record->field_end() && Info.Ctx.hasSameType(Field->getType()->getPointeeType(), @@ -12851,7 +12863,10 @@ 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()->getDecl()->hasFlexibleArrayMember()) + T->getAsStructureType() + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->hasFlexibleArrayMember()) if (const auto *V = LV.getLValueBase().dyn_cast()) if (const auto *VD = dyn_cast(V)) if (VD->hasInit()) @@ -15096,7 +15111,7 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) { const RecordType *RT = CurrentType->getAs(); if (!RT) return Error(OOE); - RecordDecl *RD = RT->getDecl(); + RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->isInvalidDecl()) return false; const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD); unsigned i = MemberDecl->getFieldIndex(); @@ -15118,7 +15133,7 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) { const RecordType *RT = CurrentType->getAs(); if (!RT) return Error(OOE); - RecordDecl *RD = RT->getDecl(); + RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->isInvalidDecl()) return false; const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD); @@ -15129,7 +15144,8 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) { return Error(OOE); // Add the offset to the base. - Result += RL.getBaseClassOffset(cast(BaseRT->getDecl())); + Result += RL.getBaseClassOffset(cast( + BaseRT->getOriginalDecl()->getDefinitionOrSelf())); break; } } @@ -15308,7 +15324,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->getDecl(); + const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); // 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 112b756d2be1a..502a3e6b145e3 100644 --- a/clang/lib/AST/FormatString.cpp +++ b/clang/lib/AST/FormatString.cpp @@ -417,10 +417,11 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const { // 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. - if (!ETy->getDecl()->isComplete()) + const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf(); + if (!ED->isComplete()) return NoMatch; if (ETy->isUnscopedEnumerationType()) - argTy = ETy->getDecl()->getIntegerType(); + argTy = ED->getIntegerType(); } if (const auto *BT = argTy->getAs()) { @@ -466,10 +467,11 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const { // 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. - if (!ETy->getDecl()->isComplete()) + const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf(); + if (!ED->isComplete()) argTy = C.IntTy; else if (ETy->isUnscopedEnumerationType()) - argTy = ETy->getDecl()->getIntegerType(); + argTy = ED->getIntegerType(); } if (argTy->isSaturatedFixedPointType()) diff --git a/clang/lib/AST/InheritViz.cpp b/clang/lib/AST/InheritViz.cpp index 822fbc2ca78e8..c03492c64b161 100644 --- a/clang/lib/AST/InheritViz.cpp +++ b/clang/lib/AST/InheritViz.cpp @@ -89,8 +89,8 @@ void InheritanceHierarchyWriter::WriteNode(QualType Type, bool FromVirtual) { Out << " \"];\n"; // Display the base classes. - const auto *Decl = - static_cast(Type->castAs()->getDecl()); + const auto *Decl = static_cast( + Type->castAs()->getOriginalDecl()); for (const auto &Base : Decl->bases()) { QualType CanonBaseType = Context.getCanonicalType(Base.getType()); diff --git a/clang/lib/AST/ItaniumCXXABI.cpp b/clang/lib/AST/ItaniumCXXABI.cpp index 6ceedd657fe7e..43a8bcd9443ff 100644 --- a/clang/lib/AST/ItaniumCXXABI.cpp +++ b/clang/lib/AST/ItaniumCXXABI.cpp @@ -42,10 +42,10 @@ namespace { /// /// Returns the name of anonymous union VarDecl or nullptr if it is not found. static const IdentifierInfo *findAnonymousUnionVarDeclName(const VarDecl& VD) { - const RecordType *RT = VD.getType()->getAs(); - assert(RT && "type of VarDecl is expected to be RecordType."); - assert(RT->getDecl()->isUnion() && "RecordType is expected to be a union."); - if (const FieldDecl *FD = RT->getDecl()->findFirstNamedDataMember()) { + const auto *RT = VD.getType()->castAs(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + 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 d060bc87b0308..0e5a0d5db8e8c 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -1596,7 +1596,10 @@ 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()->getDecl(); + const RecordDecl *RD = VD->getType() + ->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); // Itanium C++ ABI 5.1.2: // @@ -2540,7 +2543,8 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty, case Type::Enum: case Type::Record: - mangleSourceNameWithAbiTags(cast(Ty)->getDecl()); + mangleSourceNameWithAbiTags( + cast(Ty)->getOriginalDecl()->getDefinitionOrSelf()); break; case Type::TemplateSpecialization: { @@ -2601,8 +2605,9 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty, } case Type::InjectedClassName: - mangleSourceNameWithAbiTags( - cast(Ty)->getDecl()); + mangleSourceNameWithAbiTags(cast(Ty) + ->getOriginalDecl() + ->getDefinitionOrSelf()); break; case Type::DependentName: @@ -3850,7 +3855,7 @@ void CXXNameMangler::mangleType(const RecordType *T) { mangleType(static_cast(T)); } void CXXNameMangler::mangleType(const TagType *T) { - mangleName(T->getDecl()); + mangleName(T->getOriginalDecl()->getDefinitionOrSelf()); } // ::= @@ -4759,7 +4764,7 @@ void CXXNameMangler::mangleIntegerLiteral(QualType T, void CXXNameMangler::mangleMemberExprBase(const Expr *Base, bool IsArrow) { // Ignore member expressions involving anonymous unions. while (const auto *RT = Base->getType()->getAs()) { - if (!RT->getDecl()->isAnonymousStructOrUnion()) + if (!RT->getOriginalDecl()->isAnonymousStructOrUnion()) break; const auto *ME = dyn_cast(Base); if (!ME) @@ -7036,7 +7041,7 @@ static bool hasMangledSubstitutionQualifiers(QualType T) { bool CXXNameMangler::mangleSubstitution(QualType T) { if (!hasMangledSubstitutionQualifiers(T)) { if (const RecordType *RT = T->getAs()) - return mangleSubstitution(RT->getDecl()); + return mangleSubstitution(RT->getOriginalDecl()->getDefinitionOrSelf()); } uintptr_t TypePtr = reinterpret_cast(T.getAsOpaquePtr()); @@ -7077,7 +7082,7 @@ bool CXXNameMangler::isSpecializedAs(QualType S, llvm::StringRef Name, return false; const ClassTemplateSpecializationDecl *SD = - dyn_cast(RT->getDecl()); + dyn_cast(RT->getOriginalDecl()); if (!SD || !SD->getIdentifier()->isStr(Name)) return false; @@ -7207,7 +7212,7 @@ bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) { void CXXNameMangler::addSubstitution(QualType T) { if (!hasMangledSubstitutionQualifiers(T)) { if (const RecordType *RT = T->getAs()) { - addSubstitution(RT->getDecl()); + addSubstitution(RT->getOriginalDecl()->getDefinitionOrSelf()); return; } } diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index fdbd4479bb995..246e5322acb3d 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -395,8 +395,8 @@ llvm::json::Array JSONNodeDumper::createCastPath(const CastExpr *C) { for (auto I = C->path_begin(), E = C->path_end(); I != E; ++I) { const CXXBaseSpecifier *Base = *I; - const auto *RD = - cast(Base->getType()->castAs()->getDecl()); + const auto *RD = cast( + Base->getType()->castAs()->getOriginalDecl()); llvm::json::Object Val{{"name", RD->getName()}}; if (Base->isVirtual()) @@ -816,7 +816,7 @@ void JSONNodeDumper::VisitTemplateSpecializationType( void JSONNodeDumper::VisitInjectedClassNameType( const InjectedClassNameType *ICNT) { - JOS.attribute("decl", createBareDeclRef(ICNT->getDecl())); + JOS.attribute("decl", createBareDeclRef(ICNT->getOriginalDecl())); } void JSONNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *OIT) { diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 4b2ba5cd1e3ce..1d17f75b8c53a 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -3247,11 +3247,11 @@ void MicrosoftCXXNameMangler::mangleTagTypeKind(TagTypeKind TTK) { } void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers, SourceRange) { - mangleType(cast(T)->getDecl()); + mangleType(cast(T)->getOriginalDecl()->getDefinitionOrSelf()); } void MicrosoftCXXNameMangler::mangleType(const RecordType *T, Qualifiers, SourceRange) { - mangleType(cast(T)->getDecl()); + mangleType(cast(T)->getOriginalDecl()->getDefinitionOrSelf()); } void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) { mangleTagTypeKind(TD->getTagKind()); diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp index 9812d26a61f05..c7a69d7c5ba42 100644 --- a/clang/lib/AST/ODRHash.cpp +++ b/clang/lib/AST/ODRHash.cpp @@ -1069,7 +1069,7 @@ class ODRTypeVisitor : public TypeVisitor { } void VisitInjectedClassNameType(const InjectedClassNameType *T) { - AddDecl(T->getDecl()); + AddDecl(T->getOriginalDecl()->getDefinitionOrSelf()); VisitType(T); } diff --git a/clang/lib/AST/PrintfFormatString.cpp b/clang/lib/AST/PrintfFormatString.cpp index bcd44f0a85eed..687160c6116be 100644 --- a/clang/lib/AST/PrintfFormatString.cpp +++ b/clang/lib/AST/PrintfFormatString.cpp @@ -794,7 +794,7 @@ 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->getDecl()->getIntegerType(); + QT = ETy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); const BuiltinType *BT = QT->getAs(); if (!BT) { diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 5c3ea20542f8b..32c4c5e066ef6 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2012,8 +2012,7 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D, } else if (const BuiltinType *BTy = BaseTy->getAs()) { performBuiltinTypeAlignmentUpgrade(BTy); } else if (const RecordType *RT = BaseTy->getAs()) { - const RecordDecl *RD = RT->getDecl(); - assert(RD && "Expected non-null RecordDecl."); + const RecordDecl *RD = RT->getOriginalDecl(); const ASTRecordLayout &FieldRecord = Context.getASTRecordLayout(RD); PreferredAlign = FieldRecord.getPreferredAlignment(); } @@ -2714,7 +2713,7 @@ MicrosoftRecordLayoutBuilder::getAdjustedElementInfo( else { if (auto RT = FD->getType()->getBaseElementTypeUnsafe()->getAs()) { - auto const &Layout = Context.getASTRecordLayout(RT->getDecl()); + auto const &Layout = Context.getASTRecordLayout(RT->getOriginalDecl()); EndsWithZeroSizedObject = Layout.endsWithZeroSizedObject(); FieldRequiredAlignment = std::max(FieldRequiredAlignment, Layout.getRequiredAlignment()); @@ -3697,8 +3696,8 @@ static void DumpRecordLayout(raw_ostream &OS, const RecordDecl *RD, // Recursively dump fields of record type. if (auto RT = Field->getType()->getAs()) { - DumpRecordLayout(OS, RT->getDecl(), C, FieldOffset, IndentLevel, - Field->getName().data(), + DumpRecordLayout(OS, RT->getOriginalDecl()->getDefinitionOrSelf(), C, + FieldOffset, IndentLevel, Field->getName().data(), /*PrintSizeInfo=*/false, /*IncludeVirtualBases=*/true); continue; diff --git a/clang/lib/AST/ScanfFormatString.cpp b/clang/lib/AST/ScanfFormatString.cpp index 1227edd47d13d..31c001d025fea 100644 --- a/clang/lib/AST/ScanfFormatString.cpp +++ b/clang/lib/AST/ScanfFormatString.cpp @@ -432,9 +432,10 @@ bool ScanfSpecifier::fixType(QualType QT, QualType RawQT, // If it's an enum, get its underlying type. if (const EnumType *ETy = PT->getAs()) { // Don't try to fix incomplete enums. - if (!ETy->getDecl()->isComplete()) + const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf(); + if (!ED->isComplete()) return false; - PT = ETy->getDecl()->getIntegerType(); + PT = ED->getIntegerType(); } const BuiltinType *BT = PT->getAs(); diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index 7c89dea4629cc..2fae4ab2b0ea3 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -57,7 +57,7 @@ static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out, if (Policy.UseEnumerators) { if (const EnumType *ET = T->getAs()) { - for (const EnumConstantDecl *ECD : ET->getDecl()->enumerators()) { + for (const EnumConstantDecl *ECD : ET->getOriginalDecl()->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/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 5fa51855190a1..8aa01bfaf9668 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1398,8 +1398,8 @@ static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) { if (!First) OS << " -> "; - const auto *RD = - cast(Base->getType()->castAs()->getDecl()); + const auto *RD = cast( + Base->getType()->castAs()->getOriginalDecl()); if (Base->isVirtual()) OS << "virtual "; @@ -2210,7 +2210,7 @@ void TextNodeDumper::VisitTemplateSpecializationType( void TextNodeDumper::VisitInjectedClassNameType( const InjectedClassNameType *T) { - dumpDeclRef(T->getDecl()); + dumpDeclRef(T->getOriginalDecl()); } void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) { diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 8007ad6eff5fd..d756d22645156 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -113,10 +113,10 @@ const IdentifierInfo *QualType::getBaseTypeIdentifier() const { return DNT->getIdentifier(); if (ty->isPointerOrReferenceType()) return ty->getPointeeType().getBaseTypeIdentifier(); - else if (ty->isRecordType()) - ND = ty->castAs()->getDecl(); + if (ty->isRecordType()) + ND = ty->castAs()->getOriginalDecl(); else if (ty->isEnumeralType()) - ND = ty->castAs()->getDecl(); + ND = ty->castAs()->getOriginalDecl(); else if (ty->getTypeClass() == Type::Typedef) ND = ty->castAs()->getDecl(); else if (ty->isArrayType()) @@ -673,13 +673,13 @@ const Type *Type::getUnqualifiedDesugaredType() const { bool Type::isClassType() const { if (const auto *RT = getAs()) - return RT->getDecl()->isClass(); + return RT->getOriginalDecl()->isClass(); return false; } bool Type::isStructureType() const { if (const auto *RT = getAs()) - return RT->getDecl()->isStruct(); + return RT->getOriginalDecl()->isStruct(); return false; } @@ -687,7 +687,7 @@ bool Type::isStructureTypeWithFlexibleArrayMember() const { const auto *RT = getAs(); if (!RT) return false; - const auto *Decl = RT->getDecl(); + const auto *Decl = RT->getOriginalDecl()->getDefinitionOrSelf(); if (!Decl->isStruct()) return false; return Decl->hasFlexibleArrayMember(); @@ -695,19 +695,21 @@ bool Type::isStructureTypeWithFlexibleArrayMember() const { bool Type::isObjCBoxableRecordType() const { if (const auto *RT = getAs()) - return RT->getDecl()->hasAttr(); + return RT->getOriginalDecl() + ->getDefinitionOrSelf() + ->hasAttr(); return false; } bool Type::isInterfaceType() const { if (const auto *RT = getAs()) - return RT->getDecl()->isInterface(); + return RT->getOriginalDecl()->isInterface(); return false; } bool Type::isStructureOrClassType() const { if (const auto *RT = getAs()) { - RecordDecl *RD = RT->getDecl(); + RecordDecl *RD = RT->getOriginalDecl(); return RD->isStruct() || RD->isClass() || RD->isInterface(); } return false; @@ -721,7 +723,7 @@ bool Type::isVoidPointerType() const { bool Type::isUnionType() const { if (const auto *RT = getAs()) - return RT->getDecl()->isUnion(); + return RT->getOriginalDecl()->isUnion(); return false; } @@ -738,7 +740,7 @@ bool Type::isComplexIntegerType() const { bool Type::isScopedEnumeralType() const { if (const auto *ET = getAs()) - return ET->getDecl()->isScoped(); + return ET->getOriginalDecl()->isScoped(); return false; } @@ -772,13 +774,13 @@ QualType Type::getPointeeType() const { const RecordType *Type::getAsStructureType() const { // If this is directly a structure type, return it. if (const auto *RT = dyn_cast(this)) { - if (RT->getDecl()->isStruct()) + if (RT->getOriginalDecl()->isStruct()) return RT; } // If the canonical form of this type isn't the right kind, reject it. if (const auto *RT = dyn_cast(CanonicalType)) { - if (!RT->getDecl()->isStruct()) + if (!RT->getOriginalDecl()->isStruct()) return nullptr; // If this is a typedef for a structure type, strip the typedef off without @@ -791,13 +793,13 @@ const RecordType *Type::getAsStructureType() const { const RecordType *Type::getAsUnionType() const { // If this is directly a union type, return it. if (const auto *RT = dyn_cast(this)) { - if (RT->getDecl()->isUnion()) + if (RT->getOriginalDecl()->isUnion()) return RT; } // If the canonical form of this type isn't the right kind, reject it. if (const auto *RT = dyn_cast(CanonicalType)) { - if (!RT->getDecl()->isUnion()) + if (!RT->getOriginalDecl()->isUnion()) return nullptr; // If this is a typedef for a union type, strip the typedef off without @@ -1920,25 +1922,32 @@ const CXXRecordDecl *Type::getPointeeCXXRecordDecl() const { return nullptr; if (const auto *RT = PointeeType->getAs()) - return dyn_cast(RT->getDecl()); + return dyn_cast( + RT->getOriginalDecl()->getDefinitionOrSelf()); return nullptr; } CXXRecordDecl *Type::getAsCXXRecordDecl() const { - return dyn_cast_or_null(getAsTagDecl()); + const auto *TT = dyn_cast(CanonicalType); + if (!isa_and_present(TT)) + return nullptr; + auto *TD = TT->getOriginalDecl(); + if (!isa(TT) && !isa(TD)) + return nullptr; + return cast(TD)->getDefinitionOrSelf(); } RecordDecl *Type::getAsRecordDecl() const { - return dyn_cast_or_null(getAsTagDecl()); + const auto *TT = dyn_cast(CanonicalType); + if (!isa_and_present(TT)) + return nullptr; + return cast(TT->getOriginalDecl())->getDefinitionOrSelf(); } TagDecl *Type::getAsTagDecl() const { - if (const auto *TT = getAs()) - return TT->getDecl(); - if (const auto *Injected = getAs()) - return Injected->getDecl(); - + if (const auto *TT = dyn_cast(CanonicalType)) + return TT->getOriginalDecl()->getDefinitionOrSelf(); return nullptr; } @@ -2109,7 +2118,7 @@ bool Type::isIntegralType(const ASTContext &Ctx) const { // Complete enum types are integral in C. if (!Ctx.getLangOpts().CPlusPlus) if (const auto *ET = dyn_cast(CanonicalType)) - return ET->getDecl()->isComplete(); + return IsEnumDeclComplete(ET->getOriginalDecl()); return isBitIntType(); } @@ -2126,7 +2135,7 @@ bool Type::isIntegralOrUnscopedEnumerationType() const { bool Type::isUnscopedEnumerationType() const { if (const auto *ET = dyn_cast(CanonicalType)) - return !ET->getDecl()->isScoped(); + return !ET->getOriginalDecl()->isScoped(); return false; } @@ -2211,8 +2220,10 @@ bool Type::isSignedIntegerType() const { if (const EnumType *ET = dyn_cast(CanonicalType)) { // Incomplete enum types are not treated as integer types. // FIXME: In C++, enum types are never integer types. - if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped()) - return ET->getDecl()->getIntegerType()->isSignedIntegerType(); + const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + if (!ED->isComplete() || ED->isScoped()) + return false; + return ED->getIntegerType()->isSignedIntegerType(); } if (const auto *IT = dyn_cast(CanonicalType)) @@ -2227,9 +2238,12 @@ bool Type::isSignedIntegerOrEnumerationType() const { if (const auto *BT = dyn_cast(CanonicalType)) return BT->isSignedInteger(); - if (const auto *ET = dyn_cast(CanonicalType); - ET && ET->getDecl()->isComplete()) - return ET->getDecl()->getIntegerType()->isSignedIntegerType(); + if (const auto *ET = dyn_cast(CanonicalType)) { + const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + if (!ED->isComplete()) + return false; + return ED->getIntegerType()->isSignedIntegerType(); + } if (const auto *IT = dyn_cast(CanonicalType)) return IT->isSigned(); @@ -2256,8 +2270,10 @@ bool Type::isUnsignedIntegerType() const { if (const auto *ET = dyn_cast(CanonicalType)) { // Incomplete enum types are not treated as integer types. // FIXME: In C++, enum types are never integer types. - if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped()) - return ET->getDecl()->getIntegerType()->isUnsignedIntegerType(); + const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + if (!ED->isComplete() || ED->isScoped()) + return false; + return ED->getIntegerType()->isUnsignedIntegerType(); } if (const auto *IT = dyn_cast(CanonicalType)) @@ -2272,9 +2288,12 @@ bool Type::isUnsignedIntegerOrEnumerationType() const { if (const auto *BT = dyn_cast(CanonicalType)) return BT->isUnsignedInteger(); - if (const auto *ET = dyn_cast(CanonicalType); - ET && ET->getDecl()->isComplete()) - return ET->getDecl()->getIntegerType()->isUnsignedIntegerType(); + if (const auto *ET = dyn_cast(CanonicalType)) { + const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + if (!ED->isComplete()) + return false; + return ED->getIntegerType()->isUnsignedIntegerType(); + } if (const auto *IT = dyn_cast(CanonicalType)) return IT->isUnsigned(); @@ -2323,8 +2342,10 @@ bool Type::isRealType() const { if (const auto *BT = dyn_cast(CanonicalType)) return BT->getKind() >= BuiltinType::Bool && BT->getKind() <= BuiltinType::Ibm128; - if (const auto *ET = dyn_cast(CanonicalType)) - return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped(); + if (const auto *ET = dyn_cast(CanonicalType)) { + const auto *ED = ET->getOriginalDecl(); + return !ED->isScoped() && ED->getDefinitionOrSelf()->isComplete(); + } return isBitIntType(); } @@ -2332,14 +2353,16 @@ bool Type::isArithmeticType() const { if (const auto *BT = dyn_cast(CanonicalType)) return BT->getKind() >= BuiltinType::Bool && BT->getKind() <= BuiltinType::Ibm128; - if (const auto *ET = dyn_cast(CanonicalType)) + if (const auto *ET = dyn_cast(CanonicalType)) { // GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2). // If a body isn't seen by the time we get here, return false. // // C++0x: Enumerations are not arithmetic types. For now, just return // false for scoped enumerations since that will disable any // unwanted implicit conversions. - return !ET->getDecl()->isScoped() && ET->getDecl()->isComplete(); + const auto *ED = ET->getOriginalDecl(); + return !ED->isScoped() && ED->getDefinitionOrSelf()->isComplete(); + } return isa(CanonicalType) || isBitIntType(); } @@ -2347,8 +2370,8 @@ bool Type::hasBooleanRepresentation() const { if (const auto *VT = dyn_cast(CanonicalType)) return VT->getElementType()->isBooleanType(); if (const auto *ET = dyn_cast(CanonicalType)) { - return ET->getDecl()->isComplete() && - ET->getDecl()->getIntegerType()->isBooleanType(); + const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + return ED->isComplete() && ED->getIntegerType()->isBooleanType(); } if (const auto *IT = dyn_cast(CanonicalType)) return IT->getNumBits() == 1; @@ -2380,7 +2403,10 @@ Type::ScalarTypeKind Type::getScalarTypeKind() const { } else if (isa(T)) { return STK_MemberPointer; } else if (isa(T)) { - assert(cast(T)->getDecl()->isComplete()); + assert(cast(T) + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->isComplete()); return STK_Integral; } else if (const auto *CT = dyn_cast(T)) { if (CT->getElementType()->isRealFloatingType()) @@ -2404,7 +2430,8 @@ Type::ScalarTypeKind Type::getScalarTypeKind() const { /// includes union types. bool Type::isAggregateType() const { if (const auto *Record = dyn_cast(CanonicalType)) { - if (const auto *ClassDecl = dyn_cast(Record->getDecl())) + if (const auto *ClassDecl = dyn_cast( + Record->getOriginalDecl()->getDefinitionOrSelf())) return ClassDecl->isAggregate(); return true; @@ -2438,7 +2465,8 @@ bool Type::isIncompleteType(NamedDecl **Def) const { // be completed. return isVoidType(); case Enum: { - EnumDecl *EnumD = cast(CanonicalType)->getDecl(); + EnumDecl *EnumD = + cast(CanonicalType)->getOriginalDecl()->getDefinitionOrSelf(); if (Def) *Def = EnumD; return !EnumD->isComplete(); @@ -2446,13 +2474,17 @@ 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)->getDecl(); + RecordDecl *Rec = cast(CanonicalType) + ->getOriginalDecl() + ->getDefinitionOrSelf(); if (Def) *Def = Rec; return !Rec->isCompleteDefinition(); } case InjectedClassName: { - CXXRecordDecl *Rec = cast(CanonicalType)->getDecl(); + CXXRecordDecl *Rec = cast(CanonicalType) + ->getOriginalDecl() + ->getDefinitionOrSelf(); if (!Rec->isBeingDefined()) return false; if (Def) @@ -2734,9 +2766,9 @@ bool QualType::isCXX98PODType(const ASTContext &Context) const { return true; case Type::Record: - if (const auto *ClassDecl = - dyn_cast(cast(CanonicalType)->getDecl())) - return ClassDecl->isPOD(); + if (const auto *ClassDecl = dyn_cast( + cast(CanonicalType)->getOriginalDecl())) + return ClassDecl->getDefinitionOrSelf()->isPOD(); // C struct/union is POD. return true; @@ -2777,7 +2809,8 @@ bool QualType::isTrivialType(const ASTContext &Context) const { if (CanonicalType->isScalarType() || CanonicalType->isVectorType()) return true; if (const auto *RT = CanonicalType->getAs()) { - if (const auto *ClassDecl = dyn_cast(RT->getDecl())) { + if (const auto *ClassDecl = + dyn_cast(RT->getOriginalDecl())) { // C++20 [class]p6: // A trivial class is a class that is trivially copyable, and // has one or more eligible default constructors such that each is @@ -2836,14 +2869,17 @@ static bool isTriviallyCopyableTypeImpl(const QualType &type, return true; if (const auto *RT = CanonicalType->getAs()) { - if (const auto *ClassDecl = dyn_cast(RT->getDecl())) { + if (const auto *ClassDecl = + dyn_cast(RT->getOriginalDecl())) { if (IsCopyConstructible) { return ClassDecl->isTriviallyCopyConstructible(); } else { return ClassDecl->isTriviallyCopyable(); } } - return !RT->getDecl()->isNonTrivialToPrimitiveCopy(); + return !RT->getOriginalDecl() + ->getDefinitionOrSelf() + ->isNonTrivialToPrimitiveCopy(); } // No other types can match. return false; @@ -2933,7 +2969,9 @@ QualType::PrimitiveDefaultInitializeKind QualType::isNonTrivialToPrimitiveDefaultInitialize() const { if (const auto *RT = getTypePtr()->getBaseElementTypeUnsafe()->getAs()) - if (RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) + if (RT->getOriginalDecl() + ->getDefinitionOrSelf() + ->isNonTrivialToPrimitiveDefaultInitialize()) return PDIK_Struct; switch (getQualifiers().getObjCLifetime()) { @@ -2949,7 +2987,9 @@ QualType::isNonTrivialToPrimitiveDefaultInitialize() const { QualType::PrimitiveCopyKind QualType::isNonTrivialToPrimitiveCopy() const { if (const auto *RT = getTypePtr()->getBaseElementTypeUnsafe()->getAs()) - if (RT->getDecl()->isNonTrivialToPrimitiveCopy()) + if (RT->getOriginalDecl() + ->getDefinitionOrSelf() + ->isNonTrivialToPrimitiveCopy()) return PCK_Struct; Qualifiers Qs = getQualifiers(); @@ -3017,8 +3057,8 @@ bool Type::isLiteralType(const ASTContext &Ctx) const { // -- all non-static data members and base classes of literal types // // We resolve DR1361 by ignoring the second bullet. - if (const auto *ClassDecl = dyn_cast(RT->getDecl())) - return ClassDecl->isLiteral(); + if (const auto *ClassDecl = dyn_cast(RT->getOriginalDecl())) + return ClassDecl->getDefinitionOrSelf()->isLiteral(); return true; } @@ -3071,8 +3111,8 @@ bool Type::isStandardLayoutType() const { if (BaseTy->isScalarType() || BaseTy->isVectorType()) return true; if (const auto *RT = BaseTy->getAs()) { - if (const auto *ClassDecl = dyn_cast(RT->getDecl())) - if (!ClassDecl->isStandardLayout()) + if (const auto *ClassDecl = dyn_cast(RT->getOriginalDecl())) + if (!ClassDecl->getDefinitionOrSelf()->isStandardLayout()) return false; // Default to 'true' for non-C++ class types. @@ -3114,7 +3154,9 @@ bool QualType::isCXX11PODType(const ASTContext &Context) const { if (BaseTy->isScalarType() || BaseTy->isVectorType()) return true; if (const auto *RT = BaseTy->getAs()) { - if (const auto *ClassDecl = dyn_cast(RT->getDecl())) { + if (const auto *ClassDecl = + dyn_cast(RT->getOriginalDecl())) { + ClassDecl = ClassDecl->getDefinitionOrSelf(); // C++11 [class]p10: // A POD struct is a non-union class that is both a trivial class [...] if (!ClassDecl->isTrivial()) @@ -3154,8 +3196,9 @@ bool Type::isNothrowT() const { bool Type::isAlignValT() const { if (const auto *ET = getAs()) { - IdentifierInfo *II = ET->getDecl()->getIdentifier(); - if (II && II->isStr("align_val_t") && ET->getDecl()->isInStdNamespace()) + const auto *ED = ET->getOriginalDecl(); + IdentifierInfo *II = ED->getIdentifier(); + if (II && II->isStr("align_val_t") && ED->isInStdNamespace()) return true; } return false; @@ -3163,8 +3206,9 @@ bool Type::isAlignValT() const { bool Type::isStdByteType() const { if (const auto *ET = getAs()) { - IdentifierInfo *II = ET->getDecl()->getIdentifier(); - if (II && II->isStr("byte") && ET->getDecl()->isInStdNamespace()) + const auto *ED = ET->getOriginalDecl(); + IdentifierInfo *II = ED->getIdentifier(); + if (II && II->isStr("byte") && ED->isInStdNamespace()) return true; } return false; @@ -4312,8 +4356,10 @@ bool RecordType::hasConstFields() const { unsigned NextToCheckIndex = 0; while (RecordTypeList.size() > NextToCheckIndex) { - for (FieldDecl *FD : - RecordTypeList[NextToCheckIndex]->getDecl()->fields()) { + for (FieldDecl *FD : RecordTypeList[NextToCheckIndex] + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->fields()) { QualType FieldTy = FD->getType(); if (FieldTy.isConstQualified()) return true; @@ -4784,7 +4830,8 @@ static CachedProperties computeCachedProperties(const Type *T) { case Type::Record: case Type::Enum: { - const TagDecl *Tag = cast(T)->getDecl(); + const TagDecl *Tag = + cast(T)->getOriginalDecl()->getDefinitionOrSelf(); // C++ [basic.link]p8: // - it is a class or enumeration type that is named (or has a name @@ -4893,7 +4940,8 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) { case Type::Record: case Type::Enum: - return getDeclLinkageAndVisibility(cast(T)->getDecl()); + return getDeclLinkageAndVisibility( + cast(T)->getOriginalDecl()->getDefinitionOrSelf()); case Type::Complex: return computeTypeLinkageInfo(cast(T)->getElementType()); @@ -5096,7 +5144,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const { llvm_unreachable("unknown builtin type"); case Type::Record: { - const RecordDecl *RD = cast(type)->getDecl(); + const RecordDecl *RD = cast(type)->getOriginalDecl(); // For template specializations, look only at primary template attributes. // This is a consistent regardless of whether the instantiation is known. if (const auto *CTSD = dyn_cast(RD)) @@ -5294,14 +5342,18 @@ bool Type::isCARCBridgableType() const { /// Check if the specified type is the CUDA device builtin surface type. bool Type::isCUDADeviceBuiltinSurfaceType() const { if (const auto *RT = getAs()) - return RT->getDecl()->hasAttr(); + return RT->getOriginalDecl() + ->getMostRecentDecl() + ->hasAttr(); return false; } /// Check if the specified type is the CUDA device builtin texture type. bool Type::isCUDADeviceBuiltinTextureType() const { if (const auto *RT = getAs()) - return RT->getDecl()->hasAttr(); + return RT->getOriginalDecl() + ->getMostRecentDecl() + ->hasAttr(); return false; } @@ -5365,7 +5417,7 @@ QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) { } if (const auto *RT = type->getBaseElementTypeUnsafe()->getAs()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl(); if (const auto *CXXRD = dyn_cast(RD)) { /// Check if this is a C++ object with a non-trivial destructor. if (CXXRD->hasDefinition() && !CXXRD->hasTrivialDestructor()) diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 8704b7466a4f5..c909697b5b037 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -303,9 +303,8 @@ bool TypeSpecTypeLoc::isKind(const TypeLoc &TL) { } bool TagTypeLoc::isDefinition() const { - TagDecl *D = getDecl(); - return D->isCompleteDefinition() && - (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc()); + return getTypePtr()->isTagOwned() && + getOriginalDecl()->isCompleteDefinition(); } // Reimplemented to account for GNU/C++ extension diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index f8082ab5b0db9..ce5870e2da690 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1640,9 +1640,11 @@ void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) { void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) { // Print the preferred name if we have one for this type. if (Policy.UsePreferredNames) { - for (const auto *PNA : T->getDecl()->specific_attrs()) { + for (const auto *PNA : T->getOriginalDecl() + ->getMostRecentDecl() + ->specific_attrs()) { if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(), - T->getDecl())) + T->getOriginalDecl())) continue; // Find the outermost typedef or alias template. QualType T = PNA->getTypedefType(); diff --git a/clang/lib/AST/VTTBuilder.cpp b/clang/lib/AST/VTTBuilder.cpp index de011848a721e..85101aee97e66 100644 --- a/clang/lib/AST/VTTBuilder.cpp +++ b/clang/lib/AST/VTTBuilder.cpp @@ -64,7 +64,9 @@ void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) { continue; const auto *BaseDecl = - cast(I.getType()->castAs()->getDecl()); + cast( + I.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); CharUnits BaseOffset = Base.getBaseOffset() + @@ -90,7 +92,9 @@ VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, for (const auto &I : RD->bases()) { const auto *BaseDecl = - cast(I.getType()->castAs()->getDecl()); + cast( + I.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); // Itanium C++ ABI 2.6.2: // Secondary virtual pointers are present for all bases with either @@ -154,7 +158,9 @@ void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD, VisitedVirtualBasesSetTy &VBases) { for (const auto &I : RD->bases()) { const auto *BaseDecl = - cast(I.getType()->castAs()->getDecl()); + cast( + I.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); // Check if this is a virtual base. if (I.isVirtual()) { diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp index 0001745a6ff22..6cec526ba8443 100644 --- a/clang/lib/AST/VTableBuilder.cpp +++ b/clang/lib/AST/VTableBuilder.cpp @@ -313,10 +313,12 @@ ComputeReturnAdjustmentBaseOffset(ASTContext &Context, } const CXXRecordDecl *DerivedRD = - cast(cast(CanDerivedReturnType)->getDecl()); + cast( + cast(CanDerivedReturnType)->getOriginalDecl()) + ->getDefinitionOrSelf(); - const CXXRecordDecl *BaseRD = - cast(cast(CanBaseReturnType)->getDecl()); + const CXXRecordDecl *BaseRD = cast( + cast(CanBaseReturnType)->getOriginalDecl()); return ComputeBaseOffset(Context, BaseRD, DerivedRD); } diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index 80e7c8eff671a..5037b75542925 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -1875,7 +1875,9 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D, assert(inserted.second && "Are we visiting the same expression again?"); if (isa(Exp)) Self = Placeholder; - if (TagT->getDecl()->hasAttr()) + if (TagT->getOriginalDecl() + ->getMostRecentDecl() + ->hasAttr()) Scp = CapabilityExpr(Placeholder, Exp->getType(), /*Neg=*/false); } diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index ddbd0a9ca904b..f560dd8ae1dd1 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -84,8 +84,8 @@ static std::pair classifyCapability(QualType QT) { // which it is. The type should either be a record or a typedef, or a pointer // or reference thereof. if (const auto *RT = QT->getAs()) { - if (const auto *RD = RT->getDecl()) - return classifyCapability(*RD); + if (const auto *RD = RT->getOriginalDecl()) + return classifyCapability(*RD->getDefinitionOrSelf()); } else if (const auto *TT = QT->getAs()) { if (const auto *TD = TT->getDecl()) return classifyCapability(*TD); diff --git a/clang/lib/CodeGen/ABIInfo.cpp b/clang/lib/CodeGen/ABIInfo.cpp index d981d69913632..b5d5f46dc5b5d 100644 --- a/clang/lib/CodeGen/ABIInfo.cpp +++ b/clang/lib/CodeGen/ABIInfo.cpp @@ -68,7 +68,7 @@ bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base, return false; Members *= NElements; } else if (const RecordType *RT = Ty->getAs()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->hasFlexibleArrayMember()) return false; diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index 0a612d3461dc2..79dbe70a0c8eb 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -29,7 +29,7 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); ASTContext &Context = getContext(); if (const auto *EIT = Ty->getAs()) @@ -53,7 +53,7 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = EnumTy->getDecl()->getIntegerType(); + RetTy = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); if (const auto *EIT = RetTy->getAs()) if (EIT->getNumBits() > @@ -105,13 +105,12 @@ llvm::Type *CodeGen::getVAListElementType(CodeGenFunction &CGF) { CGCXXABI::RecordArgABI CodeGen::getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI) { - const CXXRecordDecl *RD = dyn_cast(RT->getDecl()); - if (!RD) { - if (!RT->getDecl()->canPassInRegisters()) - return CGCXXABI::RAA_Indirect; - return CGCXXABI::RAA_Default; - } - return CXXABI.getRecordArgABI(RD); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + if (const auto *CXXRD = dyn_cast(RD)) + return CXXABI.getRecordArgABI(CXXRD); + if (!RD->canPassInRegisters()) + return CGCXXABI::RAA_Indirect; + return CGCXXABI::RAA_Default; } CGCXXABI::RecordArgABI CodeGen::getRecordArgABI(QualType T, CGCXXABI &CXXABI) { @@ -125,20 +124,21 @@ bool CodeGen::classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info) { QualType Ty = FI.getReturnType(); - if (const auto *RT = Ty->getAs()) - if (!isa(RT->getDecl()) && - !RT->getDecl()->canPassInRegisters()) { + if (const auto *RT = Ty->getAs()) { + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + if (!isa(RD) && !RD->canPassInRegisters()) { FI.getReturnInfo() = Info.getNaturalAlignIndirect( Ty, Info.getDataLayout().getAllocaAddrSpace()); return true; } + } return CXXABI.classifyReturnType(FI); } QualType CodeGen::useFirstFieldIfTransparentUnion(QualType Ty) { if (const RecordType *UT = Ty->getAsUnionType()) { - const RecordDecl *UD = UT->getDecl(); + const RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf(); if (UD->hasAttr()) { assert(!UD->field_empty() && "sema created an empty transparent union"); return UD->field_begin()->getType(); @@ -276,7 +276,7 @@ bool CodeGen::isEmptyField(ASTContext &Context, const FieldDecl *FD, // according to the Itanium ABI. The exception applies only to records, // not arrays of records, so we must also check whether we stripped off an // array type above. - if (isa(RT->getDecl()) && + if (isa(RT->getOriginalDecl()) && (WasArray || (!AsIfNoUniqueAddr && !FD->hasAttr()))) return false; @@ -288,7 +288,7 @@ bool CodeGen::isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, const RecordType *RT = T->getAs(); if (!RT) return false; - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->hasFlexibleArrayMember()) return false; @@ -320,7 +320,7 @@ bool CodeGen::isEmptyRecordForLayout(const ASTContext &Context, QualType T) { if (!RT) return false; - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); // If this is a C++ record, check the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) { @@ -344,7 +344,7 @@ const Type *CodeGen::isSingleElementStruct(QualType T, ASTContext &Context) { if (!RT) return nullptr; - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->hasFlexibleArrayMember()) return nullptr; @@ -463,7 +463,7 @@ bool CodeGen::isRecordWithSIMDVectorType(ASTContext &Context, QualType Ty) { const RecordType *RT = Ty->getAs(); if (!RT) return false; - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); // If this is a C++ record, check the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index 0e80522536e15..cfeba6f25ac62 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -425,7 +425,8 @@ static bool isSafeForCXXConstantCapture(QualType type) { // Only records can be unsafe. if (!recordType) return true; - const auto *record = cast(recordType->getDecl()); + const auto *record = + cast(recordType->getOriginalDecl())->getDefinitionOrSelf(); // Maintain semantics for classes with non-trivial dtors or copy ctors. if (!record->hasTrivialDestructor()) return false; diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp index dd26be74e561b..c7f4bf8a21354 100644 --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -1131,7 +1131,8 @@ 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()->getDecl()); + D->getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); 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 78a7b021855b7..5560985af4de6 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -83,8 +83,9 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) { if (I.isVirtual()) continue; // Skip base classes with trivial destructors. - const auto *Base = - cast(I.getType()->castAs()->getDecl()); + const auto *Base = cast( + I.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); if (Base->hasTrivialDestructor()) continue; // If we've already found a base class with a non-trivial @@ -288,7 +289,8 @@ CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD, QualType T = QualType(QTy, 0); const RecordType *RT = T->getAs(); assert(RT && "BuildAppleKextVirtualCall - Qual type must be record"); - const auto *RD = cast(RT->getDecl()); + const auto *RD = + cast(RT->getOriginalDecl())->getDefinitionOrSelf(); 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 82216e8a748a3..3b36554a9389b 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1008,7 +1008,7 @@ getTypeExpansion(QualType Ty, const ASTContext &Context) { if (const RecordType *RT = Ty->getAs()) { SmallVector Bases; SmallVector Fields; - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); assert(!RD->hasFlexibleArrayMember() && "Cannot expand structure with flexible array."); if (RD->isUnion()) { @@ -1895,7 +1895,7 @@ bool CodeGenModule::MayDropFunctionReturn(const ASTContext &Context, // complex destructor or a non-trivially copyable type. if (const RecordType *RT = ReturnType.getCanonicalType()->getAs()) { - if (const auto *ClassDecl = dyn_cast(RT->getDecl())) + if (const auto *ClassDecl = dyn_cast(RT->getOriginalDecl())) return ClassDecl->hasTrivialDestructor(); } return ReturnType.isTriviallyCopyableType(Context); @@ -2863,7 +2863,8 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, // Obj-C ARC-managed structs, MSVC callee-destroyed objects). if (!ParamType.isDestructedType() || !ParamType->isRecordType() || ParamType->castAs() - ->getDecl() + ->getOriginalDecl() + ->getDefinitionOrSelf() ->isParamDestroyedInCallee()) Attrs.addAttribute(llvm::Attribute::DeadOnReturn); } @@ -3820,7 +3821,7 @@ static void setUsedBits(CodeGenModule &CGM, const RecordType *RTy, int Offset, SmallVectorImpl &Bits) { ASTContext &Context = CGM.getContext(); int CharWidth = Context.getCharWidth(); - const RecordDecl *RD = RTy->getDecl()->getDefinition(); + const RecordDecl *RD = RTy->getOriginalDecl()->getDefinition(); const ASTRecordLayout &ASTLayout = Context.getASTRecordLayout(RD); const CGRecordLayout &Layout = CGM.getTypes().getCGRecordLayout(RD); @@ -4281,7 +4282,10 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args, // Deactivate the cleanup for the callee-destructed param that was pushed. if (type->isRecordType() && !CurFuncIsThunk && - type->castAs()->getDecl()->isParamDestroyedInCallee() && + type->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->isParamDestroyedInCallee() && param->needsDestruction(getContext())) { EHScopeStack::stable_iterator cleanup = CalleeDestructedParamCleanups.lookup(cast(param)); @@ -4877,8 +4881,10 @@ 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()->getDecl()->isParamDestroyedInCallee()) { + if (type->isRecordType() && type->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->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 e6437a6865fd3..e9a92ae0f01cb 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -181,7 +181,9 @@ CharUnits CodeGenModule::computeNonVirtualBaseClassOffset( const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); const auto *BaseDecl = - cast(Base->getType()->castAs()->getDecl()); + cast( + Base->getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); // Add the offset. Offset += Layout.getBaseClassOffset(BaseDecl); @@ -301,7 +303,8 @@ Address CodeGenFunction::GetAddressOfBaseClass( // and hence will not require any further steps. if ((*Start)->isVirtual()) { VBase = cast( - (*Start)->getType()->castAs()->getDecl()); + (*Start)->getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); ++Start; } @@ -558,7 +561,8 @@ static void EmitBaseInitializer(CodeGenFunction &CGF, const Type *BaseType = BaseInit->getBaseClass(); const auto *BaseClassDecl = - cast(BaseType->castAs()->getDecl()); + cast(BaseType->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); bool isBaseVirtual = BaseInit->isBaseVirtual(); @@ -1264,7 +1268,8 @@ namespace { static bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit) { const Type *BaseType = BaseInit->getBaseClass(); const auto *BaseClassDecl = - cast(BaseType->castAs()->getDecl()); + cast(BaseType->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); return BaseClassDecl->isDynamicClass(); } @@ -1373,7 +1378,9 @@ HasTrivialDestructorBody(ASTContext &Context, continue; const CXXRecordDecl *NonVirtualBase = - cast(I.getType()->castAs()->getDecl()); + cast( + I.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); if (!HasTrivialDestructorBody(Context, NonVirtualBase, MostDerivedClassDecl)) return false; @@ -1382,8 +1389,10 @@ HasTrivialDestructorBody(ASTContext &Context, if (BaseClassDecl == MostDerivedClassDecl) { // Check virtual bases. for (const auto &I : BaseClassDecl->vbases()) { - const CXXRecordDecl *VirtualBase = - cast(I.getType()->castAs()->getDecl()); + const auto *VirtualBase = + cast( + I.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); if (!HasTrivialDestructorBody(Context, VirtualBase, MostDerivedClassDecl)) return false; @@ -1403,7 +1412,8 @@ FieldHasTrivialDestructorBody(ASTContext &Context, if (!RT) return true; - CXXRecordDecl *FieldClassDecl = cast(RT->getDecl()); + auto *FieldClassDecl = + cast(RT->getOriginalDecl())->getDefinitionOrSelf(); // The destructor for an implicit anonymous union member is never invoked. if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion()) @@ -1898,7 +1908,9 @@ void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD, // the reverse order. for (const auto &Base : ClassDecl->vbases()) { auto *BaseClassDecl = - cast(Base.getType()->castAs()->getDecl()); + cast( + Base.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); if (BaseClassDecl->hasTrivialDestructor()) { // Under SanitizeMemoryUseAfterDtor, poison the trivial base class @@ -1964,7 +1976,7 @@ void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD, // Anonymous union members do not have their destructors called. const RecordType *RT = type->getAsUnionType(); - if (RT && RT->getDecl()->isAnonymousStructOrUnion()) + if (RT && RT->getOriginalDecl()->isAnonymousStructOrUnion()) continue; CleanupKind cleanupKind = getCleanupKind(dtorKind); @@ -2119,7 +2131,8 @@ void CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF, Address addr, QualType type) { const RecordType *rtype = type->castAs(); - const CXXRecordDecl *record = cast(rtype->getDecl()); + const auto *record = + cast(rtype->getOriginalDecl())->getDefinitionOrSelf(); const CXXDestructorDecl *dtor = record->getDestructor(); assert(!dtor->isTrivial()); CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false, @@ -2639,8 +2652,9 @@ void CodeGenFunction::getVTablePointers(BaseSubobject Base, // Traverse bases. for (const auto &I : RD->bases()) { - auto *BaseDecl = - cast(I.getType()->castAs()->getDecl()); + auto *BaseDecl = cast( + I.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); // Ignore classes without a vtable. if (!BaseDecl->isDynamicClass()) @@ -2840,7 +2854,8 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived, if (!ClassTy) return; - const CXXRecordDecl *ClassDecl = cast(ClassTy->getDecl()); + const auto *ClassDecl = + cast(ClassTy->getOriginalDecl())->getDefinitionOrSelf(); if (!ClassDecl->isCompleteDefinition() || !ClassDecl->isDynamicClass()) return; diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index d7918e8d3449a..69a0286ee4758 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1294,7 +1294,7 @@ static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM, static SmallString<256> getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM, llvm::DICompileUnit *TheCU) { SmallString<256> Identifier; - const TagDecl *TD = Ty->getDecl(); + const TagDecl *TD = Ty->getOriginalDecl()->getDefinitionOrSelf(); if (!needsTypeIdentifier(TD, CGM, TheCU)) return Identifier; @@ -1330,8 +1330,8 @@ static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD) { llvm::DICompositeType * CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty, llvm::DIScope *Ctx) { - const RecordDecl *RD = Ty->getDecl(); - if (llvm::DIType *T = getTypeOrNull(CGM.getContext().getRecordType(RD))) + const RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf(); + if (llvm::DIType *T = getTypeOrNull(QualType(Ty, 0))) return cast(T); llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation()); const unsigned Line = @@ -2367,7 +2367,9 @@ void CGDebugInfo::CollectCXXBasesAux( const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); for (const auto &BI : Bases) { const auto *Base = - cast(BI.getType()->castAs()->getDecl()); + cast( + BI.getType()->castAs()->getOriginalDecl()) + ->getDefinition(); if (!SeenTypes.insert(Base).second) continue; auto *BaseTy = getOrCreateType(BI.getType(), Unit); @@ -3028,7 +3030,7 @@ void CGDebugInfo::completeRequiredType(const RecordDecl *RD) { } llvm::DIType *CGDebugInfo::CreateType(const RecordType *Ty) { - RecordDecl *RD = Ty->getDecl(); + RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf(); llvm::DIType *T = cast_or_null(getTypeOrNull(QualType(Ty, 0))); if (T || shouldOmitDefinition(DebugKind, DebugTypeExtRefs, RD, CGM.getLangOpts())) { @@ -3056,7 +3058,7 @@ llvm::DIType *CGDebugInfo::GetPreferredNameType(const CXXRecordDecl *RD, std::pair CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) { - RecordDecl *RD = Ty->getDecl(); + RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf(); // Get overall information about the record type for the debug info. llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation()); @@ -4098,7 +4100,7 @@ CGDebugInfo::getOrCreateLimitedType(const RecordType *Ty) { // TODO: Currently used for context chains when limiting debug info. llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) { - RecordDecl *RD = Ty->getDecl(); + RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf(); // Get overall information about the record type for the debug info. StringRef RDName = getClassName(RD); @@ -5081,7 +5083,7 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD, } else if (const auto *RT = dyn_cast(VD->getType())) { // If VD is an anonymous union then Storage represents value for // all union fields. - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->isUnion() && RD->isAnonymousStructOrUnion()) { // GDB has trouble finding local variables in anonymous unions, so we emit // artificial local variables for each of the members. @@ -5631,8 +5633,9 @@ llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls( // Ignore unnamed fields, but recurse into anonymous records. if (FieldName.empty()) { if (const auto *RT = dyn_cast(Field->getType())) - GVE = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName, - Var, DContext); + GVE = + CollectAnonRecordDecls(RT->getOriginalDecl()->getDefinitionOrSelf(), + Unit, LineNo, LinkageName, Var, DContext); continue; } // Use VarDecl's Tag, Scope and Line number. @@ -5651,7 +5654,7 @@ static bool ReferencesAnonymousEntity(RecordType *RT) { // But so long as it's not one of those, it doesn't matter if some sub-type // of the record (a template parameter) can't be reconstituted - because the // un-reconstitutable type itself will carry its own name. - const auto *RD = dyn_cast(RT->getDecl()); + const auto *RD = dyn_cast(RT->getOriginalDecl()); if (!RD) return false; if (!RD->getIdentifier()) @@ -5713,12 +5716,12 @@ struct ReconstitutableType : public RecursiveASTVisitor { bool TraverseEnumType(EnumType *ET, bool = false) { // Unnamed enums can't be reconstituted due to a lack of column info we // produce in the DWARF, so we can't get Clang's full name back. - if (const auto *ED = dyn_cast(ET->getDecl())) { + if (const auto *ED = dyn_cast(ET->getOriginalDecl())) { if (!ED->getIdentifier()) { Reconstitutable = false; return false; } - if (!ED->isExternallyVisible()) { + if (!ED->getDefinitionOrSelf()->isExternallyVisible()) { Reconstitutable = false; return false; } @@ -5914,7 +5917,8 @@ 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()->getDecl(); + const RecordDecl *RD = + T->castAs()->getOriginalDecl()->getDefinitionOrSelf(); 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 6e0d55059cfeb..55155ada9b9c7 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1569,7 +1569,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { ; if (const RecordType *RecordTy = Ty->getAs()) { - const auto *RD = RecordTy->getDecl(); + const auto *RD = RecordTy->getOriginalDecl()->getDefinitionOrSelf(); const auto *CXXRD = dyn_cast(RD); if ((CXXRD && !CXXRD->hasTrivialDestructor()) || RD->isNonTrivialToPrimitiveDestroy()) { @@ -2729,7 +2729,10 @@ 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()->getDecl()->isParamDestroyedInCallee()) { + Ty->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->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 f865ba5eb13a4..1b1f6a98988ef 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -397,9 +397,10 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M, if (const RecordType *RT = E->getType()->getBaseElementTypeUnsafe()->getAs()) { // Get the destructor for the reference temporary. - if (auto *ClassDecl = dyn_cast(RT->getDecl()); + if (auto *ClassDecl = dyn_cast(RT->getOriginalDecl()); ClassDecl && !ClassDecl->hasTrivialDestructor()) - ReferenceTemporaryDtor = ClassDecl->getDestructor(); + ReferenceTemporaryDtor = + ClassDecl->getDefinitionOrSelf()->getDestructor(); } if (!ReferenceTemporaryDtor) @@ -1749,9 +1750,11 @@ static bool isConstantEmittableObjectType(QualType type) { // Otherwise, all object types satisfy this except C++ classes with // mutable subobjects or non-trivial copy/destroy behavior. if (const auto *RT = dyn_cast(type)) - if (const auto *RD = dyn_cast(RT->getDecl())) + if (const auto *RD = dyn_cast(RT->getOriginalDecl())) { + RD = RD->getDefinitionOrSelf(); if (RD->hasMutableFields() || !RD->isTrivial()) return false; + } return true; } @@ -1912,8 +1915,10 @@ static bool getRangeForType(CodeGenFunction &CGF, QualType Ty, llvm::APInt &Min, llvm::APInt &End, bool StrictEnums, bool IsBool) { const EnumType *ET = Ty->getAs(); - bool IsRegularCPlusPlusEnum = CGF.getLangOpts().CPlusPlus && StrictEnums && - ET && !ET->getDecl()->isFixed(); + const EnumDecl *ED = + ET ? ET->getOriginalDecl()->getDefinitionOrSelf() : nullptr; + bool IsRegularCPlusPlusEnum = + CGF.getLangOpts().CPlusPlus && StrictEnums && ET && !ED->isFixed(); if (!IsBool && !IsRegularCPlusPlusEnum) return false; @@ -4266,7 +4271,9 @@ static bool IsPreserveAIArrayBase(CodeGenFunction &CGF, const Expr *ArrayBase) { const auto *PointeeT = PtrT->getPointeeType() ->getUnqualifiedDesugaredType(); if (const auto *RecT = dyn_cast(PointeeT)) - return RecT->getDecl()->hasAttr(); + return RecT->getOriginalDecl() + ->getMostRecentDecl() + ->hasAttr(); return false; } @@ -5624,7 +5631,9 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { case CK_DerivedToBase: { const auto *DerivedClassTy = E->getSubExpr()->getType()->castAs(); - auto *DerivedClassDecl = cast(DerivedClassTy->getDecl()); + auto *DerivedClassDecl = + cast(DerivedClassTy->getOriginalDecl()) + ->getDefinitionOrSelf(); LValue LV = EmitLValue(E->getSubExpr()); Address This = LV.getAddress(); @@ -5644,7 +5653,9 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { return EmitAggExprToLValue(E); case CK_BaseToDerived: { const auto *DerivedClassTy = E->getType()->castAs(); - auto *DerivedClassDecl = cast(DerivedClassTy->getDecl()); + auto *DerivedClassDecl = + cast(DerivedClassTy->getOriginalDecl()) + ->getDefinitionOrSelf(); LValue LV = EmitLValue(E->getSubExpr()); @@ -6702,7 +6713,7 @@ void CodeGenFunction::FlattenAccessAndType( WorkList.emplace_back(CAT->getElementType(), IdxListCopy); } } else if (const auto *RT = dyn_cast(T)) { - const RecordDecl *Record = RT->getDecl(); + const RecordDecl *Record = RT->getOriginalDecl()->getDefinitionOrSelf(); assert(!Record->isUnion() && "Union types not supported in flat cast."); const CXXRecordDecl *CXXD = dyn_cast(Record); diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index cad6731173700..2c1081d665231 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -272,7 +272,7 @@ bool AggExprEmitter::TypeRequiresGCollection(QualType T) { if (!RecordTy) return false; // Don't mess with non-trivial C++ types. - RecordDecl *Record = RecordTy->getDecl(); + RecordDecl *Record = RecordTy->getOriginalDecl()->getDefinitionOrSelf(); if (isa(Record) && (cast(Record)->hasNonTrivialCopyConstructor() || !cast(Record)->hasTrivialDestructor())) @@ -428,7 +428,10 @@ AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { Ctx.getAsConstantArrayType(E->getSubExpr()->getType()); assert(ArrayType && "std::initializer_list constructed from non-array"); - RecordDecl *Record = E->getType()->castAs()->getDecl(); + RecordDecl *Record = E->getType() + ->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); RecordDecl::field_iterator Field = Record->field_begin(); assert(Field != Record->field_end() && Ctx.hasSameType(Field->getType()->getPointeeType(), @@ -1810,7 +1813,10 @@ 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()->getDecl(); + RecordDecl *record = ExprToVisit->getType() + ->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); // We'll need to enter cleanup scopes in case any of the element // initializers throws an exception. @@ -2120,7 +2126,7 @@ static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) { // referencee. InitListExprs for unions and arrays can't have references. if (const RecordType *RT = E->getType()->getAs()) { if (!RT->isUnionType()) { - RecordDecl *SD = RT->getDecl(); + RecordDecl *SD = RT->getOriginalDecl()->getDefinitionOrSelf(); CharUnits NumNonZeroBytes = CharUnits::Zero(); unsigned ILEElement = 0; @@ -2172,7 +2178,7 @@ static void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E, if (CGF.getLangOpts().CPlusPlus) if (const RecordType *RT = CGF.getContext() .getBaseElementType(E->getType())->getAs()) { - const CXXRecordDecl *RD = cast(RT->getDecl()); + const CXXRecordDecl *RD = cast(RT->getOriginalDecl()); if (RD->hasUserDeclaredConstructor()) return; } @@ -2293,7 +2299,8 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty, if (getLangOpts().CPlusPlus) { if (const RecordType *RT = Ty->getAs()) { - CXXRecordDecl *Record = cast(RT->getDecl()); + auto *Record = + cast(RT->getOriginalDecl())->getDefinitionOrSelf(); assert((Record->hasTrivialCopyConstructor() || Record->hasTrivialCopyAssignment() || Record->hasTrivialMoveConstructor() || @@ -2377,7 +2384,7 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty, if (CGM.getLangOpts().getGC() == LangOptions::NonGC) { // fall through } else if (const RecordType *RecordTy = Ty->getAs()) { - RecordDecl *Record = RecordTy->getDecl(); + RecordDecl *Record = RecordTy->getOriginalDecl()->getDefinitionOrSelf(); if (Record->hasObjectMember()) { CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, SizeVal); @@ -2386,7 +2393,9 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty, } else if (Ty->isArrayType()) { QualType BaseType = getContext().getBaseElementType(Ty); if (const RecordType *RecordTy = BaseType->getAs()) { - if (RecordTy->getDecl()->hasObjectMember()) { + if (RecordTy->getOriginalDecl() + ->getDefinitionOrSelf() + ->hasObjectMember()) { CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, SizeVal); return; diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index e4791faaf187e..70b12231d65a3 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -181,7 +181,7 @@ static CXXRecordDecl *getCXXRecord(const Expr *E) { if (const PointerType *PTy = T->getAs()) T = PTy->getPointeeType(); const RecordType *Ty = T->castAs(); - return cast(Ty->getDecl()); + return cast(Ty->getOriginalDecl())->getDefinitionOrSelf(); } // Note: This function also emit constructor calls to support a MSVC @@ -1236,11 +1236,12 @@ void CodeGenFunction::EmitNewArrayInitializer( // usually use memset. if (auto *ILE = dyn_cast(Init)) { if (const RecordType *RType = ILE->getType()->getAs()) { - if (RType->getDecl()->isStruct()) { + const RecordDecl *RD = RType->getOriginalDecl()->getDefinitionOrSelf(); + if (RD->isStruct()) { unsigned NumElements = 0; - if (auto *CXXRD = dyn_cast(RType->getDecl())) + if (auto *CXXRD = dyn_cast(RD)) NumElements = CXXRD->getNumBases(); - for (auto *Field : RType->getDecl()->fields()) + for (auto *Field : RD->fields()) if (!Field->isUnnamedBitField()) ++NumElements; // FIXME: Recurse into nested InitListExprs. @@ -1686,9 +1687,11 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { QualType AlignValT = sizeType; if (allocatorType->getNumParams() > IndexOfAlignArg) { AlignValT = allocatorType->getParamType(IndexOfAlignArg); - assert(getContext().hasSameUnqualifiedType( - AlignValT->castAs()->getDecl()->getIntegerType(), - sizeType) && + assert(getContext().hasSameUnqualifiedType(AlignValT->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->getIntegerType(), + sizeType) && "wrong type for alignment parameter"); ++ParamsToSkip; } else { @@ -1971,7 +1974,8 @@ static bool EmitObjectDelete(CodeGenFunction &CGF, // destructor is virtual, we'll just emit the vcall and return. const CXXDestructorDecl *Dtor = nullptr; if (const RecordType *RT = ElementType->getAs()) { - CXXRecordDecl *RD = cast(RT->getDecl()); + auto *RD = + cast(RT->getOriginalDecl())->getDefinitionOrSelf(); if (RD->hasDefinition() && !RD->hasTrivialDestructor()) { Dtor = RD->getDestructor(); diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 715bd392f59f7..a96c1518d2a1d 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -714,7 +714,10 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter, } bool ConstStructBuilder::Build(const InitListExpr *ILE, bool AllowOverwrite) { - RecordDecl *RD = ILE->getType()->castAs()->getDecl(); + RecordDecl *RD = ILE->getType() + ->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); unsigned FieldNo = -1; @@ -977,7 +980,8 @@ bool ConstStructBuilder::DoZeroInitPadding(const ASTRecordLayout &Layout, llvm::Constant *ConstStructBuilder::Finalize(QualType Type) { Type = Type.getNonReferenceType(); - RecordDecl *RD = Type->castAs()->getDecl(); + RecordDecl *RD = + Type->castAs()->getOriginalDecl()->getDefinitionOrSelf(); llvm::Type *ValTy = CGM.getTypes().ConvertType(Type); return Builder.build(ValTy, RD->hasFlexibleArrayMember()); } @@ -1000,7 +1004,8 @@ llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter, ConstantAggregateBuilder Const(Emitter.CGM); ConstStructBuilder Builder(Emitter, Const, CharUnits::Zero()); - const RecordDecl *RD = ValTy->castAs()->getDecl(); + const RecordDecl *RD = + ValTy->castAs()->getOriginalDecl()->getDefinitionOrSelf(); const CXXRecordDecl *CD = dyn_cast(RD); if (!Builder.Build(Val, RD, false, CD, CharUnits::Zero())) return nullptr; @@ -1506,7 +1511,9 @@ class ConstExprEmitter llvm::Type *ValTy = CGM.getTypes().ConvertType(destType); bool HasFlexibleArray = false; if (const auto *RT = destType->getAs()) - HasFlexibleArray = RT->getDecl()->hasFlexibleArrayMember(); + HasFlexibleArray = RT->getOriginalDecl() + ->getDefinitionOrSelf() + ->hasFlexibleArrayMember(); return Const.build(ValTy, HasFlexibleArray); } @@ -2640,7 +2647,9 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM, } const CXXRecordDecl *base = - cast(I.getType()->castAs()->getDecl()); + cast( + I.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); // Ignore empty bases. if (isEmptyRecordForLayout(CGM.getContext(), I.getType()) || @@ -2679,8 +2688,10 @@ 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 CXXRecordDecl *base = - cast(I.getType()->castAs()->getDecl()); + const auto *base = + cast( + I.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); // Ignore empty bases. if (isEmptyRecordForLayout(CGM.getContext(), I.getType())) @@ -2746,7 +2757,9 @@ llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) { } if (const RecordType *RT = T->getAs()) - return ::EmitNullConstant(*this, RT->getDecl(), /*complete object*/ true); + return ::EmitNullConstant(*this, + RT->getOriginalDecl()->getDefinitionOrSelf(), + /*complete object*/ true); assert(T->isMemberDataPointerType() && "Should only see pointers to data members here!"); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 44931d0481e26..0318f85a344d7 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -3515,7 +3515,9 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) { case OffsetOfNode::Field: { FieldDecl *MemberDecl = ON.getField(); - RecordDecl *RD = CurrentType->castAs()->getDecl(); + RecordDecl *RD = CurrentType->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD); // Compute the index of the field in its parent. @@ -3548,15 +3550,16 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) { continue; } - RecordDecl *RD = CurrentType->castAs()->getDecl(); - const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD); + const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout( + CurrentType->castAs()->getOriginalDecl()); // Save the element type. CurrentType = ON.getBase()->getType(); // Compute the offset to the base. auto *BaseRT = CurrentType->castAs(); - auto *BaseRD = cast(BaseRT->getDecl()); + auto *BaseRD = + cast(BaseRT->getOriginalDecl())->getDefinitionOrSelf(); 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 8529ec4190d13..1b941fff8b644 100644 --- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp +++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp @@ -39,7 +39,8 @@ template struct StructVisitor { template void visitStructFields(QualType QT, CharUnits CurStructOffset, Ts... Args) { - const RecordDecl *RD = QT->castAs()->getDecl(); + const RecordDecl *RD = + QT->castAs()->getOriginalDecl()->getDefinitionOrSelf(); // Iterate over the fields of the struct. for (const FieldDecl *FD : RD->fields()) { @@ -464,7 +465,8 @@ template struct GenFuncBase { if (WrongType) { std::string FuncName = std::string(F->getName()); - SourceLocation Loc = QT->castAs()->getDecl()->getLocation(); + SourceLocation Loc = + QT->castAs()->getOriginalDecl()->getLocation(); CGM.Error(Loc, "special function " + FuncName + " for non-trivial C struct has incorrect type"); return nullptr; diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 24b6ce7c1c70d..b5f17b812222a 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -1000,7 +1000,9 @@ PropertyImplStrategy::PropertyImplStrategy(CodeGenModule &CGM, // Compute whether the ivar has strong members. if (CGM.getLangOpts().getGC()) if (const RecordType *recordType = ivarType->getAs()) - HasStrong = recordType->getDecl()->hasObjectMember(); + HasStrong = recordType->getOriginalDecl() + ->getDefinitionOrSelf() + ->hasObjectMember(); // We can never access structs with object members with a native // access, because we need to use write barriers. This is what diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 14273dd2e5e12..eb4904050ae0f 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -2495,7 +2495,7 @@ void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT, CharUnits BytePos, bool &HasUnion, bool ByrefLayout) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); SmallVector Fields(RD->fields()); llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0)); const llvm::StructLayout *RecLayout = @@ -3354,7 +3354,8 @@ static bool hasWeakMember(QualType type) { } if (auto recType = type->getAs()) { - for (auto *field : recType->getDecl()->fields()) { + for (auto *field : + recType->getOriginalDecl()->getDefinitionOrSelf()->fields()) { if (hasWeakMember(field->getType())) return true; } @@ -5184,7 +5185,7 @@ CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident, } void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); // If this is a union, remember that we had one, because it might mess // up the ordering of layout entries. diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp b/clang/lib/CodeGen/CGObjCRuntime.cpp index 6e2f32022a01e..cbf99534d2ce6 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.cpp +++ b/clang/lib/CodeGen/CGObjCRuntime.cpp @@ -440,7 +440,9 @@ void CGObjCRuntime::destroyCalleeDestroyedArguments(CodeGenFunction &CGF, } else { QualType QT = param->getType(); auto *RT = QT->getAs(); - if (RT && RT->getDecl()->isParamDestroyedInCallee()) { + if (RT && RT->getOriginalDecl() + ->getDefinitionOrSelf() + ->isParamDestroyedInCallee()) { RValue RV = I->getRValue(CGF); QualType::DestructionKind DtorKind = QT.isDestructedType(); switch (DtorKind) { diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 7276b74a43ebb..29067bf956c7b 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -3915,7 +3915,10 @@ 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()->getDecl()->field_empty()) { + if (!SharedsTy->getAsStructureType() + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->field_empty()) { KmpTaskSharedsPtr = Address( CGF.EmitLoadOfScalar( CGF.EmitLValueForField( @@ -3945,8 +3948,11 @@ 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()->getDecl(); + const RecordDecl *KmpCmplrdataUD = (*FI) + ->getType() + ->getAsUnionType() + ->getOriginalDecl() + ->getDefinitionOrSelf(); if (NeedsCleanup) { llvm::Value *DestructorFn = emitDestructorsFunction( CGM, Loc, KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy, diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 1f03472d91a0f..d077ee50856b7 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2223,7 +2223,9 @@ CodeGenFunction::EmitNullInitialization(Address DestPtr, QualType Ty) { // Ignore empty classes in C++. if (getLangOpts().CPlusPlus) { if (const RecordType *RT = Ty->getAs()) { - if (cast(RT->getDecl())->isEmpty()) + if (cast(RT->getOriginalDecl()) + ->getDefinitionOrSelf() + ->isEmpty()) return; } } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 6c32c98cec011..6822113e11b69 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2974,7 +2974,7 @@ class CodeGenFunction : public CodeGenTypeCache { /// member. bool hasVolatileMember(QualType T) { if (const RecordType *RT = T->getAs()) { - const RecordDecl *RD = cast(RT->getDecl()); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); return RD->hasVolatileMember(); } return false; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 52a8e3fec539d..709614e828f0a 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4152,9 +4152,11 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { // Check if T is a class type with a destructor that's not dllimport. static bool HasNonDllImportDtor(QualType T) { if (const auto *RT = T->getBaseElementTypeUnsafe()->getAs()) - if (CXXRecordDecl *RD = dyn_cast(RT->getDecl())) + if (auto *RD = dyn_cast(RT->getOriginalDecl())) { + RD = RD->getDefinitionOrSelf(); if (RD->getDestructor() && !RD->getDestructor()->hasAttr()) return true; + } return false; } @@ -6028,7 +6030,7 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context, return true; if (const auto *RT = VarType->getAs()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); for (const FieldDecl *FD : RD->fields()) { if (FD->isBitField()) continue; diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index a02a009158d12..3dc0859cc5d51 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -143,7 +143,7 @@ static bool TypeHasMayAlias(QualType QTy) { /// Check if the given type is a valid base type to be used in access tags. static bool isValidBaseType(QualType QTy) { if (const RecordType *TTy = QTy->getAs()) { - const RecordDecl *RD = TTy->getDecl()->getDefinition(); + const RecordDecl *RD = TTy->getOriginalDecl()->getDefinition(); // Incomplete types are not valid base access types. if (!RD) return false; @@ -311,7 +311,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) { // This also covers anonymous structs and unions, which have a different // compatibility rule, but it doesn't matter because you can never have a // pointer to an anonymous struct or union. - if (!RT->getDecl()->getDeclName()) + if (!RT->getOriginalDecl()->getDeclName()) return getAnyPtr(PtrDepth); // For non-builtin types use the mangled name of the canonical type. @@ -333,14 +333,15 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) { // Enum types are distinct types. In C++ they have "underlying types", // however they aren't related for TBAA. if (const EnumType *ETy = dyn_cast(Ty)) { + const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf(); if (!Features.CPlusPlus) - return getTypeInfo(ETy->getDecl()->getIntegerType()); + return getTypeInfo(ED->getIntegerType()); // In C++ mode, types have linkage, so we can rely on the ODR and // on their mangled names, if they're external. // TODO: Is there a way to get a program-wide unique name for a // decl with local linkage or no linkage? - if (!ETy->getDecl()->isExternallyVisible()) + if (!ED->isExternallyVisible()) return getChar(); SmallString<256> OutName; @@ -433,7 +434,7 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, llvm::MDBuilder::TBAAStructField(BaseOffset, Size, TBAATag)); return true; } - const RecordDecl *RD = TTy->getDecl()->getDefinition(); + const RecordDecl *RD = TTy->getOriginalDecl()->getDefinition(); if (RD->hasFlexibleArrayMember()) return false; @@ -514,7 +515,7 @@ CodeGenTBAA::getTBAAStructInfo(QualType QTy) { llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) { if (auto *TTy = dyn_cast(Ty)) { - const RecordDecl *RD = TTy->getDecl()->getDefinition(); + const RecordDecl *RD = TTy->getOriginalDecl()->getDefinition(); const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); using TBAAStructField = llvm::MDBuilder::TBAAStructField; SmallVector Fields; diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index d0209e03808ee..f2a0a649a88fd 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -312,11 +312,11 @@ llvm::Type *CodeGenTypes::ConvertFunctionTypeInternal(QualType QFT) { // Force conversion of all the relevant record types, to make sure // we re-convert the FunctionType when appropriate. if (const RecordType *RT = FT->getReturnType()->getAs()) - ConvertRecordDeclType(RT->getDecl()); + ConvertRecordDeclType(RT->getOriginalDecl()->getDefinitionOrSelf()); if (const FunctionProtoType *FPT = dyn_cast(FT)) for (unsigned i = 0, e = FPT->getNumParams(); i != e; i++) if (const RecordType *RT = FPT->getParamType(i)->getAs()) - ConvertRecordDeclType(RT->getDecl()); + ConvertRecordDeclType(RT->getOriginalDecl()->getDefinitionOrSelf()); SkippedLayout = true; @@ -374,7 +374,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { // RecordTypes are cached and processed specially. if (const RecordType *RT = dyn_cast(Ty)) - return ConvertRecordDeclType(RT->getDecl()); + return ConvertRecordDeclType(RT->getOriginalDecl()->getDefinitionOrSelf()); llvm::Type *CachedType = nullptr; auto TCI = TypeCache.find(Ty); @@ -700,7 +700,8 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { break; case Type::Enum: { - const EnumDecl *ED = cast(Ty)->getDecl(); + const EnumDecl *ED = + cast(Ty)->getOriginalDecl()->getDefinitionOrSelf(); if (ED->isCompleteDefinition() || ED->isFixed()) return ConvertType(ED->getIntegerType()); // Return a placeholder 'i32' type. This can be changed later when the @@ -813,7 +814,10 @@ 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()->getDecl()); + ConvertRecordDeclType(I.getType() + ->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf()); } } @@ -872,7 +876,7 @@ bool CodeGenTypes::isZeroInitializable(QualType T) { // Records are non-zero-initializable if they contain any // non-zero-initializable subobjects. if (const RecordType *RT = T->getAs()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); return isZeroInitializable(RD); } diff --git a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp index 1ed33894b15aa..ac56dda74abb7 100644 --- a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp +++ b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp @@ -101,7 +101,8 @@ llvm::TargetExtType *HLSLBufferLayoutBuilder::createLayoutType( const RecordType *RT = RecordTypes.back(); RecordTypes.pop_back(); - for (const auto *FD : RT->getDecl()->fields()) { + for (const auto *FD : + RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) { assert((!PackOffsets || Index < PackOffsets->size()) && "number of elements in layout struct does not match number of " "packoffset annotations"); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 25f06050e59e7..f0f7b97c624f7 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1392,8 +1392,9 @@ void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF, // to pass to the deallocation function. // Grab the vtable pointer as an intptr_t*. - auto *ClassDecl = - cast(ElementType->castAs()->getDecl()); + auto *ClassDecl = cast( + ElementType->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); llvm::Value *VTable = CGF.GetVTablePtr(Ptr, CGF.UnqualPtrTy, ClassDecl); // Track back to entry -2 and pull out the offset there. @@ -1479,7 +1480,8 @@ void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) { // trivial destructor (or isn't a record), we just pass null. llvm::Constant *Dtor = nullptr; if (const RecordType *RecordTy = ThrowType->getAs()) { - CXXRecordDecl *Record = cast(RecordTy->getDecl()); + CXXRecordDecl *Record = + cast(RecordTy->getOriginalDecl())->getDefinitionOrSelf(); if (!Record->hasTrivialDestructor()) { // __cxa_throw is declared to take its destructor as void (*)(void *). We // must match that if function pointers can be authenticated with a @@ -1606,7 +1608,8 @@ llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF, Address ThisPtr, llvm::Type *StdTypeInfoPtrTy) { auto *ClassDecl = - cast(SrcRecordTy->castAs()->getDecl()); + cast(SrcRecordTy->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); llvm::Value *Value = CGF.GetVTablePtr(ThisPtr, CGM.GlobalsInt8PtrTy, ClassDecl); @@ -1763,7 +1766,8 @@ llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy) { auto *ClassDecl = - cast(SrcRecordTy->castAs()->getDecl()); + cast(SrcRecordTy->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); llvm::Value *OffsetToTop; if (CGM.getItaniumVTableContext().isRelativeLayout()) { // Get the vtable pointer. @@ -3755,7 +3759,8 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, if (!Context.getLangOpts().RTTI) return false; if (const RecordType *RecordTy = dyn_cast(Ty)) { - const CXXRecordDecl *RD = cast(RecordTy->getDecl()); + const CXXRecordDecl *RD = + cast(RecordTy->getOriginalDecl())->getDefinitionOrSelf(); if (!RD->hasDefinition()) return false; @@ -3789,7 +3794,9 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, /// IsIncompleteClassType - Returns whether the given record type is incomplete. static bool IsIncompleteClassType(const RecordType *RecordTy) { - return !RecordTy->getDecl()->isCompleteDefinition(); + return !RecordTy->getOriginalDecl() + ->getDefinitionOrSelf() + ->isCompleteDefinition(); } /// ContainsIncompleteClassType - Returns whether the given type contains an @@ -3844,8 +3851,9 @@ static bool CanUseSingleInheritance(const CXXRecordDecl *RD) { return false; // Check that the class is dynamic iff the base is. - auto *BaseDecl = - cast(Base->getType()->castAs()->getDecl()); + auto *BaseDecl = cast( + Base->getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); if (!BaseDecl->isEmpty() && BaseDecl->isDynamicClass() != RD->isDynamicClass()) return false; @@ -3924,7 +3932,8 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty, case Type::Record: { const CXXRecordDecl *RD = - cast(cast(Ty)->getDecl()); + cast(cast(Ty)->getOriginalDecl()) + ->getDefinitionOrSelf(); if (!RD->hasDefinition() || !RD->getNumBases()) { VTableName = ClassTypeInfo; @@ -4046,7 +4055,8 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM, return llvm::GlobalValue::LinkOnceODRLinkage; if (const RecordType *Record = dyn_cast(Ty)) { - const CXXRecordDecl *RD = cast(Record->getDecl()); + const CXXRecordDecl *RD = + cast(Record->getOriginalDecl())->getDefinitionOrSelf(); if (RD->hasAttr()) return llvm::GlobalValue::WeakODRLinkage; if (CGM.getTriple().isWindowsItaniumEnvironment()) @@ -4210,7 +4220,8 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( case Type::Record: { const CXXRecordDecl *RD = - cast(cast(Ty)->getDecl()); + cast(cast(Ty)->getOriginalDecl()) + ->getDefinitionOrSelf(); if (!RD->hasDefinition() || !RD->getNumBases()) { // We don't need to emit any fields. break; @@ -4257,7 +4268,8 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( if (CGM.getTarget().hasPS4DLLImportExport() && GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) { if (const RecordType *RecordTy = dyn_cast(Ty)) { - const CXXRecordDecl *RD = cast(RecordTy->getDecl()); + const CXXRecordDecl *RD = cast(RecordTy->getOriginalDecl()) + ->getDefinitionOrSelf(); if (RD->hasAttr() || CXXRecordNonInlineHasAttr(RD)) GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass; @@ -4361,8 +4373,9 @@ static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, unsigned Flags = 0; - auto *BaseDecl = - cast(Base->getType()->castAs()->getDecl()); + auto *BaseDecl = cast( + Base->getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); if (Base->isVirtual()) { // Mark the virtual base as seen. @@ -4462,7 +4475,9 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType())); auto *BaseDecl = - cast(Base.getType()->castAs()->getDecl()); + cast( + Base.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); int64_t OffsetFlags = 0; diff --git a/clang/lib/CodeGen/SwiftCallingConv.cpp b/clang/lib/CodeGen/SwiftCallingConv.cpp index 10f9f20bca313..de58e0d95a866 100644 --- a/clang/lib/CodeGen/SwiftCallingConv.cpp +++ b/clang/lib/CodeGen/SwiftCallingConv.cpp @@ -66,9 +66,9 @@ void SwiftAggLowering::addTypedData(QualType type, CharUnits begin) { // Record types. if (auto recType = type->getAs()) { - addTypedData(recType->getDecl(), begin); + addTypedData(recType->getOriginalDecl(), begin); - // Array types. + // Array types. } else if (type->isArrayType()) { // Incomplete array types (flexible array members?) don't provide // data to lay out, and the other cases shouldn't be possible. @@ -814,7 +814,7 @@ static ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type, bool forReturn) { unsigned IndirectAS = CGM.getDataLayout().getAllocaAddrSpace(); if (auto recordType = dyn_cast(type)) { - auto record = recordType->getDecl(); + auto record = recordType->getOriginalDecl(); auto &layout = CGM.getContext().getASTRecordLayout(record); if (mustPassRecordIndirectly(CGM, record)) @@ -822,7 +822,8 @@ static ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type, /*AddrSpace=*/IndirectAS, /*byval=*/false); SwiftAggLowering lowering(CGM); - lowering.addTypedData(recordType->getDecl(), CharUnits::Zero(), layout); + lowering.addTypedData(recordType->getOriginalDecl(), CharUnits::Zero(), + layout); lowering.finish(); return classifyExpandedType(lowering, forReturn, layout.getAlignment(), diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index b82c46966cf0b..289f8a9dcf211 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -375,7 +375,7 @@ 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->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); if (const auto *EIT = Ty->getAs()) if (EIT->getNumBits() > 128) @@ -496,7 +496,7 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn, const RecordType *RT = Ty->getAs(); if (!RT) return false; - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) { for (const auto &I : CXXRD->bases()) if (!Self(Self, I.getType())) @@ -548,7 +548,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->getDecl()->getIntegerType(); + RetTy = + EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); if (const auto *EIT = RetTy->getAs()) if (EIT->getNumBits() > 128) @@ -744,7 +745,7 @@ bool AArch64ABIInfo::passAsPureScalableType( return false; // Pure scalable types are never unions and never contain unions. - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->isUnion()) return false; diff --git a/clang/lib/CodeGen/Targets/AMDGPU.cpp b/clang/lib/CodeGen/Targets/AMDGPU.cpp index 47a552a7bf495..41bccbb5721b2 100644 --- a/clang/lib/CodeGen/Targets/AMDGPU.cpp +++ b/clang/lib/CodeGen/Targets/AMDGPU.cpp @@ -96,7 +96,7 @@ unsigned AMDGPUABIInfo::numRegsForType(QualType Ty) const { } if (const RecordType *RT = Ty->getAs()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); assert(!RD->hasFlexibleArrayMember()); for (const FieldDecl *Field : RD->fields()) { @@ -153,7 +153,7 @@ ABIArgInfo AMDGPUABIInfo::classifyReturnType(QualType RetTy) const { return ABIArgInfo::getDirect(CGT.ConvertType(QualType(SeltTy, 0))); if (const RecordType *RT = RetTy->getAs()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->hasFlexibleArrayMember()) return DefaultABIInfo::classifyReturnType(RetTy); } @@ -246,7 +246,7 @@ ABIArgInfo AMDGPUABIInfo::classifyArgumentType(QualType Ty, bool Variadic, return ABIArgInfo::getDirect(CGT.ConvertType(QualType(SeltTy, 0))); if (const RecordType *RT = Ty->getAs()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->hasFlexibleArrayMember()) return DefaultABIInfo::classifyArgumentType(Ty); } diff --git a/clang/lib/CodeGen/Targets/ARC.cpp b/clang/lib/CodeGen/Targets/ARC.cpp index c8db7e8f9706e..ace524e1976d9 100644 --- a/clang/lib/CodeGen/Targets/ARC.cpp +++ b/clang/lib/CodeGen/Targets/ARC.cpp @@ -106,13 +106,14 @@ ABIArgInfo ARCABIInfo::classifyArgumentType(QualType Ty, // Treat an enum type as its underlying type. if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); auto SizeInRegs = llvm::alignTo(getContext().getTypeSize(Ty), 32) / 32; if (isAggregateTypeForABI(Ty)) { // Structures with flexible arrays are always indirect. - if (RT && RT->getDecl()->hasFlexibleArrayMember()) + if (RT && + RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember()) return getIndirectByValue(Ty); // Ignore empty structs/unions. diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp index 68f9e01856486..532ba4cead244 100644 --- a/clang/lib/CodeGen/Targets/ARM.cpp +++ b/clang/lib/CodeGen/Targets/ARM.cpp @@ -383,7 +383,7 @@ 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->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); } if (const auto *EIT = Ty->getAs()) @@ -516,7 +516,7 @@ static bool isIntegerLikeType(QualType Ty, ASTContext &Context, if (!RT) return false; // Ignore records with flexible arrays. - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->hasFlexibleArrayMember()) return false; @@ -593,7 +593,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->getDecl()->getIntegerType(); + RetTy = + EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); if (const auto *EIT = RetTy->getAs()) if (EIT->getNumBits() > 64) @@ -718,7 +719,7 @@ bool ARMABIInfo::containsAnyFP16Vectors(QualType Ty) const { return false; return containsAnyFP16Vectors(AT->getElementType()); } else if (const RecordType *RT = Ty->getAs()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); // If this is a C++ record, check the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) diff --git a/clang/lib/CodeGen/Targets/BPF.cpp b/clang/lib/CodeGen/Targets/BPF.cpp index 880a891083c3a..87d50e671d251 100644 --- a/clang/lib/CodeGen/Targets/BPF.cpp +++ b/clang/lib/CodeGen/Targets/BPF.cpp @@ -48,7 +48,7 @@ class BPFABIInfo : public DefaultABIInfo { } if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); ASTContext &Context = getContext(); if (const auto *EIT = Ty->getAs()) @@ -70,7 +70,8 @@ class BPFABIInfo : public DefaultABIInfo { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = EnumTy->getDecl()->getIntegerType(); + RetTy = + EnumTy->getOriginalDecl()->getDefinitionOrSelf()->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 ef26d483a180a..7e5a16f30727f 100644 --- a/clang/lib/CodeGen/Targets/CSKY.cpp +++ b/clang/lib/CodeGen/Targets/CSKY.cpp @@ -116,7 +116,7 @@ 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->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->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 2976657360650..0c423429eda4f 100644 --- a/clang/lib/CodeGen/Targets/Hexagon.cpp +++ b/clang/lib/CodeGen/Targets/Hexagon.cpp @@ -98,7 +98,7 @@ ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty, if (!isAggregateTypeForABI(Ty)) { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); uint64_t Size = getContext().getTypeSize(Ty); if (Size <= 64) @@ -161,7 +161,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->getDecl()->getIntegerType(); + RetTy = + EnumTy->getOriginalDecl()->getDefinitionOrSelf()->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 6f75bd54a8ef2..08cb36034f6fd 100644 --- a/clang/lib/CodeGen/Targets/Lanai.cpp +++ b/clang/lib/CodeGen/Targets/Lanai.cpp @@ -102,7 +102,8 @@ ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty, if (isAggregateTypeForABI(Ty)) { // Structures with flexible arrays are always indirect. - if (RT && RT->getDecl()->hasFlexibleArrayMember()) + if (RT && + RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember()) return getIndirectResult(Ty, /*ByVal=*/true, State); // Ignore empty structs/unions. @@ -125,7 +126,7 @@ ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty, // Treat an enum type as its underlying type. if (const auto *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); bool InReg = shouldUseInReg(Ty, State); diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp index 7640f3779816a..af863e6101e2c 100644 --- a/clang/lib/CodeGen/Targets/LoongArch.cpp +++ b/clang/lib/CodeGen/Targets/LoongArch.cpp @@ -150,7 +150,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper( // Non-zero-length arrays of empty records make the struct ineligible to be // passed via FARs in C++. if (const auto *RTy = EltTy->getAs()) { - if (ArraySize != 0 && isa(RTy->getDecl()) && + if (ArraySize != 0 && isa(RTy->getOriginalDecl()) && isEmptyRecord(getContext(), EltTy, true, true)) return false; } @@ -169,7 +169,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper( // copy constructor are not eligible for the FP calling convention. if (getRecordArgABI(Ty, CGT.getCXXABI())) return false; - const RecordDecl *RD = RTy->getDecl(); + const RecordDecl *RD = RTy->getOriginalDecl()->getDefinitionOrSelf(); if (isEmptyRecord(getContext(), Ty, true, true) && (!RD->isUnion() || !isa(RD))) return true; @@ -181,7 +181,9 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper( if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) { for (const CXXBaseSpecifier &B : CXXRD->bases()) { const auto *BDecl = - cast(B.getType()->castAs()->getDecl()); + cast( + B.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); if (!detectFARsEligibleStructHelper( B.getType(), CurOff + Layout.getBaseClassOffset(BDecl), Field1Ty, Field1Off, Field2Ty, Field2Off)) @@ -369,7 +371,7 @@ 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->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->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 c025f7312959c..e12a34ce07bbe 100644 --- a/clang/lib/CodeGen/Targets/Mips.cpp +++ b/clang/lib/CodeGen/Targets/Mips.cpp @@ -161,7 +161,7 @@ llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty, uint64_t TySize) const { return llvm::StructType::get(getVMContext(), ArgList); } - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); assert(!(TySize % 8) && "Size of structure must be multiple of 8."); @@ -242,7 +242,7 @@ MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); // Make sure we pass indirectly things that are too large. if (const auto *EIT = Ty->getAs()) @@ -265,7 +265,7 @@ MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const { SmallVector RTList; if (RT && RT->isStructureOrClassType()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); unsigned FieldCnt = Layout.getFieldCount(); @@ -333,7 +333,7 @@ ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = EnumTy->getDecl()->getIntegerType(); + RetTy = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->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 82bdfe2666b52..e874617796f86 100644 --- a/clang/lib/CodeGen/Targets/NVPTX.cpp +++ b/clang/lib/CodeGen/Targets/NVPTX.cpp @@ -133,7 +133,7 @@ bool NVPTXABIInfo::isUnsupportedType(QualType T) const { const auto *RT = T->getAs(); if (!RT) return false; - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); // If this is a C++ record, check the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) @@ -174,7 +174,7 @@ ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = EnumTy->getDecl()->getIntegerType(); + RetTy = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy) : ABIArgInfo::getDirect()); @@ -183,7 +183,7 @@ 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->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->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 4df4c9f3c3475..38e76399299ec 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -154,7 +154,7 @@ class AIXTargetCodeGenInfo : public TargetCodeGenInfo { bool AIXABIInfo::isPromotableTypeForABI(QualType Ty) const { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); // Promotable integer types are required to be promoted by the ABI. if (getContext().isPromotableIntegerType(Ty)) @@ -295,7 +295,9 @@ void AIXTargetCodeGenInfo::setTargetAttributes( unsigned Alignment = Context.toBits(Context.getDeclAlign(D)) / 8; const auto *Ty = VarD->getType().getTypePtr(); const RecordDecl *RDecl = - Ty->isRecordType() ? Ty->getAs()->getDecl() : nullptr; + Ty->isRecordType() + ? Ty->getAs()->getOriginalDecl()->getDefinitionOrSelf() + : nullptr; bool EmitDiagnostic = UserSpecifiedTOC && GV->hasExternalLinkage(); auto reportUnsupportedWarning = [&](bool ShouldEmitWarning, StringRef Msg) { @@ -707,7 +709,7 @@ bool PPC64_SVR4_ABIInfo::isPromotableTypeForABI(QualType Ty) const { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->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 e3232b61a693c..1fab9e402ee7f 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -228,7 +228,7 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff, // Non-zero-length arrays of empty records make the struct ineligible for // the FP calling convention in C++. if (const auto *RTy = EltTy->getAs()) { - if (ArraySize != 0 && isa(RTy->getDecl()) && + if (ArraySize != 0 && isa(RTy->getOriginalDecl()) && isEmptyRecord(getContext(), EltTy, true, true)) return false; } @@ -250,7 +250,7 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff, return false; if (isEmptyRecord(getContext(), Ty, true, true)) return true; - const RecordDecl *RD = RTy->getDecl(); + const RecordDecl *RD = RTy->getOriginalDecl()->getDefinitionOrSelf(); // Unions aren't eligible unless they're empty (which is caught above). if (RD->isUnion()) return false; @@ -259,7 +259,9 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff, if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) { for (const CXXBaseSpecifier &B : CXXRD->bases()) { const auto *BDecl = - cast(B.getType()->castAs()->getDecl()); + cast( + B.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); CharUnits BaseOff = Layout.getBaseClassOffset(BDecl); bool Ret = detectFPCCEligibleStructHelper(B.getType(), CurOff + BaseOff, Field1Ty, Field1Off, Field2Ty, @@ -673,7 +675,7 @@ 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->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); // All integral types are promoted to XLen width if (Size < XLen && Ty->isIntegralOrEnumerationType()) { diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp index d952c6e117607..237aea755fa29 100644 --- a/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/clang/lib/CodeGen/Targets/SPIR.cpp @@ -119,7 +119,7 @@ ABIArgInfo SPIRVABIInfo::classifyReturnType(QualType RetTy) const { return DefaultABIInfo::classifyReturnType(RetTy); if (const RecordType *RT = RetTy->getAs()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->hasFlexibleArrayMember()) return DefaultABIInfo::classifyReturnType(RetTy); } @@ -187,7 +187,7 @@ ABIArgInfo SPIRVABIInfo::classifyArgumentType(QualType Ty) const { RAA == CGCXXABI::RAA_DirectInMemory); if (const RecordType *RT = Ty->getAs()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->hasFlexibleArrayMember()) return DefaultABIInfo::classifyArgumentType(Ty); } @@ -432,7 +432,7 @@ static llvm::Type *getInlineSpirvType(CodeGenModule &CGM, case SpirvOperandKind::TypeId: { QualType TypeOperand = Operand.getResultType(); if (auto *RT = TypeOperand->getAs()) { - auto *RD = RT->getDecl(); + auto *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); assert(RD->isCompleteDefinition() && "Type completion should have been required in Sema"); diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp b/clang/lib/CodeGen/Targets/Sparc.cpp index 9642196b78c63..1547bed7ea8b2 100644 --- a/clang/lib/CodeGen/Targets/Sparc.cpp +++ b/clang/lib/CodeGen/Targets/Sparc.cpp @@ -238,7 +238,7 @@ SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit) const { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->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 6ea6c7a546436..38cc4d39126be 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -146,7 +146,7 @@ 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->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); // Promotable integer types are required to be promoted by the ABI. if (ABIInfo::isPromotableIntegerTypeForABI(Ty)) @@ -211,7 +211,7 @@ QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const { const RecordType *RT = Ty->getAs(); if (RT && RT->isStructureOrClassType()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); QualType Found; // If this is a C++ record, check the bases first. @@ -455,7 +455,7 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const { if (const RecordType *RT = Ty->getAs()) { // Structures with flexible arrays have variable length, so really // fail the size test above. - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->hasFlexibleArrayMember()) return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(), /*ByVal=*/false); @@ -526,7 +526,7 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty, return true; if (const auto *RecordTy = Ty->getAs()) { - const RecordDecl *RD = RecordTy->getDecl(); + const RecordDecl *RD = RecordTy->getOriginalDecl()->getDefinitionOrSelf(); if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) if (CXXRD->hasDefinition()) for (const auto &I : CXXRD->bases()) diff --git a/clang/lib/CodeGen/Targets/WebAssembly.cpp b/clang/lib/CodeGen/Targets/WebAssembly.cpp index 9217c78a540a3..ac8dcd2a0540a 100644 --- a/clang/lib/CodeGen/Targets/WebAssembly.cpp +++ b/clang/lib/CodeGen/Targets/WebAssembly.cpp @@ -118,7 +118,8 @@ ABIArgInfo WebAssemblyABIInfo::classifyArgumentType(QualType Ty) const { const RecordType *RT = Ty->getAs(); assert(RT); bool HasBitField = false; - for (auto *Field : RT->getDecl()->fields()) { + for (auto *Field : + RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) { if (Field->isBitField()) { HasBitField = true; break; diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 1d0645751480d..d3431aae0431c 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -359,7 +359,8 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty, // Structure types are passed in register if all fields would be // passed in a register. - for (const auto *FD : RT->getDecl()->fields()) { + for (const auto *FD : + RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) { // Empty fields are ignored. if (isEmptyField(Context, FD, true)) continue; @@ -429,9 +430,9 @@ bool X86_32ABIInfo::canExpandIndirectArgument(QualType Ty) const { const RecordType *RT = Ty->getAs(); if (!RT) return false; - const RecordDecl *RD = RT->getDecl(); uint64_t Size = 0; - if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) { + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + if (const auto *CXXRD = dyn_cast(RD)) { if (!IsWin32StructABI) { // On non-Windows, we have to conservatively match our old bitcode // prototypes in order to be ABI-compatible at the bitcode level. @@ -509,7 +510,9 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, if (isAggregateTypeForABI(RetTy)) { if (const RecordType *RT = RetTy->getAs()) { // Structures with flexible arrays are always indirect. - if (RT->getDecl()->hasFlexibleArrayMember()) + if (RT->getOriginalDecl() + ->getDefinitionOrSelf() + ->hasFlexibleArrayMember()) return getIndirectReturnResult(RetTy, State); } @@ -554,7 +557,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, // Treat an enum type as its underlying type. if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = EnumTy->getDecl()->getIntegerType(); + RetTy = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); if (const auto *EIT = RetTy->getAs()) if (EIT->getNumBits() > 64) @@ -796,7 +799,8 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State, if (isAggregateTypeForABI(Ty)) { // Structures with flexible arrays are always indirect. // FIXME: This should not be byval! - if (RT && RT->getDecl()->hasFlexibleArrayMember()) + if (RT && + RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember()) return getIndirectResult(Ty, true, State); // Ignore empty structs/unions on non-Windows. @@ -831,7 +835,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State, unsigned AlignInBits = 0; if (RT) { const ASTRecordLayout &Layout = - getContext().getASTRecordLayout(RT->getDecl()); + getContext().getASTRecordLayout(RT->getOriginalDecl()); AlignInBits = getContext().toBits(Layout.getRequiredAlignment()); } else if (TI.isAlignRequired()) { AlignInBits = TI.Align; @@ -883,7 +887,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State, if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); bool InReg = shouldPrimitiveUseInReg(Ty, State); @@ -1847,7 +1851,8 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo, if (const EnumType *ET = Ty->getAs()) { // Classify the underlying integer type. - classify(ET->getDecl()->getIntegerType(), OffsetBase, Lo, Hi, isNamedArg); + classify(ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(), + OffsetBase, Lo, Hi, isNamedArg); return; } @@ -2053,7 +2058,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo, if (getRecordArgABI(RT, getCXXABI())) return; - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); // Assume variable sized types are passed in memory. if (RD->hasFlexibleArrayMember()) @@ -2070,7 +2075,9 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo, assert(!I.isVirtual() && !I.getType()->isDependentType() && "Unexpected base class!"); const auto *Base = - cast(I.getType()->castAs()->getDecl()); + cast( + I.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); // Classify this field. // @@ -2184,7 +2191,7 @@ ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty) const { if (!isAggregateTypeForABI(Ty)) { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); if (Ty->isBitIntType()) return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace()); @@ -2226,7 +2233,7 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty, !Ty->isBitIntType()) { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) : ABIArgInfo::getDirect()); @@ -2347,7 +2354,7 @@ static bool BitsContainNoUserData(QualType Ty, unsigned StartBit, } if (const RecordType *RT = Ty->getAs()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); // If this is a C++ record, check the bases first. @@ -2356,7 +2363,9 @@ static bool BitsContainNoUserData(QualType Ty, unsigned StartBit, assert(!I.isVirtual() && !I.getType()->isDependentType() && "Unexpected base class!"); const auto *Base = - cast(I.getType()->castAs()->getDecl()); + cast( + I.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); // If the base is after the span we care about, ignore it. unsigned BaseOffset = Context.toBits(Layout.getBaseClassOffset(Base)); @@ -2637,7 +2646,8 @@ ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy) const { if (Hi == NoClass && isa(ResType)) { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = RetTy->getAs()) - RetTy = EnumTy->getDecl()->getIntegerType(); + RetTy = + EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); if (RetTy->isIntegralOrEnumerationType() && isPromotableIntegerTypeForABI(RetTy)) @@ -2787,7 +2797,7 @@ X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned freeIntRegs, if (Hi == NoClass && isa(ResType)) { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); if (Ty->isIntegralOrEnumerationType() && isPromotableIntegerTypeForABI(Ty)) @@ -2866,14 +2876,15 @@ ABIArgInfo X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, unsigned &NeededInt, unsigned &NeededSSE, unsigned &MaxVectorWidth) const { - auto RT = Ty->getAs(); - assert(RT && "classifyRegCallStructType only valid with struct types"); + auto *RD = cast(Ty.getCanonicalType()) + ->getOriginalDecl() + ->getDefinitionOrSelf(); - if (RT->getDecl()->hasFlexibleArrayMember()) + if (RD->hasFlexibleArrayMember()) return getIndirectReturnResult(Ty); // Sum up bases - if (auto CXXRD = dyn_cast(RT->getDecl())) { + if (auto CXXRD = dyn_cast(RD)) { if (CXXRD->isDynamicClass()) { NeededInt = NeededSSE = 0; return getIndirectReturnResult(Ty); @@ -3313,7 +3324,7 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, unsigned &FreeSSERegs, return ABIArgInfo::getIgnore(); if (const EnumType *EnumTy = Ty->getAs()) - Ty = EnumTy->getDecl()->getIntegerType(); + Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); TypeInfo Info = getContext().getTypeInfo(Ty); uint64_t Width = Info.Width; @@ -3327,7 +3338,7 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, unsigned &FreeSSERegs, RAA == CGCXXABI::RAA_DirectInMemory); } - if (RT->getDecl()->hasFlexibleArrayMember()) + if (RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember()) return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(), /*ByVal=*/false); } diff --git a/clang/lib/CodeGen/Targets/XCore.cpp b/clang/lib/CodeGen/Targets/XCore.cpp index b7824bde5f55a..aa6947b1d956b 100644 --- a/clang/lib/CodeGen/Targets/XCore.cpp +++ b/clang/lib/CodeGen/Targets/XCore.cpp @@ -379,7 +379,7 @@ static bool appendRecordType(SmallStringEnc &Enc, const RecordType *RT, // We collect all encoded fields and order as necessary. bool IsRecursive = false; - const RecordDecl *RD = RT->getDecl()->getDefinition(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinition(); if (RD && !RD->field_empty()) { // An incomplete TypeString stub is placed in the cache for this RecordType // so that recursive calls to this RecordType will use it whilst building a @@ -428,7 +428,7 @@ static bool appendEnumType(SmallStringEnc &Enc, const EnumType *ET, Enc += "){"; // We collect all encoded enumerations and order them alphanumerically. - if (const EnumDecl *ED = ET->getDecl()->getDefinition()) { + if (const EnumDecl *ED = ET->getOriginalDecl()->getDefinition()) { SmallVector FE; for (auto I = ED->enumerator_begin(), E = ED->enumerator_end(); I != E; ++I) { diff --git a/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp b/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp index 41e4e0cf1795f..5adbbc6d1c34c 100644 --- a/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp +++ b/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp @@ -26,7 +26,7 @@ TypedefUnderlyingTypeResolver::getUnderlyingTypeDecl(QualType Type) const { if (TypedefTy) TypeDecl = TypedefTy->getDecl(); if (const TagType *TagTy = Type->getAs()) { - TypeDecl = TagTy->getDecl(); + TypeDecl = TagTy->getOriginalDecl(); } else if (const ObjCInterfaceType *ObjCITy = Type->getAs()) { TypeDecl = ObjCITy->getDecl(); diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp index bb4ff93be0397..2bc6f26d34368 100644 --- a/clang/lib/Index/IndexTypeSourceInfo.cpp +++ b/clang/lib/Index/IndexTypeSourceInfo.cpp @@ -117,7 +117,7 @@ class TypeIndexer : public RecursiveASTVisitor { } bool VisitTagTypeLoc(TagTypeLoc TL) { - TagDecl *D = TL.getDecl(); + TagDecl *D = TL.getOriginalDecl(); if (!IndexCtx.shouldIndexFunctionLocalSymbols() && D->getParentFunctionOrMethod()) return true; diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp index 16dcf88cbded8..5b1d1cb698231 100644 --- a/clang/lib/Index/USRGeneration.cpp +++ b/clang/lib/Index/USRGeneration.cpp @@ -910,9 +910,13 @@ void USRGenerator::VisitType(QualType T) { continue; } if (const TagType *TT = T->getAs()) { - Out << '$'; - VisitTagDecl(TT->getDecl()); - return; + if (const auto *ICNT = dyn_cast(TT)) { + T = ICNT->getCanonicalInjectedTST(); + } else { + Out << '$'; + VisitTagDecl(TT->getOriginalDecl()); + return; + } } if (const ObjCInterfaceType *OIT = T->getAs()) { Out << '$'; diff --git a/clang/lib/InstallAPI/Visitor.cpp b/clang/lib/InstallAPI/Visitor.cpp index 5a5eba2ca10d6..f12e04069817b 100644 --- a/clang/lib/InstallAPI/Visitor.cpp +++ b/clang/lib/InstallAPI/Visitor.cpp @@ -543,8 +543,8 @@ void InstallAPIVisitor::emitVTableSymbols(const CXXRecordDecl *D, } for (const auto &It : D->bases()) { - const CXXRecordDecl *Base = - cast(It.getType()->castAs()->getDecl()); + const CXXRecordDecl *Base = cast( + It.getType()->castAs()->getOriginalDecl()); const auto BaseAccess = getAccessForDecl(Base); if (!BaseAccess) continue; diff --git a/clang/lib/Interpreter/InterpreterValuePrinter.cpp b/clang/lib/Interpreter/InterpreterValuePrinter.cpp index 34ffd62da85e4..e1b25f7387bcd 100644 --- a/clang/lib/Interpreter/InterpreterValuePrinter.cpp +++ b/clang/lib/Interpreter/InterpreterValuePrinter.cpp @@ -66,10 +66,10 @@ static std::string QualTypeToString(ASTContext &Ctx, QualType QT) { const QualType NonRefTy = QT.getNonReferenceType(); if (const auto *TTy = llvm::dyn_cast(NonRefTy)) - return DeclTypeToString(NonRefTy, TTy->getDecl()); + return DeclTypeToString(NonRefTy, TTy->getOriginalDecl()); if (const auto *TRy = dyn_cast(NonRefTy)) - return DeclTypeToString(NonRefTy, TRy->getDecl()); + return DeclTypeToString(NonRefTy, TRy->getOriginalDecl()); const QualType Canon = NonRefTy.getCanonicalType(); @@ -105,7 +105,7 @@ static std::string EnumToString(const Value &V) { const EnumType *EnumTy = DesugaredTy.getNonReferenceType()->getAs(); assert(EnumTy && "Fail to cast to enum type"); - EnumDecl *ED = EnumTy->getDecl(); + EnumDecl *ED = EnumTy->getOriginalDecl()->getDefinitionOrSelf(); uint64_t Data = V.getULongLong(); bool IsFirst = true; llvm::APSInt AP = Ctx.MakeIntValue(Data, DesugaredTy); @@ -666,7 +666,7 @@ __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, VRef.setPtr(va_arg(args, void *)); } else { if (const auto *ET = QT->getAs()) - QT = ET->getDecl()->getIntegerType(); + QT = ET->getOriginalDecl()->getDefinitionOrSelf()->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 be2ab5587a980..84ba508e9cbc8 100644 --- a/clang/lib/Interpreter/Value.cpp +++ b/clang/lib/Interpreter/Value.cpp @@ -102,7 +102,7 @@ static Value::Kind ConvertQualTypeToKind(const ASTContext &Ctx, QualType QT) { return Value::K_Void; if (const auto *ET = QT->getAs()) - QT = ET->getDecl()->getIntegerType(); + QT = ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); const auto *BT = QT->getAs(); if (!BT || BT->isNullPtrType()) @@ -149,9 +149,9 @@ Value::Value(const Interpreter *In, void *Ty) : Interp(In), OpaqueType(Ty) { } if (const auto *RT = DtorTy->getAs()) { if (CXXRecordDecl *CXXRD = - llvm::dyn_cast(RT->getDecl())) { + llvm::dyn_cast(RT->getOriginalDecl())) { if (llvm::Expected Addr = - Interp.CompileDtorCall(CXXRD)) + Interp.CompileDtorCall(CXXRD->getDefinitionOrSelf())) DtorF = reinterpret_cast(Addr->getValue()); else llvm::logAllUnhandledErrors(Addr.takeError(), llvm::errs()); diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 56608e990fd50..48ec4a48b9e63 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1882,9 +1882,10 @@ class DeferredDiagnosticsEmitter for (const FieldDecl *FD : RD->fields()) { QualType FT = FD->getType(); if (const auto *RT = FT->getAs()) - if (const auto *ClassDecl = dyn_cast(RT->getDecl())) - if (ClassDecl->hasDefinition()) - if (CXXDestructorDecl *MemberDtor = ClassDecl->getDestructor()) + if (const auto *ClassDecl = + dyn_cast(RT->getOriginalDecl())) + if (const auto *Def = ClassDecl->getDefinition()) + if (CXXDestructorDecl *MemberDtor = Def->getDestructor()) asImpl().visitUsedDecl(MemberDtor->getLocation(), MemberDtor); } @@ -1892,9 +1893,10 @@ class DeferredDiagnosticsEmitter for (const auto &Base : RD->bases()) { QualType BaseType = Base.getType(); if (const auto *RT = BaseType->getAs()) - if (const auto *BaseDecl = dyn_cast(RT->getDecl())) - if (BaseDecl->hasDefinition()) - if (CXXDestructorDecl *BaseDtor = BaseDecl->getDestructor()) + if (const auto *BaseDecl = + dyn_cast(RT->getOriginalDecl())) + if (const auto *Def = BaseDecl->getDefinition()) + if (CXXDestructorDecl *BaseDtor = Def->getDestructor()) asImpl().visitUsedDecl(BaseDtor->getLocation(), BaseDtor); } } @@ -1907,9 +1909,10 @@ class DeferredDiagnosticsEmitter VD->needsDestruction(S.Context)) { QualType VT = VD->getType(); if (const auto *RT = VT->getAs()) - if (const auto *ClassDecl = dyn_cast(RT->getDecl())) - if (ClassDecl->hasDefinition()) - if (CXXDestructorDecl *Dtor = ClassDecl->getDestructor()) + if (const auto *ClassDecl = + dyn_cast(RT->getOriginalDecl())) + if (const auto *Def = ClassDecl->getDefinition()) + if (CXXDestructorDecl *Dtor = Def->getDestructor()) asImpl().visitUsedDecl(Dtor->getLocation(), Dtor); } diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index 576074a1f4aeb..ba560d3c52340 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/lib/Sema/SemaAccess.cpp @@ -440,7 +440,9 @@ static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC, CanQualType Friend) { if (const RecordType *RT = Friend->getAs()) - return MatchesFriend(S, EC, cast(RT->getDecl())); + return MatchesFriend( + S, EC, + cast(RT->getOriginalDecl())->getDefinitionOrSelf()); // TODO: we can do better than this if (Friend->isDependentType()) @@ -1785,7 +1787,8 @@ Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, return AR_accessible; const RecordType *RT = ObjectExpr->getType()->castAs(); - CXXRecordDecl *NamingClass = cast(RT->getDecl()); + CXXRecordDecl *NamingClass = + cast(RT->getOriginalDecl())->getDefinitionOrSelf(); AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found, ObjectExpr->getType()); diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp index 8c6a17301fba6..778941c128bdd 100644 --- a/clang/lib/Sema/SemaAvailability.cpp +++ b/clang/lib/Sema/SemaAvailability.cpp @@ -102,7 +102,7 @@ Sema::ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, std::string *Message, break; for (const Type *T = TD->getUnderlyingType().getTypePtr(); /**/; /**/) { if (auto *TT = dyn_cast(T)) { - D = TT->getDecl(); + D = TT->getOriginalDecl()->getDefinitionOrSelf(); } else if (isa(T)) { // A Subst* node represents a use through a template. // Any uses of the underlying declaration happened through it's template @@ -1011,7 +1011,7 @@ bool DiagnoseUnguardedAvailability::VisitTypeLoc(TypeLoc Ty) { return true; if (const auto *TT = dyn_cast(TyPtr)) { - TagDecl *TD = TT->getDecl(); + TagDecl *TD = TT->getOriginalDecl()->getDefinitionOrSelf(); DiagnoseDeclAvailability(TD, Range); } else if (const auto *TD = dyn_cast(TyPtr)) { diff --git a/clang/lib/Sema/SemaBPF.cpp b/clang/lib/Sema/SemaBPF.cpp index 7c00084d62dd9..6428435ed9d2a 100644 --- a/clang/lib/Sema/SemaBPF.cpp +++ b/clang/lib/Sema/SemaBPF.cpp @@ -58,10 +58,10 @@ static bool isValidPreserveTypeInfoArg(Expr *Arg) { // Record type or Enum type. const Type *Ty = ArgType->getUnqualifiedDesugaredType(); if (const auto *RT = Ty->getAs()) { - if (!RT->getDecl()->getDeclName().isEmpty()) + if (!RT->getOriginalDecl()->getDeclName().isEmpty()) return true; } else if (const auto *ET = Ty->getAs()) { - if (!ET->getDecl()->getDeclName().isEmpty()) + if (!ET->getOriginalDecl()->getDeclName().isEmpty()) return true; } @@ -105,7 +105,7 @@ static bool isValidPreserveEnumValueArg(Expr *Arg) { return false; // The enum value must be supported. - return llvm::is_contained(ET->getDecl()->enumerators(), Enumerator); + return llvm::is_contained(ET->getOriginalDecl()->enumerators(), Enumerator); } bool SemaBPF::CheckBPFBuiltinFunctionCall(unsigned BuiltinID, diff --git a/clang/lib/Sema/SemaCUDA.cpp b/clang/lib/Sema/SemaCUDA.cpp index 24cb8c369790b..fbf64d3d57050 100644 --- a/clang/lib/Sema/SemaCUDA.cpp +++ b/clang/lib/Sema/SemaCUDA.cpp @@ -426,7 +426,8 @@ bool SemaCUDA::inferTargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl, continue; } - CXXRecordDecl *BaseClassDecl = cast(BaseType->getDecl()); + CXXRecordDecl *BaseClassDecl = + cast(BaseType->getOriginalDecl())->getDefinitionOrSelf(); Sema::SpecialMemberOverloadResult SMOR = SemaRef.LookupSpecialMember(BaseClassDecl, CSM, /* ConstArg */ ConstRHS, @@ -471,7 +472,9 @@ bool SemaCUDA::inferTargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl, continue; } - CXXRecordDecl *FieldRecDecl = cast(FieldType->getDecl()); + CXXRecordDecl *FieldRecDecl = + cast(FieldType->getOriginalDecl()) + ->getDefinitionOrSelf(); Sema::SpecialMemberOverloadResult SMOR = SemaRef.LookupSpecialMember(FieldRecDecl, CSM, /* ConstArg */ ConstRHS && !F->isMutable(), diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index 8e055aacf5b27..a82129821b884 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -122,7 +122,7 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS, } } else if (const auto *RecordT = dyn_cast(NNSType)) { // The nested name specifier refers to a member of a class template. - return RecordT->getDecl(); + return RecordT->getOriginalDecl()->getDefinitionOrSelf(); } } diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 41277a25410ef..da43848a1a7d0 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -964,7 +964,7 @@ void CastOperation::CheckDynamicCast() { } // C++ 5.2.7p6: Otherwise, v shall be [polymorphic]. - const RecordDecl *SrcDecl = SrcRecord->getDecl()->getDefinition(); + const RecordDecl *SrcDecl = SrcRecord->getOriginalDecl()->getDefinition(); assert(SrcDecl && "Definition missing"); if (!cast(SrcDecl)->isPolymorphic()) { Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic) @@ -1455,7 +1455,7 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, // converted to an integral type. [...] A value of a scoped enumeration type // can also be explicitly converted to a floating-point type [...]. if (const EnumType *Enum = SrcType->getAs()) { - if (Enum->getDecl()->isScoped()) { + if (Enum->getOriginalDecl()->isScoped()) { if (DestType->isBooleanType()) { Kind = CK_IntegralToBoolean; return TC_Success; @@ -1487,8 +1487,8 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, // [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(); - Kind = Enum->getDecl()->isFixed() && - Enum->getDecl()->getIntegerType()->isBooleanType() + const EnumDecl *ED = Enum->getOriginalDecl()->getDefinitionOrSelf(); + Kind = ED->isFixed() && ED->getIntegerType()->isBooleanType() ? CK_IntegralToBoolean : CK_IntegralCast; return TC_Success; @@ -3097,27 +3097,26 @@ void CastOperation::CheckCStyleCast() { if (!DestType->isScalarType() && !DestType->isVectorType() && !DestType->isMatrixType()) { - const RecordType *DestRecordTy = DestType->getAs(); - - if (DestRecordTy && Self.Context.hasSameUnqualifiedType(DestType, SrcType)){ - // GCC struct/union extension: allow cast to self. - Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar) - << DestType << SrcExpr.get()->getSourceRange(); - Kind = CK_NoOp; - return; - } - - // GCC's cast to union extension. - if (DestRecordTy && DestRecordTy->getDecl()->isUnion()) { - RecordDecl *RD = DestRecordTy->getDecl(); - if (CastExpr::getTargetFieldForToUnionCast(RD, SrcType)) { - Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union) - << SrcExpr.get()->getSourceRange(); - Kind = CK_ToUnion; + if (const RecordType *DestRecordTy = DestType->getAs()) { + if (Self.Context.hasSameUnqualifiedType(DestType, SrcType)) { + // GCC struct/union extension: allow cast to self. + Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar) + << DestType << SrcExpr.get()->getSourceRange(); + Kind = CK_NoOp; return; - } else { + } + + // GCC's cast to union extension. + if (RecordDecl *RD = DestRecordTy->getOriginalDecl(); RD->isUnion()) { + if (CastExpr::getTargetFieldForToUnionCast(RD->getDefinitionOrSelf(), + SrcType)) { + Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union) + << SrcExpr.get()->getSourceRange(); + Kind = CK_ToUnion; + return; + } Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type) - << SrcType << SrcExpr.get()->getSourceRange(); + << SrcType << SrcExpr.get()->getSourceRange(); SrcExpr = ExprError(); return; } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 223e2bc8a4a57..47ebf83bf0f50 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3315,7 +3315,9 @@ static bool CheckNonNullExpr(Sema &S, const Expr *Expr) { // As a special case, transparent unions initialized with zero are // considered null for the purposes of the nonnull attribute. if (const RecordType *UT = Expr->getType()->getAsUnionType(); - UT && UT->getDecl()->hasAttr()) { + UT && UT->getOriginalDecl() + ->getMostRecentDecl() + ->hasAttr()) { if (const auto *CLE = dyn_cast(Expr)) if (const auto *ILE = dyn_cast(CLE->getInitializer())) Expr = ILE->getInit(0); @@ -5172,7 +5174,9 @@ bool Sema::BuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall) { return false; if (!Type->isEnumeralType()) return true; - const EnumDecl *ED = Type->castAs()->getDecl(); + const EnumDecl *ED = Type->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); return !(ED && Context.typesAreCompatible(ED->getPromotionType(), Type)); }()) { @@ -7788,8 +7792,11 @@ CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty) { if (!RT) return Results; - const CXXRecordDecl *RD = dyn_cast(RT->getDecl()); - if (!RD || !RD->getDefinition()) + CXXRecordDecl *RD = dyn_cast(RT->getOriginalDecl()); + if (!RD) + return Results; + RD = RD->getDefinition(); + if (!RD) return Results; LookupResult R(S, &S.Context.Idents.get(Name), SourceLocation(), @@ -8325,7 +8332,8 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, bool IsScopedEnum = false; QualType IntendedTy = ExprTy; if (auto EnumTy = ExprTy->getAs()) { - IntendedTy = EnumTy->getDecl()->getIntegerType(); + IntendedTy = + EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); if (EnumTy->isUnscopedEnumerationType()) { ExprTy = IntendedTy; // This controls whether we're talking about the underlying type or not, @@ -9621,7 +9629,10 @@ 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()->getDecl()->fields()) + for (const FieldDecl *FD : FT->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->fields()) visit(FD->getType(), FD->getLocation()); } void visitArray(QualType::PrimitiveDefaultInitializeKind PDIK, @@ -9666,7 +9677,10 @@ 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()->getDecl()->fields()) + for (const FieldDecl *FD : FT->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->fields()) visit(FD->getType(), FD->getLocation()); } void visitArray(QualType::PrimitiveCopyKind PCK, const ArrayType *AT, @@ -9947,8 +9961,9 @@ void Sema::CheckMemaccessArguments(const CallExpr *Call, getLangOpts().CPlusPlus && !RT->isIncompleteType() && !RT->desugar().isTriviallyCopyableType(Context); + const auto *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) && - RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) { + RD->isNonTrivialToPrimitiveDefaultInitialize()) { DiagRuntimeBehavior(Dest->getExprLoc(), Dest, PDiag(diag::warn_cstruct_memaccess) << ArgIdx << FnName << PointeeTy << 0); @@ -10467,10 +10482,14 @@ 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->getDecl()->getIntegerType().getDesugaredType(C).getTypePtr(); + T = ET->getOriginalDecl() + ->getDefinitionOrSelf() + ->getIntegerType() + .getDesugaredType(C) + .getTypePtr(); } else if (const auto *ET = dyn_cast(T)) { // For enum types in C++, use the known bit width of the enumerators. - EnumDecl *Enum = ET->getDecl(); + 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()) { @@ -10512,7 +10531,9 @@ struct IntRange { if (const AtomicType *AT = dyn_cast(T)) T = AT->getValueType().getTypePtr(); if (const EnumType *ET = dyn_cast(T)) - T = C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr(); + T = C.getCanonicalType( + ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType()) + .getTypePtr(); if (const auto *EIT = dyn_cast(T)) return IntRange(EIT->getNumBits(), EIT->isUnsigned()); @@ -11484,7 +11505,9 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, return false; if (BitfieldType->isEnumeralType()) { - EnumDecl *BitfieldEnumDecl = BitfieldType->castAs()->getDecl(); + EnumDecl *BitfieldEnumDecl = BitfieldType->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); // 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. @@ -11521,7 +11544,7 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, EnumTy = PTAttr->getType()->getAs(); } if (EnumTy) { - EnumDecl *ED = EnumTy->getDecl(); + EnumDecl *ED = EnumTy->getOriginalDecl()->getDefinitionOrSelf(); bool SignedBitfield = BitfieldType->isSignedIntegerOrEnumerationType(); // Enum types are implicitly signed on Windows, so check if there are any @@ -12587,8 +12610,8 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, if (const EnumType *SourceEnum = Source->getAs()) if (const EnumType *TargetEnum = Target->getAs()) - if (SourceEnum->getDecl()->hasNameForLinkage() && - TargetEnum->getDecl()->hasNameForLinkage() && + if (SourceEnum->getOriginalDecl()->hasNameForLinkage() && + TargetEnum->getOriginalDecl()->hasNameForLinkage() && SourceEnum != TargetEnum) { if (SourceMgr.isInSystemMacro(CC)) return; @@ -15228,16 +15251,16 @@ static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2) { return false; if (TC1 == Type::Enum) { - return isLayoutCompatible(C, - cast(T1)->getDecl(), - cast(T2)->getDecl()); + return isLayoutCompatible( + C, cast(T1)->getOriginalDecl()->getDefinitionOrSelf(), + cast(T2)->getOriginalDecl()->getDefinitionOrSelf()); } else if (TC1 == Type::Record) { if (!T1->isStandardLayoutType() || !T2->isStandardLayoutType()) return false; - return isLayoutCompatible(C, - cast(T1)->getDecl(), - cast(T2)->getDecl()); + return isLayoutCompatible( + C, cast(T1)->getOriginalDecl()->getDefinitionOrSelf(), + cast(T2)->getOriginalDecl()->getDefinitionOrSelf()); } return false; @@ -15591,7 +15614,9 @@ void Sema::RefersToMemberWithReducedAlignment( return; if (ME->isArrow()) BaseType = BaseType->getPointeeType(); - RecordDecl *RD = BaseType->castAs()->getDecl(); + RecordDecl *RD = BaseType->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); if (RD->isInvalidDecl()) return; diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 443cb146c0ff3..0c86a1f97046a 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2039,7 +2039,7 @@ static const char *GetCompletionTypeString(QualType T, ASTContext &Context, // Anonymous tag types are constant strings. if (const TagType *TagT = dyn_cast(T)) - if (TagDecl *Tag = TagT->getDecl()) + if (TagDecl *Tag = TagT->getOriginalDecl()) if (!Tag->hasNameForLinkage()) { switch (Tag->getTagKind()) { case TagTypeKind::Struct: @@ -5053,9 +5053,9 @@ void SemaCodeCompletion::CodeCompleteExpression( Data.PreferredType->isMemberPointerType() || Data.PreferredType->isBlockPointerType(); if (Data.PreferredType->isEnumeralType()) { - EnumDecl *Enum = Data.PreferredType->castAs()->getDecl(); - if (auto *Def = Enum->getDefinition()) - Enum = Def; + EnumDecl *Enum = Data.PreferredType->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); // FIXME: collect covered enumerators in cases like: // if (x == my_enum::one) { ... } else if (x == ^) {} AddEnumerators(Results, getASTContext(), Enum, SemaRef.CurContext, @@ -6180,9 +6180,8 @@ void SemaCodeCompletion::CodeCompleteCase(Scope *S) { // Code-complete the cases of a switch statement over an enumeration type // by providing the list of - EnumDecl *Enum = type->castAs()->getDecl(); - if (EnumDecl *Def = Enum->getDefinition()) - Enum = Def; + 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 diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index 6f09a7cbb6e64..cc03616e0dfe1 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -638,7 +638,9 @@ static void checkNoThrow(Sema &S, const Stmt *E, QualType::DestructionKind::DK_cxx_destructor) { const auto *T = cast(ReturnType.getCanonicalType().getTypePtr()); - checkDeclNoexcept(cast(T->getDecl())->getDestructor(), + checkDeclNoexcept(cast(T->getOriginalDecl()) + ->getDefinition() + ->getDestructor(), /*IsDtor=*/true); } } else diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ead542ed51a8a..3043f8f8d004c 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -5272,9 +5272,9 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, Record = dyn_cast(Tag); else if (const RecordType *RT = DS.getRepAsType().get()->getAsStructureType()) - Record = RT->getDecl(); + Record = RT->getOriginalDecl()->getDefinitionOrSelf(); else if (const RecordType *UT = DS.getRepAsType().get()->getAsUnionType()) - Record = UT->getDecl(); + Record = UT->getOriginalDecl()->getDefinitionOrSelf(); if (Record && getLangOpts().MicrosoftExt) { Diag(DS.getBeginLoc(), diag::ext_ms_anonymous_record) @@ -9788,7 +9788,8 @@ static void checkIsValidOpenCLKernelParameter( // At this point we already handled everything except of a RecordType. assert(PT->isRecordType() && "Unexpected type."); - const RecordDecl *PD = PT->castAs()->getDecl(); + const RecordDecl *PD = + PT->castAs()->getOriginalDecl()->getDefinitionOrSelf(); VisitStack.push_back(PD); assert(VisitStack.back() && "First decl null?"); @@ -9816,7 +9817,9 @@ static void checkIsValidOpenCLKernelParameter( "Unexpected type."); const Type *FieldRecTy = FieldTy->getPointeeOrArrayElementType(); - RD = FieldRecTy->castAs()->getDecl(); + RD = FieldRecTy->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); } else { RD = cast(Next); } @@ -13335,7 +13338,8 @@ struct DiagNonTrivalCUnionDefaultInitializeVisitor } void visitStruct(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) { - const RecordDecl *RD = QT->castAs()->getDecl(); + const RecordDecl *RD = + QT->castAs()->getOriginalDecl()->getDefinitionOrSelf(); if (RD->isUnion()) { if (OrigLoc.isValid()) { bool IsUnion = false; @@ -13401,7 +13405,8 @@ struct DiagNonTrivalCUnionDestructedTypeVisitor } void visitStruct(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) { - const RecordDecl *RD = QT->castAs()->getDecl(); + const RecordDecl *RD = + QT->castAs()->getOriginalDecl()->getDefinitionOrSelf(); if (RD->isUnion()) { if (OrigLoc.isValid()) { bool IsUnion = false; @@ -13466,7 +13471,8 @@ struct DiagNonTrivalCUnionCopyVisitor } void visitStruct(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) { - const RecordDecl *RD = QT->castAs()->getDecl(); + const RecordDecl *RD = + QT->castAs()->getOriginalDecl()->getDefinitionOrSelf(); if (RD->isUnion()) { if (OrigLoc.isValid()) { bool IsUnion = false; @@ -14439,7 +14445,9 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { if (getLangOpts().CPlusPlus && Var->hasLocalStorage()) { if (const RecordType *Record = Context.getBaseElementType(Type)->getAs()) { - CXXRecordDecl *CXXRecord = cast(Record->getDecl()); + CXXRecordDecl *CXXRecord = + cast(Record->getOriginalDecl()) + ->getDefinitionOrSelf(); // Mark the function (if we're in one) for further checking even if the // looser rules of C++11 do not require such checks, so that we can // diagnose incompatibilities with C++98. @@ -19061,7 +19069,7 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, if (!InvalidDecl && getLangOpts().CPlusPlus) { if (Record->isUnion()) { if (const RecordType *RT = EltTy->getAs()) { - CXXRecordDecl* RDecl = cast(RT->getDecl()); + CXXRecordDecl *RDecl = cast(RT->getOriginalDecl()); if (RDecl->getDefinition()) { // C++ [class.union]p1: An object of a class with a non-trivial // constructor, a non-trivial copy constructor, a non-trivial @@ -19127,7 +19135,8 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) { QualType EltTy = Context.getBaseElementType(FD->getType()); if (const RecordType *RT = EltTy->getAs()) { - CXXRecordDecl *RDecl = cast(RT->getDecl()); + CXXRecordDecl *RDecl = + cast(RT->getOriginalDecl())->getDefinitionOrSelf(); if (RDecl->getDefinition()) { // We check for copy constructors before constructors // because otherwise we'll never get complaints about @@ -19450,7 +19459,7 @@ bool Sema::EntirelyFunctionPointers(const RecordDecl *Record) { } // If a member is a struct entirely of function pointers, that counts too. if (const RecordType *RT = FieldType->getAs()) { - const RecordDecl *Record = RT->getDecl(); + const RecordDecl *Record = RT->getOriginalDecl()->getDefinitionOrSelf(); if (Record->isStruct() && EntirelyFunctionPointers(Record)) return true; } @@ -19608,7 +19617,9 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, EnclosingDecl->setInvalidDecl(); continue; } else if (const RecordType *FDTTy = FDTy->getAs()) { - if (Record && FDTTy->getDecl()->hasFlexibleArrayMember()) { + if (Record && FDTTy->getOriginalDecl() + ->getDefinitionOrSelf() + ->hasFlexibleArrayMember()) { // A type which contains a flexible array member is considered to be a // flexible array member. Record->setHasFlexibleArrayMember(true); @@ -19634,9 +19645,10 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, // Ivars can not have abstract class types FD->setInvalidDecl(); } - if (Record && FDTTy->getDecl()->hasObjectMember()) + const RecordDecl *RD = FDTTy->getOriginalDecl()->getDefinitionOrSelf(); + if (Record && RD->hasObjectMember()) Record->setHasObjectMember(true); - if (Record && FDTTy->getDecl()->hasVolatileMember()) + if (Record && RD->hasVolatileMember()) Record->setHasVolatileMember(true); } else if (FDTy->isObjCObjectType()) { /// A field cannot be an Objective-c object @@ -19667,8 +19679,10 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, Record->setHasObjectMember(true); else if (Context.getAsArrayType(FD->getType())) { QualType BaseType = Context.getBaseElementType(FD->getType()); - if (BaseType->isRecordType() && - BaseType->castAs()->getDecl()->hasObjectMember()) + if (BaseType->isRecordType() && BaseType->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->hasObjectMember()) Record->setHasObjectMember(true); else if (BaseType->isObjCObjectPointerType() || BaseType.isObjCGCStrong()) @@ -19701,7 +19715,9 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, } if (const auto *RT = FT->getAs()) { - if (RT->getDecl()->getArgPassingRestrictions() == + if (RT->getOriginalDecl() + ->getDefinitionOrSelf() + ->getArgPassingRestrictions() == RecordArgPassingKind::CanNeverPassInRegs) Record->setArgPassingRestrictions( RecordArgPassingKind::CanNeverPassInRegs); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index efc99868c80d9..e4f28357a4903 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -177,7 +177,7 @@ static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) { return !Result.empty(); }; - const RecordDecl *Record = RT->getDecl(); + const RecordDecl *Record = RT->getOriginalDecl()->getDefinitionOrSelf(); bool foundStarOperator = IsOverloadedOperatorPresent(Record, OO_Star); bool foundArrowOperator = IsOverloadedOperatorPresent(Record, OO_Arrow); if (foundStarOperator && foundArrowOperator) @@ -271,7 +271,8 @@ static bool checkRecordTypeForCapability(Sema &S, QualType Ty) { if (threadSafetyCheckIsSmartPointer(S, RT)) return true; - return checkRecordDeclForAttr(RT->getDecl()); + return checkRecordDeclForAttr( + RT->getOriginalDecl()->getDefinitionOrSelf()); } static bool checkRecordTypeForScopedCapability(Sema &S, QualType Ty) { @@ -284,7 +285,8 @@ static bool checkRecordTypeForScopedCapability(Sema &S, QualType Ty) { if (RT->isIncompleteType()) return true; - return checkRecordDeclForAttr(RT->getDecl()); + return checkRecordDeclForAttr( + RT->getOriginalDecl()->getDefinitionOrSelf()); } static bool checkTypedefTypeForCapability(QualType Ty) { @@ -1254,8 +1256,8 @@ bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) { // The nonnull attribute, and other similar attributes, can be applied to a // transparent union that contains a pointer type. if (const RecordType *UT = T->getAsUnionType()) { - if (UT && UT->getDecl()->hasAttr()) { - RecordDecl *UD = UT->getDecl(); + RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf(); + if (UD->hasAttr()) { for (const auto *I : UD->fields()) { QualType QT = I->getType(); if (QT->isAnyPointerType() || QT->isBlockPointerType()) @@ -4362,7 +4364,10 @@ static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) { RecordDecl *RD = nullptr; const auto *TD = dyn_cast(D); if (TD && TD->getUnderlyingType()->isUnionType()) - RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); + RD = TD->getUnderlyingType() + ->getAsUnionType() + ->getOriginalDecl() + ->getDefinitionOrSelf(); else RD = dyn_cast(D); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 7519fa91bd631..5ed59afd77e59 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2184,7 +2184,10 @@ static bool CheckConstexprCtorInitializer(Sema &SemaRef, return false; } } else if (Field->isAnonymousStructOrUnion()) { - const RecordDecl *RD = Field->getType()->castAs()->getDecl(); + const RecordDecl *RD = Field->getType() + ->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); for (auto *I : RD->fields()) // If an anonymous union contains an anonymous struct of which any member // is initialized, all members must be initialized. @@ -2981,7 +2984,8 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, NoteIndirectBases(Context, IndirectBaseTypes, NewBaseType); if (const RecordType *Record = NewBaseType->getAs()) { - const CXXRecordDecl *RD = cast(Record->getDecl()); + const CXXRecordDecl *RD = cast(Record->getOriginalDecl()) + ->getDefinitionOrSelf(); if (Class->isInterface() && (!RD->isInterfaceLike() || KnownBase->getAccessSpecifier() != AS_public)) { @@ -5622,9 +5626,9 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors, static void PopulateKeysForFields(FieldDecl *Field, SmallVectorImpl &IdealInits) { if (const RecordType *RT = Field->getType()->getAs()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl(); if (RD->isAnonymousStructOrUnion()) { - for (auto *Field : RD->fields()) + for (auto *Field : RD->getDefinitionOrSelf()->fields()) PopulateKeysForFields(Field, IdealInits); return; } @@ -7597,7 +7601,9 @@ static bool defaultedSpecialMemberIsConstexpr( const RecordType *BaseType = B.getType()->getAs(); if (!BaseType) continue; - CXXRecordDecl *BaseClassDecl = cast(BaseType->getDecl()); + CXXRecordDecl *BaseClassDecl = + cast(BaseType->getOriginalDecl()) + ->getDefinitionOrSelf(); if (!specialMemberIsConstexpr(S, BaseClassDecl, CSM, 0, ConstArg, InheritedCtor, Inherited)) return false; @@ -7620,7 +7626,9 @@ static bool defaultedSpecialMemberIsConstexpr( continue; QualType BaseType = S.Context.getBaseElementType(F->getType()); if (const RecordType *RecordTy = BaseType->getAs()) { - CXXRecordDecl *FieldRecDecl = cast(RecordTy->getDecl()); + CXXRecordDecl *FieldRecDecl = + cast(RecordTy->getOriginalDecl()) + ->getDefinitionOrSelf(); if (!specialMemberIsConstexpr(S, FieldRecDecl, CSM, BaseType.getCVRQualifiers(), ConstArg && !F->isMutable())) @@ -10457,8 +10465,10 @@ 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()->getDecl(); + RecordDecl *BaseRecord = Specifier->getType() + ->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); DeclarationName Name = Method->getDeclName(); assert(Name.getNameKind() == DeclarationName::Identifier); @@ -10616,7 +10626,8 @@ void Sema::checkIllFormedTrivialABIStruct(CXXRecordDecl &RD) { if (const auto *RT = FT->getBaseElementTypeUnsafe()->getAs()) if (!RT->isDependentType() && - !cast(RT->getDecl())->canPassInRegisters()) { + !cast(RT->getOriginalDecl()->getDefinitionOrSelf()) + ->canPassInRegisters()) { PrintDiagAndRemoveAttr(5); return; } @@ -13919,7 +13930,8 @@ bool SpecialMemberExceptionSpecInfo::visitBase(CXXBaseSpecifier *Base) { if (!RT) return false; - auto *BaseClass = cast(RT->getDecl()); + auto *BaseClass = + cast(RT->getOriginalDecl())->getDefinitionOrSelf(); Sema::SpecialMemberOverloadResult SMOR = lookupInheritedCtor(BaseClass); if (auto *BaseCtor = SMOR.getMethod()) { visitSubobjectCall(Base, BaseCtor); @@ -13945,8 +13957,9 @@ bool SpecialMemberExceptionSpecInfo::visitField(FieldDecl *FD) { ExceptSpec.CalledExpr(E); } else if (auto *RT = S.Context.getBaseElementType(FD->getType()) ->getAs()) { - visitClassSubobject(cast(RT->getDecl()), FD, - FD->getType().getCVRQualifiers()); + visitClassSubobject( + cast(RT->getOriginalDecl())->getDefinitionOrSelf(), FD, + FD->getType().getCVRQualifiers()); } return false; } @@ -14762,9 +14775,10 @@ buildMemcpyForAssignmentOp(Sema &S, SourceLocation Loc, QualType T, VK_PRValue, OK_Ordinary, Loc, false, S.CurFPFeatureOverrides()); const Type *E = T->getBaseElementTypeUnsafe(); - bool NeedsCollectableMemCpy = - E->isRecordType() && - E->castAs()->getDecl()->hasObjectMember(); + bool NeedsCollectableMemCpy = E->isRecordType() && E->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->hasObjectMember(); // Create a reference to the __builtin_objc_memmove_collectable function StringRef MemCpyName = NeedsCollectableMemCpy ? @@ -14841,7 +14855,8 @@ buildSingleCopyAssignRecursively(Sema &S, SourceLocation Loc, QualType T, // ignoring any possible virtual overriding functions in more derived // classes); if (const RecordType *RecordTy = T->getAs()) { - CXXRecordDecl *ClassDecl = cast(RecordTy->getDecl()); + CXXRecordDecl *ClassDecl = + cast(RecordTy->getOriginalDecl())->getDefinitionOrSelf(); // Look for operator=. DeclarationName Name @@ -16304,7 +16319,8 @@ void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) { if (VD->getInit() && VD->getInit()->containsErrors()) return; - CXXRecordDecl *ClassDecl = cast(Record->getDecl()); + CXXRecordDecl *ClassDecl = + cast(Record->getOriginalDecl())->getDefinitionOrSelf(); if (ClassDecl->isInvalidDecl()) return; if (ClassDecl->hasIrrelevantDestructor()) return; if (ClassDecl->isDependentContext()) return; @@ -19142,8 +19158,9 @@ void Sema::MarkVirtualMembersReferenced(SourceLocation Loc, return; for (const auto &I : RD->bases()) { - const auto *Base = - cast(I.getType()->castAs()->getDecl()); + const auto *Base = cast( + I.getType()->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); if (Base->getNumVBases() == 0) continue; MarkVirtualMembersReferenced(Loc, Base); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index d228f432f0e1b..88ed83eca243e 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -3232,8 +3232,10 @@ static bool tryMatchRecordTypes(ASTContext &Context, assert(lt && rt && lt != rt); if (!isa(lt) || !isa(rt)) return false; - RecordDecl *left = cast(lt)->getDecl(); - RecordDecl *right = cast(rt)->getDecl(); + RecordDecl *left = + cast(lt)->getOriginalDecl()->getDefinitionOrSelf(); + RecordDecl *right = + cast(rt)->getOriginalDecl()->getDefinitionOrSelf(); // Require union-hood to match. if (left->isUnion() != right->isUnion()) return false; @@ -3847,7 +3849,9 @@ static bool IsVariableSizedType(QualType T) { if (T->isIncompleteArrayType()) return true; const auto *RecordTy = T->getAs(); - return (RecordTy && RecordTy->getDecl()->hasFlexibleArrayMember()); + return (RecordTy && RecordTy->getOriginalDecl() + ->getDefinitionOrSelf() + ->hasFlexibleArrayMember()); } static void DiagnoseVariableSizedIvars(Sema &S, ObjCContainerDecl *OCD) { @@ -3893,7 +3897,9 @@ static void DiagnoseVariableSizedIvars(Sema &S, ObjCContainerDecl *OCD) { << TagTypeKind::Class; // Use "class" for Obj-C. IsInvalidIvar = true; } else if (const RecordType *RecordTy = IvarTy->getAs()) { - if (RecordTy->getDecl()->hasFlexibleArrayMember()) { + if (RecordTy->getOriginalDecl() + ->getDefinitionOrSelf() + ->hasFlexibleArrayMember()) { S.Diag(ivar->getLocation(), diag::err_objc_variable_sized_type_not_at_end) << ivar->getDeclName() << IvarTy; @@ -5538,7 +5544,8 @@ void SemaObjC::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { if (const RecordType *RecordTy = Context.getBaseElementType(Field->getType()) ->getAs()) { - CXXRecordDecl *RD = cast(RecordTy->getDecl()); + CXXRecordDecl *RD = cast(RecordTy->getOriginalDecl()) + ->getDefinitionOrSelf(); if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(RD)) { SemaRef.MarkFunctionReferenced(Field->getLocation(), Destructor); SemaRef.CheckDestructorAccess( diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index feaf1749c842f..3de6936eef9bb 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1528,8 +1528,8 @@ void Sema::checkEnumArithmeticConversions(Expr *LHS, Expr *RHS, // are ill-formed. if (getLangOpts().CPlusPlus26) DiagID = diag::warn_conv_mixed_enum_types_cxx26; - else if (!L->castAs()->getDecl()->hasNameForLinkage() || - !R->castAs()->getDecl()->hasNameForLinkage()) { + else if (!L->castAs()->getOriginalDecl()->hasNameForLinkage() || + !R->castAs()->getOriginalDecl()->hasNameForLinkage()) { // If either enumeration type is unnamed, it's less likely that the // user cares about this, but this situation is still deprecated in // C++2a. Use a different warning group. @@ -7082,7 +7082,7 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, for (unsigned i = 0, e = Args.size(); i != e; i++) { if (const auto *RT = dyn_cast(Args[i]->getType().getCanonicalType())) { - if (RT->getDecl()->isOrContainsUnion()) + if (RT->getOriginalDecl()->isOrContainsUnion()) Diag(Args[i]->getBeginLoc(), diag::warn_cmse_nonsecure_union) << 0 << i; } @@ -8611,7 +8611,8 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, // type. if (const RecordType *LHSRT = LHSTy->getAs()) { // C99 6.5.15p3 if (const RecordType *RHSRT = RHSTy->getAs()) - if (LHSRT->getDecl() == RHSRT->getDecl()) + if (declaresSameEntity(LHSRT->getOriginalDecl(), + RHSRT->getOriginalDecl())) // "If both the operands have structure or union type, the result has // that type." This implies that CV qualifiers are dropped. return Context.getCommonSugaredType(LHSTy.getUnqualifiedType(), @@ -9680,11 +9681,14 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, // If the ArgType is a Union type, we want to handle a potential // transparent_union GCC extension. const RecordType *UT = ArgType->getAsUnionType(); - if (!UT || !UT->getDecl()->hasAttr()) + if (!UT) + return AssignConvertType::Incompatible; + + RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf(); + if (!UD->hasAttr()) return AssignConvertType::Incompatible; // The field to initialize within the transparent union. - RecordDecl *UD = UT->getDecl(); FieldDecl *InitField = nullptr; // It's compatible if the expression matches any of the fields. for (auto *it : UD->fields()) { @@ -11407,7 +11411,7 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, static bool isScopedEnumerationType(QualType T) { if (const EnumType *ET = T->getAs()) - return ET->getDecl()->isScoped(); + return ET->getOriginalDecl()->isScoped(); return false; } @@ -12296,8 +12300,10 @@ static QualType checkArithmeticOrEnumeralThreeWayCompare(Sema &S, S.InvalidOperands(Loc, LHS, RHS); return QualType(); } - QualType IntType = - LHSStrippedType->castAs()->getDecl()->getIntegerType(); + QualType IntType = LHSStrippedType->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->getIntegerType(); assert(IntType->isArithmeticType()); // We can't use `CK_IntegralCast` when the underlying type is 'bool', so we @@ -13700,8 +13706,10 @@ static void DiagnoseRecursiveConstFields(Sema &S, const ValueDecl *VD, // diagnostics in field nesting order. while (RecordTypeList.size() > NextToCheckIndex) { bool IsNested = NextToCheckIndex > 0; - for (const FieldDecl *Field : - RecordTypeList[NextToCheckIndex]->getDecl()->fields()) { + for (const FieldDecl *Field : RecordTypeList[NextToCheckIndex] + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->fields()) { // First, check every field for constness. QualType FieldTy = Field->getType(); if (FieldTy.isConstQualified()) { @@ -16156,7 +16164,7 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, if (!RC) return ExprError(Diag(OC.LocEnd, diag::err_offsetof_record_type) << CurrentType); - RecordDecl *RD = RC->getDecl(); + RecordDecl *RD = RC->getOriginalDecl()->getDefinitionOrSelf(); // C++ [lib.support.types]p5: // The macro offsetof accepts a restricted set of type arguments in this @@ -16783,7 +16791,8 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, // that. QualType UnderlyingType = TInfo->getType(); if (const auto *ET = UnderlyingType->getAs()) - UnderlyingType = ET->getDecl()->getIntegerType(); + UnderlyingType = + ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); if (Context.typesAreCompatible(PromoteType, UnderlyingType, /*CompareUnqualified*/ true)) PromoteType = QualType(); @@ -18778,7 +18787,9 @@ static bool isVariableCapturable(CapturingScopeInfo *CSI, ValueDecl *Var, // Prohibit structs with flexible array members too. // We cannot capture what is in the tail end of the struct. if (const RecordType *VTTy = Var->getType()->getAs()) { - if (VTTy->getDecl()->hasFlexibleArrayMember()) { + if (VTTy->getOriginalDecl() + ->getDefinitionOrSelf() + ->hasFlexibleArrayMember()) { if (Diagnose) { if (IsBlock) S.Diag(Loc, diag::err_ref_flexarray_type); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index da17134bf39a6..de064834314fa 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -566,7 +566,8 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, QualType T = E->getType(); if (const RecordType *RecordT = T->getAs()) { - CXXRecordDecl *RecordD = cast(RecordT->getDecl()); + CXXRecordDecl *RecordD = cast(RecordT->getOriginalDecl()) + ->getDefinitionOrSelf(); // C++ [expr.typeid]p3: // [...] If the type of the expression is a class type, the class // shall be completely-defined. @@ -1978,7 +1979,7 @@ static bool doesUsualArrayDeleteWantSize(Sema &S, SourceLocation loc, DeclarationName deleteName = S.Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete); LookupResult ops(S, deleteName, loc, Sema::LookupOrdinaryName); - S.LookupQualifiedName(ops, record->getDecl()); + S.LookupQualifiedName(ops, record->getOriginalDecl()->getDefinitionOrSelf()); // We're just doing this for information. ops.suppressDiagnostics(); @@ -3049,8 +3050,9 @@ bool Sema::FindAllocationFunctions( LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName); if (AllocElemType->isRecordType() && DeleteScope != AllocationFunctionScope::Global) { - auto *RD = - cast(AllocElemType->castAs()->getDecl()); + auto *RD = cast( + AllocElemType->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); LookupQualifiedName(FoundDelete, RD); } if (FoundDelete.isAmbiguous()) @@ -4051,7 +4053,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, : diag::warn_delete_incomplete, Ex.get())) { if (const RecordType *RT = PointeeElem->getAs()) - PointeeRD = cast(RT->getDecl()); + PointeeRD = + cast(RT->getOriginalDecl())->getDefinitionOrSelf(); } } @@ -4819,7 +4822,10 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, if (FromType->isVectorType() || ToType->isVectorType()) StepTy = adjustVectorType(Context, FromType, ToType, &ElTy); if (ElTy->isBooleanType()) { - assert(FromType->castAs()->getDecl()->isFixed() && + assert(FromType->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->isFixed() && SCS.Second == ICK_Integral_Promotion && "only enums with fixed underlying type can promote to bool"); From = ImpCastExprToType(From, StepTy, CK_IntegralToBoolean, VK_PRValue, @@ -6639,7 +6645,8 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { // That should be enough to guarantee that this type is complete, if we're // not processing a decltype expression. - CXXRecordDecl *RD = cast(RT->getDecl()); + CXXRecordDecl *RD = + cast(RT->getOriginalDecl())->getDefinitionOrSelf(); if (RD->isInvalidDecl() || RD->isDependentContext()) return E; @@ -7502,7 +7509,7 @@ ExprResult Sema::IgnoredValueConversions(Expr *E) { // GCC seems to also exclude expressions of incomplete enum type. if (const EnumType *T = E->getType()->getAs()) { - if (!T->getDecl()->isComplete()) { + if (!T->getOriginalDecl()->getDefinitionOrSelf()->isComplete()) { // FIXME: stupid workaround for a codegen bug! E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).get(); return E; diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index b8d548d3416d8..03b5c79cf70e3 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -639,14 +639,14 @@ ExprResult SemaObjC::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { BoxingMethod = getNSNumberFactoryMethod(*this, Loc, ValueType); BoxedType = NSNumberPointer; } else if (const EnumType *ET = ValueType->getAs()) { - if (!ET->getDecl()->isComplete()) { + const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + if (!ED->isComplete()) { Diag(Loc, diag::err_objc_incomplete_boxed_expression_type) << ValueType << ValueExpr->getSourceRange(); return ExprError(); } - BoxingMethod = getNSNumberFactoryMethod(*this, Loc, - ET->getDecl()->getIntegerType()); + BoxingMethod = getNSNumberFactoryMethod(*this, Loc, ED->getIntegerType()); BoxedType = NSNumberPointer; } else if (ValueType->isObjCBoxableRecordType()) { // Support for structure types, that marked as objc_boxable @@ -3847,7 +3847,8 @@ static inline T *getObjCBridgeAttr(const TypedefType *TD) { if (QT->isPointerType()) { QT = QT->getPointeeType(); if (const RecordType *RT = QT->getAs()) { - for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) { + for (auto *Redecl : + RT->getOriginalDecl()->getMostRecentDecl()->redecls()) { if (auto *attr = Redecl->getAttr()) return attr; } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index f8012c450973d..59f9c675c726d 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -233,7 +233,7 @@ static unsigned calculateLegacyCbufferSize(const ASTContext &Context, constexpr unsigned CBufferAlign = 16; if (const RecordType *RT = T->getAs()) { unsigned Size = 0; - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); for (const FieldDecl *Field : RD->fields()) { QualType Ty = Field->getType(); unsigned FieldSize = calculateLegacyCbufferSize(Context, Ty); @@ -1808,7 +1808,7 @@ SemaHLSL::TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT) { // requirements and adds them to Bindings void SemaHLSL::collectResourceBindingsOnUserRecordDecl(const VarDecl *VD, const RecordType *RT) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); for (FieldDecl *FD : RD->fields()) { const Type *Ty = FD->getType()->getUnqualifiedDesugaredType(); @@ -3361,7 +3361,7 @@ bool SemaHLSL::ContainsBitField(QualType BaseTy) { continue; } if (const auto *RT = dyn_cast(T)) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (RD->isUnion()) continue; @@ -3877,7 +3877,8 @@ class InitListTransformer { } while (!RecordTypes.empty()) { const RecordType *RT = RecordTypes.pop_back_val(); - for (auto *FD : RT->getDecl()->fields()) { + for (auto *FD : + RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) { DeclAccessPair Found = DeclAccessPair::make(FD, FD->getAccess()); DeclarationNameInfo NameInfo(FD->getDeclName(), E->getBeginLoc()); ExprResult Res = S.BuildFieldReferenceExpr( @@ -3925,7 +3926,8 @@ class InitListTransformer { } while (!RecordTypes.empty()) { const RecordType *RT = RecordTypes.pop_back_val(); - for (auto *FD : RT->getDecl()->fields()) { + for (auto *FD : + RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) { Inits.push_back(generateInitListsImpl(FD->getType())); } } diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index c262b8f72021c..98f0679d86337 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -775,7 +775,7 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field, if (Init >= NumInits || !ILE->getInit(Init)) { if (const RecordType *RType = ILE->getType()->getAs()) - if (!RType->getDecl()->isUnion()) + if (!RType->getOriginalDecl()->isUnion()) assert((Init < NumInits || VerifyOnly) && "This ILE should have been expanded"); @@ -922,7 +922,7 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity, return; if (const RecordType *RType = ILE->getType()->getAs()) { - const RecordDecl *RDecl = RType->getDecl(); + const RecordDecl *RDecl = RType->getOriginalDecl()->getDefinitionOrSelf(); if (RDecl->isUnion() && ILE->getInitializedFieldInUnion()) { FillInEmptyInitForField(0, ILE->getInitializedFieldInUnion(), Entity, ILE, RequiresSecondPass, FillWithNoInit); @@ -1126,7 +1126,8 @@ int InitListChecker::numArrayElements(QualType DeclType) { } int InitListChecker::numStructUnionElements(QualType DeclType) { - RecordDecl *structDecl = DeclType->castAs()->getDecl(); + RecordDecl *structDecl = + DeclType->castAs()->getOriginalDecl()->getDefinitionOrSelf(); int InitializableMembers = 0; if (auto *CXXRD = dyn_cast(structDecl)) InitializableMembers += CXXRD->getNumBases(); @@ -1155,16 +1156,22 @@ 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()->getDecl(); + auto *ParentRD = Entity.getParent() + ->getType() + ->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); 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()->getDecl(); + auto *ParentRD = Entity.getParent() + ->getType() + ->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf(); if (CXXRecordDecl *CXXRD = dyn_cast(ParentRD)) { if (CXXRD->getNumBases()) { return false; @@ -4528,8 +4535,8 @@ static void TryConstructorInitialization(Sema &S, const RecordType *DestRecordType = DestType->getAs(); assert(DestRecordType && "Constructor initialization requires record type"); - CXXRecordDecl *DestRecordDecl - = cast(DestRecordType->getDecl()); + auto *DestRecordDecl = cast(DestRecordType->getOriginalDecl()) + ->getDefinitionOrSelf(); // Build the candidate set directly in the initialization sequence // structure, so that it will persist if we fail. @@ -5050,8 +5057,8 @@ static void TryListInitialization(Sema &S, // 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->getDecl()->isFixed() && + Kind.getKind() == InitializationKind::IK_DirectList && ET && + ET->getOriginalDecl()->getDefinitionOrSelf()->isFixed() && !S.Context.hasSameUnqualifiedType(E->getType(), DestType) && (E->getType()->isIntegralOrUnscopedEnumerationType() || E->getType()->isFloatingType())) { @@ -5161,7 +5168,8 @@ static OverloadingResult TryRefInitWithConversionFunction( S.isCompleteType(Kind.getLocation(), T1)) { // The type we're converting to is a class type. Enumerate its constructors // to see if there is a suitable conversion. - CXXRecordDecl *T1RecordDecl = cast(T1RecordType->getDecl()); + auto *T1RecordDecl = cast(T1RecordType->getOriginalDecl()) + ->getDefinitionOrSelf(); for (NamedDecl *D : S.LookupConstructors(T1RecordDecl)) { auto Info = getConstructorInfo(D); @@ -5184,7 +5192,8 @@ static OverloadingResult TryRefInitWithConversionFunction( } } } - if (T1RecordType && T1RecordType->getDecl()->isInvalidDecl()) + if (T1RecordType && + T1RecordType->getOriginalDecl()->getDefinitionOrSelf()->isInvalidDecl()) return OR_No_Viable_Function; const RecordType *T2RecordType = nullptr; @@ -5192,7 +5201,8 @@ static OverloadingResult TryRefInitWithConversionFunction( S.isCompleteType(Kind.getLocation(), T2)) { // The type we're converting from is a class type, enumerate its conversion // functions. - CXXRecordDecl *T2RecordDecl = cast(T2RecordType->getDecl()); + auto *T2RecordDecl = cast(T2RecordType->getOriginalDecl()) + ->getDefinitionOrSelf(); const auto &Conversions = T2RecordDecl->getVisibleConversionFunctions(); for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { @@ -5228,7 +5238,8 @@ static OverloadingResult TryRefInitWithConversionFunction( } } } - if (T2RecordType && T2RecordType->getDecl()->isInvalidDecl()) + if (T2RecordType && + T2RecordType->getOriginalDecl()->getDefinitionOrSelf()->isInvalidDecl()) return OR_No_Viable_Function; SourceLocation DeclLoc = Initializer->getBeginLoc(); @@ -5706,7 +5717,9 @@ static void TryValueInitialization(Sema &S, T = S.Context.getBaseElementType(T); if (const RecordType *RT = T->getAs()) { - if (CXXRecordDecl *ClassDecl = dyn_cast(RT->getDecl())) { + if (CXXRecordDecl *ClassDecl = + dyn_cast(RT->getOriginalDecl())) { + ClassDecl = ClassDecl->getDefinitionOrSelf(); bool NeedZeroInitialization = true; // C++98: // -- if T is a class type (clause 9) with a user-declared constructor @@ -5904,7 +5917,8 @@ static void TryOrBuildParenListInitialization( } } else if (auto *RT = Entity.getType()->getAs()) { bool IsUnion = RT->isUnionType(); - const CXXRecordDecl *RD = cast(RT->getDecl()); + const auto *RD = + cast(RT->getOriginalDecl())->getDefinitionOrSelf(); if (RD->isInvalidDecl()) { // Exit early to avoid confusion when processing members. // We do the same for braced list initialization in @@ -6093,8 +6107,9 @@ static void TryUserDefinedConversion(Sema &S, if (const RecordType *DestRecordType = DestType->getAs()) { // The type we're converting to is a class type. Enumerate its constructors // to see if there is a suitable conversion. - CXXRecordDecl *DestRecordDecl - = cast(DestRecordType->getDecl()); + auto *DestRecordDecl = + cast(DestRecordType->getOriginalDecl()) + ->getDefinitionOrSelf(); // Try to complete the type we're converting to. if (S.isCompleteType(Kind.getLocation(), DestType)) { @@ -6130,8 +6145,9 @@ static void TryUserDefinedConversion(Sema &S, // 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)) { - CXXRecordDecl *SourceRecordDecl - = cast(SourceRecordType->getDecl()); + auto *SourceRecordDecl = + cast(SourceRecordType->getOriginalDecl()) + ->getDefinitionOrSelf(); const auto &Conversions = SourceRecordDecl->getVisibleConversionFunctions(); @@ -7164,7 +7180,8 @@ static ExprResult CopyObject(Sema &S, Expr *CurInitExpr = (Expr *)CurInit.get(); CXXRecordDecl *Class = nullptr; if (const RecordType *Record = T->getAs()) - Class = cast(Record->getDecl()); + Class = + cast(Record->getOriginalDecl())->getDefinitionOrSelf(); if (!Class) return CurInit; @@ -7319,8 +7336,8 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S, // Find constructors which would have been considered. OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); - DeclContext::lookup_result Ctors = - S.LookupConstructors(cast(Record->getDecl())); + DeclContext::lookup_result Ctors = S.LookupConstructors( + cast(Record->getOriginalDecl())->getDefinitionOrSelf()); // Perform overload resolution. OverloadCandidateSet::iterator Best; @@ -8151,8 +8168,9 @@ ExprResult InitializationSequence::Perform(Sema &S, // regardless of how we initialized the entity. QualType T = CurInit.get()->getType(); if (const RecordType *Record = T->getAs()) { - CXXDestructorDecl *Destructor - = S.LookupDestructor(cast(Record->getDecl())); + CXXDestructorDecl *Destructor = + S.LookupDestructor(cast(Record->getOriginalDecl()) + ->getDefinitionOrSelf()); S.CheckDestructorAccess(CurInit.get()->getBeginLoc(), Destructor, S.PDiag(diag::err_access_dtor_temp) << T); S.MarkFunctionReferenced(CurInit.get()->getBeginLoc(), Destructor); @@ -9224,7 +9242,8 @@ bool InitializationSequence::Diagnose(Sema &S, if (const RecordType *Record = Entity.getType()->getAs()) - S.Diag(Record->getDecl()->getLocation(), diag::note_previous_decl) + S.Diag(Record->getOriginalDecl()->getLocation(), + diag::note_previous_decl) << S.Context.getCanonicalTagType(Record->getOriginalDecl()); } break; diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 56bebb213e3e9..0d891fc08c207 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -642,7 +642,7 @@ static EnumDecl *findEnumForBlockReturn(Expr *E) { // - it is an expression of that formal enum type. if (const EnumType *ET = E->getType()->getAs()) { - return ET->getDecl(); + return ET->getOriginalDecl()->getDefinitionOrSelf(); } // Otherwise, nope. diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index b00f61d9c00f6..89f5ccadbc416 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -3125,7 +3125,8 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, // the classes and namespaces of known non-dependent arguments. if (!BaseType) continue; - CXXRecordDecl *BaseDecl = cast(BaseType->getDecl()); + CXXRecordDecl *BaseDecl = cast(BaseType->getOriginalDecl()) + ->getDefinitionOrSelf(); if (Result.addClassTransitive(BaseDecl)) { // Find the associated namespace for this base class. DeclContext *BaseCtx = BaseDecl->getDeclContext(); @@ -3196,8 +3197,10 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) { // Its associated namespaces are the innermost enclosing // namespaces of its associated classes. case Type::Record: { + // FIXME: This should use the original decl. CXXRecordDecl *Class = - cast(cast(T)->getDecl()); + cast(cast(T)->getOriginalDecl()) + ->getDefinitionOrSelf(); addAssociatedClassesAndNamespaces(Result, Class); break; } @@ -3207,7 +3210,9 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) { // If it is a class member, its associated class is the // member’s class; else it has no associated class. case Type::Enum: { - EnumDecl *Enum = cast(T)->getDecl(); + // FIXME: This should use the original decl. + EnumDecl *Enum = + cast(T)->getOriginalDecl()->getDefinitionOrSelf(); DeclContext *Ctx = Enum->getDeclContext(); if (CXXRecordDecl *EnclosingClass = dyn_cast(Ctx)) @@ -4262,7 +4267,7 @@ class LookupVisibleHelper { const auto *Record = BaseType->getAs(); if (!Record) continue; - RD = Record->getDecl(); + RD = Record->getOriginalDecl()->getDefinitionOrSelf(); } // FIXME: It would be nice to be able to determine whether referencing diff --git a/clang/lib/Sema/SemaObjC.cpp b/clang/lib/Sema/SemaObjC.cpp index 0f39a9817ce7f..27951c9105411 100644 --- a/clang/lib/Sema/SemaObjC.cpp +++ b/clang/lib/Sema/SemaObjC.cpp @@ -1407,7 +1407,8 @@ SemaObjC::ObjCSubscriptKind SemaObjC::CheckSubscriptingKind(Expr *FromE) { int NoIntegrals = 0, NoObjCIdPointers = 0; SmallVector ConversionDecls; - for (NamedDecl *D : cast(RecordTy->getDecl()) + for (NamedDecl *D : cast(RecordTy->getOriginalDecl()) + ->getDefinitionOrSelf() ->getVisibleConversionFunctions()) { if (CXXConversionDecl *Conversion = dyn_cast(D->getUnderlyingDecl())) { @@ -1510,7 +1511,7 @@ bool SemaObjC::isCFStringType(QualType T) { if (!RT) return false; - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl(); if (RD->getTagKind() != TagTypeKind::Struct) return false; diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index 9dbb1d28aa722..bf6c364e40cc4 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -1321,7 +1321,9 @@ Decl *SemaObjC::ActOnPropertyImplDecl( } if (!CompleteTypeErr) { const RecordType *RecordTy = PropertyIvarType->getAs(); - if (RecordTy && RecordTy->getDecl()->hasFlexibleArrayMember()) { + if (RecordTy && RecordTy->getOriginalDecl() + ->getDefinitionOrSelf() + ->hasFlexibleArrayMember()) { Diag(PropertyIvarLoc, diag::err_synthesize_variable_sized_ivar) << PropertyIvarType; CompleteTypeErr = true; // suppress later diagnostics about the ivar diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 738692755a0ab..ac108221683ea 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -18614,10 +18614,11 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, if (const auto *TyRec = Ty->getAs()) { // Complete the type if it can be completed. // If the type is neither complete nor being defined, bail out now. - if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || - TyRec->getDecl()->getDefinition()) { + bool IsComplete = SemaRef.isCompleteType(Loc, Ty); + RecordDecl *RD = TyRec->getOriginalDecl()->getDefinition(); + if (IsComplete || RD) { Lookup.clear(); - SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); + SemaRef.LookupQualifiedName(Lookup, RD); if (Lookup.empty()) { Lookups.emplace_back(); Lookups.back().append(Lookup.begin(), Lookup.end()); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 7ce6c52fc4f7a..1f87f4db5cb53 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -370,7 +370,7 @@ NarrowingKind StandardConversionSequence::getNarrowingKind( // the underlying type is narrowing. This only arises for expressions of // the form 'Enum{init}'. if (auto *ET = ToType->getAs()) - ToType = ET->getDecl()->getIntegerType(); + ToType = ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); switch (Second) { // 'bool' is an integral type; dispatch to the right place to handle it. @@ -1063,7 +1063,8 @@ static bool shouldAddReversedEqEq(Sema &S, SourceLocation OpLoc, return true; LookupResult Members(S, NotEqOp, OpLoc, Sema::LookupNameKind::LookupMemberName); - S.LookupQualifiedName(Members, RHSRec->getDecl()); + S.LookupQualifiedName(Members, + RHSRec->getOriginalDecl()->getDefinitionOrSelf()); Members.suppressAccessDiagnostics(); for (NamedDecl *Op : Members) if (FunctionsCorrespond(S.Context, EqFD, Op->getAsFunction())) @@ -2601,10 +2602,12 @@ IsTransparentUnionStandardConversion(Sema &S, Expr* From, bool CStyle) { const RecordType *UT = ToType->getAsUnionType(); - if (!UT || !UT->getDecl()->hasAttr()) + if (!UT) return false; // The field to initialize within the transparent union. - RecordDecl *UD = UT->getDecl(); + const RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf(); + if (!UD->hasAttr()) + return false; // It's compatible if the expression matches any of the fields. for (const auto *it : UD->fields()) { if (IsStandardConversion(S, From, it->getType(), InOverloadResolution, SCS, @@ -2662,15 +2665,17 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) { if (const EnumType *FromEnumType = FromType->getAs()) { // C++0x 7.2p9: Note that this implicit enum to int conversion is not // provided for a scoped enumeration. - if (FromEnumType->getDecl()->isScoped()) + const EnumDecl *FromED = + FromEnumType->getOriginalDecl()->getDefinitionOrSelf(); + if (FromED->isScoped()) return false; // We can perform an integral promotion to the underlying type of the enum, // even if that's not the promoted type. Note that the check for promoting // the underlying type is based on the type alone, and does not consider // the bitfield-ness of the actual source expression. - if (FromEnumType->getDecl()->isFixed()) { - QualType Underlying = FromEnumType->getDecl()->getIntegerType(); + if (FromED->isFixed()) { + QualType Underlying = FromED->getIntegerType(); return Context.hasSameUnqualifiedType(Underlying, ToType) || IsIntegralPromotion(nullptr, Underlying, ToType); } @@ -3980,8 +3985,9 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, if (!S.isCompleteType(From->getExprLoc(), ToType)) { // We're not going to find any constructors. - } else if (CXXRecordDecl *ToRecordDecl - = dyn_cast(ToRecordType->getDecl())) { + } else if (auto *ToRecordDecl = + dyn_cast(ToRecordType->getOriginalDecl())) { + ToRecordDecl = ToRecordDecl->getDefinitionOrSelf(); Expr **Args = &From; unsigned NumArgs = 1; @@ -4054,8 +4060,9 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, // No conversion functions from incomplete types. } else if (const RecordType *FromRecordType = From->getType()->getAs()) { - if (CXXRecordDecl *FromRecordDecl - = dyn_cast(FromRecordType->getDecl())) { + if (auto *FromRecordDecl = + dyn_cast(FromRecordType->getOriginalDecl())) { + FromRecordDecl = FromRecordDecl->getDefinitionOrSelf(); // Add all of the conversion functions as candidates. const auto &Conversions = FromRecordDecl->getVisibleConversionFunctions(); for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { @@ -4506,7 +4513,8 @@ getFixedEnumPromtion(Sema &S, const StandardConversionSequence &SCS) { if (!FromType->isEnumeralType()) return FixedEnumPromotion::None; - EnumDecl *Enum = FromType->castAs()->getDecl(); + EnumDecl *Enum = + FromType->castAs()->getOriginalDecl()->getDefinitionOrSelf(); if (!Enum->isFixed()) return FixedEnumPromotion::None; @@ -5142,7 +5150,9 @@ 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()->getDecl()); + auto *T2RecordDecl = + cast(T2->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); OverloadCandidateSet CandidateSet( DeclLoc, OverloadCandidateSet::CSK_InitByUserDefinedConversion); @@ -6837,8 +6847,9 @@ ExprResult Sema::PerformContextualImplicitConversion( UnresolvedSet<4> ViableConversions; // These are *potentially* viable in C++1y. UnresolvedSet<4> ExplicitConversions; - const auto &Conversions = - cast(RecordTy->getDecl())->getVisibleConversionFunctions(); + const auto &Conversions = cast(RecordTy->getOriginalDecl()) + ->getDefinitionOrSelf() + ->getVisibleConversionFunctions(); bool HadMultipleCandidates = (std::distance(Conversions.begin(), Conversions.end()) > 1); @@ -8329,7 +8340,8 @@ void Sema::AddConversionCandidate( if (const auto *FromPtrType = ObjectType->getAs()) ObjectType = FromPtrType->getPointeeType(); const auto *ConversionContext = - cast(ObjectType->castAs()->getDecl()); + cast(ObjectType->castAs()->getOriginalDecl()) + ->getDefinitionOrSelf(); // C++23 [over.best.ics.general] // However, if the target is [...] @@ -8729,15 +8741,16 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, // the set of member candidates is empty. if (const RecordType *T1Rec = T1->getAs()) { + bool IsComplete = isCompleteType(OpLoc, T1); + CXXRecordDecl *T1RD = + cast(T1Rec->getOriginalDecl())->getDefinition(); // Complete the type if it can be completed. - if (!isCompleteType(OpLoc, T1) && !T1Rec->isBeingDefined()) - return; // If the type is neither complete nor being defined, bail out now. - if (!T1Rec->getDecl()->getDefinition()) + if (!T1RD || (!IsComplete && !T1RD->isBeingDefined())) return; LookupResult Operators(*this, OpName, OpLoc, LookupOrdinaryName); - LookupQualifiedName(Operators, T1Rec->getDecl()); + LookupQualifiedName(Operators, T1RD); Operators.suppressAccessDiagnostics(); for (LookupResult::iterator Oper = Operators.begin(), @@ -9080,7 +9093,8 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty, if (!SemaRef.isCompleteType(Loc, Ty)) return; - CXXRecordDecl *ClassDecl = cast(TyRec->getDecl()); + auto *ClassDecl = + cast(TyRec->getOriginalDecl())->getDefinitionOrSelf(); for (NamedDecl *D : ClassDecl->getVisibleConversionFunctions()) { if (isa(D)) D = cast(D)->getTargetDecl(); @@ -10192,7 +10206,7 @@ class BuiltinOperatorOverloadBuilder { if (S.getLangOpts().CPlusPlus11) { for (QualType EnumTy : CandidateTypes[ArgIdx].enumeration_types()) { - if (!EnumTy->castAs()->getDecl()->isScoped()) + if (!EnumTy->castAs()->getOriginalDecl()->isScoped()) continue; if (!AddedTypes.insert(S.Context.getCanonicalType(EnumTy)).second) @@ -16339,7 +16353,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, const auto *Record = Object.get()->getType()->castAs(); LookupResult R(*this, OpName, LParenLoc, LookupOrdinaryName); - LookupQualifiedName(R, Record->getDecl()); + LookupQualifiedName(R, Record->getOriginalDecl()->getDefinitionOrSelf()); R.suppressAccessDiagnostics(); for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); @@ -16383,8 +16397,9 @@ 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->getDecl())->getVisibleConversionFunctions(); + const auto &Conversions = cast(Record->getOriginalDecl()) + ->getDefinitionOrSelf() + ->getVisibleConversionFunctions(); for (auto I = Conversions.begin(), E = Conversions.end(); !IgnoreSurrogateFunctions && I != E; ++I) { NamedDecl *D = *I; @@ -16605,7 +16620,10 @@ ExprResult Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, return ExprError(); LookupResult R(*this, OpName, OpLoc, LookupOrdinaryName); - LookupQualifiedName(R, Base->getType()->castAs()->getDecl()); + LookupQualifiedName(R, Base->getType() + ->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf()); 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 d5c83aedb3008..7c82e540a9194 100644 --- a/clang/lib/Sema/SemaPPC.cpp +++ b/clang/lib/Sema/SemaPPC.cpp @@ -41,8 +41,10 @@ void SemaPPC::checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg) { return; QualType ArgType = Arg->getType(); - for (const FieldDecl *FD : - ArgType->castAs()->getDecl()->fields()) { + for (const FieldDecl *FD : ArgType->castAs() + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->fields()) { if (const auto *AA = FD->getAttr()) { CharUnits Alignment = getASTContext().toCharUnitsFromBits( AA->getAlignment(getASTContext())); diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index 3e03cb4bd5f99..76b705e7ad4a2 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -221,7 +221,7 @@ static SourceLocation SourceLocationForUserDeclaredType(QualType QT) { SourceLocation Loc; const Type *T = QT->getUnqualifiedDesugaredType(); if (const TagType *TT = dyn_cast(T)) - Loc = TT->getDecl()->getLocation(); + Loc = TT->getOriginalDecl()->getLocation(); else if (const ObjCInterfaceType *ObjCIT = dyn_cast(T)) Loc = ObjCIT->getDecl()->getLocation(); return Loc; diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index aa03d36bb69f2..8bfb9f8b1b99b 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -1287,11 +1287,11 @@ static void checkEnumTypesInSwitchStmt(Sema &S, const Expr *Cond, return; // Ignore anonymous enums. - if (!CondEnumType->getDecl()->getIdentifier() && - !CondEnumType->getDecl()->getTypedefNameForAnonDecl()) + if (!CondEnumType->getOriginalDecl()->getIdentifier() && + !CondEnumType->getOriginalDecl()->getTypedefNameForAnonDecl()) return; - if (!CaseEnumType->getDecl()->getIdentifier() && - !CaseEnumType->getDecl()->getTypedefNameForAnonDecl()) + if (!CaseEnumType->getOriginalDecl()->getIdentifier() && + !CaseEnumType->getOriginalDecl()->getTypedefNameForAnonDecl()) return; if (S.Context.hasSameUnqualifiedType(CondType, CaseType)) @@ -1604,9 +1604,11 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, // If switch has default case, then ignore it. if (!CaseListIsErroneous && !CaseListIsIncomplete && !HasConstantCond && - ET && ET->getDecl()->isCompleteDefinition() && - !ET->getDecl()->enumerators().empty()) { - const EnumDecl *ED = ET->getDecl(); + ET) { + const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + if (!ED->isCompleteDefinition() || ED->enumerators().empty()) + goto enum_out; + EnumValsTy EnumVals; // Gather all enum values, set their type and sort them, @@ -1749,7 +1751,7 @@ Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, if (SrcExpr->isTypeDependent() || SrcExpr->isValueDependent()) return; - const EnumDecl *ED = ET->getDecl(); + const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); if (!ED->isClosed()) return; @@ -3710,7 +3712,7 @@ class LocalTypedefNameReferencer : public DynamicRecursiveASTVisitor { Sema &S; }; bool LocalTypedefNameReferencer::VisitRecordType(RecordType *RT) { - auto *R = dyn_cast(RT->getDecl()); + auto *R = dyn_cast(RT->getOriginalDecl()); if (!R || !R->isLocalClass() || !R->isLocalClass()->isExternallyVisible() || R->isDependentType()) return true; @@ -3929,7 +3931,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, << RetValExp->getSourceRange(); if (FD->hasAttr() && RetValExp) { if (const auto *RT = dyn_cast(FnRetType.getCanonicalType())) { - if (RT->getDecl()->isOrContainsUnion()) + if (RT->getOriginalDecl()->isOrContainsUnion()) Diag(RetValExp->getBeginLoc(), diag::warn_cmse_nonsecure_union) << 1; } } diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index ceca15dd3e388..cd8b98c7444eb 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -907,7 +907,8 @@ bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member, LookupResult FieldResult(*this, &Context.Idents.get(NextMember), SourceLocation(), LookupMemberName); - if (!LookupQualifiedName(FieldResult, RT->getDecl())) + RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + if (!LookupQualifiedName(FieldResult, RD)) return true; if (!FieldResult.isSingleResult()) @@ -951,7 +952,8 @@ Sema::LookupInlineAsmVarDeclField(Expr *E, StringRef Member, LookupResult FieldResult(*this, &Context.Idents.get(Member), AsmLoc, LookupMemberName); - if (!LookupQualifiedName(FieldResult, RT->getDecl())) + if (!LookupQualifiedName(FieldResult, + RT->getOriginalDecl()->getDefinitionOrSelf())) return ExprResult(); // Only normal and indirect field results will work. diff --git a/clang/lib/Sema/SemaSwift.cpp b/clang/lib/Sema/SemaSwift.cpp index 4000beff7dc49..a99222c5ed55f 100644 --- a/clang/lib/Sema/SemaSwift.cpp +++ b/clang/lib/Sema/SemaSwift.cpp @@ -130,7 +130,7 @@ static bool isErrorParameter(Sema &S, QualType QT) { // Check for CFError**. if (const auto *PT = Pointee->getAs()) if (const auto *RT = PT->getPointeeType()->getAs()) - if (S.ObjC().isCFError(RT->getDecl())) + if (S.ObjC().isCFError(RT->getOriginalDecl()->getDefinitionOrSelf())) return true; return false; @@ -272,7 +272,8 @@ static void checkSwiftAsyncErrorBlock(Sema &S, Decl *D, // Check for CFError *. if (const auto *PtrTy = Param->getAs()) { if (const auto *RT = PtrTy->getPointeeType()->getAs()) { - if (S.ObjC().isCFError(RT->getDecl())) { + if (S.ObjC().isCFError( + RT->getOriginalDecl()->getDefinitionOrSelf())) { AnyErrorParams = true; break; } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 7e25a37694ce8..f6cf569c226ce 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2797,7 +2797,7 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( if (const EnumType *EnumT = T->getAs()) { // FIXME: Forward-declared enums require a TSK_ExplicitSpecialization // check here. - EnumDecl *Enum = EnumT->getDecl(); + EnumDecl *Enum = EnumT->getOriginalDecl(); // Get to the parent type. if (TypeDecl *Parent = dyn_cast(Enum->getParent())) @@ -3234,7 +3234,7 @@ static QualType builtinCommonTypeImpl(Sema &S, ElaboratedTypeKeyword Keyword, } static bool isInVkNamespace(const RecordType *RT) { - DeclContext *DC = RT->getDecl()->getDeclContext(); + DeclContext *DC = RT->getOriginalDecl()->getDeclContext(); if (!DC) return false; @@ -3251,8 +3251,9 @@ static SpirvOperand checkHLSLSpirvTypeOperand(Sema &SemaRef, if (auto *RT = OperandArg->getAs()) { bool Literal = false; SourceLocation LiteralLoc; - if (isInVkNamespace(RT) && RT->getDecl()->getName() == "Literal") { - auto SpecDecl = dyn_cast(RT->getDecl()); + if (isInVkNamespace(RT) && RT->getOriginalDecl()->getName() == "Literal") { + auto SpecDecl = + dyn_cast(RT->getOriginalDecl()); assert(SpecDecl); const TemplateArgumentList &LiteralArgs = SpecDecl->getTemplateArgs(); @@ -3263,8 +3264,9 @@ static SpirvOperand checkHLSLSpirvTypeOperand(Sema &SemaRef, } if (RT && isInVkNamespace(RT) && - RT->getDecl()->getName() == "integral_constant") { - auto SpecDecl = dyn_cast(RT->getDecl()); + RT->getOriginalDecl()->getName() == "integral_constant") { + auto SpecDecl = + dyn_cast(RT->getOriginalDecl()); assert(SpecDecl); const TemplateArgumentList &ConstantArgs = SpecDecl->getTemplateArgs(); @@ -3997,7 +3999,7 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK, // Check the tag kind if (const RecordType *RT = Result->getAs()) { - RecordDecl *D = RT->getDecl(); + RecordDecl *D = RT->getOriginalDecl()->getDefinitionOrSelf(); IdentifierInfo *Id = D->getIdentifier(); assert(Id && "templated class must have an identifier"); @@ -6166,11 +6168,11 @@ bool UnnamedLocalNoLinkageFinder::VisitDeducedTemplateSpecializationType( } bool UnnamedLocalNoLinkageFinder::VisitRecordType(const RecordType* T) { - return VisitTagDecl(T->getDecl()); + return VisitTagDecl(T->getOriginalDecl()->getDefinitionOrSelf()); } bool UnnamedLocalNoLinkageFinder::VisitEnumType(const EnumType* T) { - return VisitTagDecl(T->getDecl()); + return VisitTagDecl(T->getOriginalDecl()->getDefinitionOrSelf()); } bool UnnamedLocalNoLinkageFinder::VisitTemplateTypeParmType( @@ -6190,7 +6192,7 @@ bool UnnamedLocalNoLinkageFinder::VisitTemplateSpecializationType( bool UnnamedLocalNoLinkageFinder::VisitInjectedClassNameType( const InjectedClassNameType* T) { - return VisitTagDecl(T->getDecl()); + return VisitTagDecl(T->getOriginalDecl()->getDefinitionOrSelf()); } bool UnnamedLocalNoLinkageFinder::VisitDependentNameType( @@ -7243,7 +7245,8 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // that case, this may extend the argument from 1 bit to 8 bits. QualType IntegerType = ParamType; if (const EnumType *Enum = IntegerType->getAs()) - IntegerType = Enum->getDecl()->getIntegerType(); + IntegerType = + Enum->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); Value = Value.extOrTrunc(IntegerType->isBitIntType() ? Context.getIntWidth(IntegerType) : Context.getTypeSize(IntegerType)); @@ -7341,7 +7344,8 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, QualType IntegerType = ParamType; if (const EnumType *Enum = IntegerType->getAs()) { - IntegerType = Enum->getDecl()->getIntegerType(); + IntegerType = + Enum->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); } if (ParamType->isBooleanType()) { @@ -7799,7 +7803,7 @@ static Expr *BuildExpressionFromIntegralTemplateArgumentValue( // type of literal for it. QualType T = OrigT; if (const EnumType *ET = OrigT->getAs()) - T = ET->getDecl()->getIntegerType(); + T = ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); Expr *E; if (T->isAnyCharacterType()) { diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 163994c17caa6..5c14d890f94d5 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2046,7 +2046,7 @@ TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D, return cast_or_null(TransformDecl(Loc, D)); if (const TagType *Tag = T->getAs()) - return Tag->getDecl(); + return Tag->getOriginalDecl(); // The resulting type is not a tag; complain. getSema().Diag(Loc, diag::err_nested_name_spec_non_tag) << T; diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 76da4deab1e9c..5e49645ec2379 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1483,9 +1483,9 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D, // If the old typedef was the name for linkage purposes of an anonymous // tag decl, re-establish that relationship for the new typedef. if (const TagType *oldTagType = D->getUnderlyingType()->getAs()) { - TagDecl *oldTag = oldTagType->getDecl(); + TagDecl *oldTag = oldTagType->getOriginalDecl(); if (oldTag->getTypedefNameForAnonDecl() == D && !Invalid) { - TagDecl *newTag = DI->getType()->castAs()->getDecl(); + TagDecl *newTag = DI->getType()->castAs()->getOriginalDecl(); assert(!newTag->hasNameForLinkage()); newTag->setTypedefNameForAnonDecl(Typedef); } @@ -5735,7 +5735,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, QualType TransformRecordType(TypeLocBuilder &TLB, RecordTypeLoc TL) { const RecordType *T = TL.getTypePtr(); RecordDecl *Record = cast_or_null( - getDerived().TransformDecl(TL.getNameLoc(), T->getDecl())); + getDerived().TransformDecl(TL.getNameLoc(), T->getOriginalDecl())); if (Record != OldDecl) return Base::TransformRecordType(TLB, TL); @@ -6979,12 +6979,14 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, CanQualType T = Context.getCanonicalTagType(Spec); const RecordType *Tag = T->getAs(); assert(Tag && "type of non-dependent record is not a RecordType"); - if (Tag->isBeingDefined()) + auto *TagDecl = + cast(Tag->getOriginalDecl())->getDefinitionOrSelf(); + if (TagDecl->isBeingDefined()) IsBeingInstantiated = true; else if (RequireCompleteType(Loc, T, diag::err_incomplete_type)) return nullptr; - ParentDC = Tag->getDecl(); + ParentDC = TagDecl; } } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 3d301624eb366..2bb95a738e0ab 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1238,7 +1238,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { assert(!Result.isNull() && "Didn't get a type for typeof?"); if (!Result->isDependentType()) if (const TagType *TT = Result->getAs()) - S.DiagnoseUseOfDecl(TT->getDecl(), DS.getTypeSpecTypeLoc()); + S.DiagnoseUseOfDecl(TT->getOriginalDecl(), DS.getTypeSpecTypeLoc()); // TypeQuals handled by caller. Result = Context.getTypeOfType( Result, DS.getTypeSpecType() == DeclSpec::TST_typeof_unqualType @@ -2117,7 +2117,9 @@ QualType Sema::BuildArrayType(QualType T, ArraySizeModifier ASM, if (const RecordType *EltTy = T->getAs()) { // If the element type is a struct or union that contains a variadic // array, accept it as a GNU extension: C99 6.7.2.1p2. - if (EltTy->getDecl()->hasFlexibleArrayMember()) + if (EltTy->getOriginalDecl() + ->getDefinitionOrSelf() + ->hasFlexibleArrayMember()) Diag(Loc, diag::ext_flexible_array_in_array) << T; } else if (T->isObjCObjectType()) { Diag(Loc, diag::err_objc_array_of_interfaces) << T; @@ -3964,7 +3966,8 @@ classifyPointerDeclarator(Sema &S, QualType type, Declarator &declarator, return PointerDeclaratorKind::NonPointer; if (auto recordType = type->getAs()) { - RecordDecl *recordDecl = recordType->getDecl(); + RecordDecl *recordDecl = + recordType->getOriginalDecl()->getDefinitionOrSelf(); // If this is CFErrorRef*, report it as such. if (numNormalPointers == 2 && numTypeSpecifierPointers < 2 && @@ -9583,7 +9586,8 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T, if (!RT) return true; - const CXXRecordDecl *RD = cast(RT->getDecl()); + 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 @@ -9671,7 +9675,7 @@ QualType Sema::BuildTypeofExprType(Expr *E, TypeOfKind Kind) { if (!E->isTypeDependent()) { QualType T = E->getType(); if (const TagType *TT = T->getAs()) - DiagnoseUseOfDecl(TT->getDecl(), E->getExprLoc()); + DiagnoseUseOfDecl(TT->getOriginalDecl(), E->getExprLoc()); } return Context.getTypeOfExprType(E, Kind); } @@ -9837,8 +9841,7 @@ QualType Sema::BuildPackIndexingType(QualType Pattern, Expr *IndexExpr, static QualType GetEnumUnderlyingType(Sema &S, QualType BaseType, SourceLocation Loc) { assert(BaseType->isEnumeralType()); - EnumDecl *ED = BaseType->castAs()->getDecl(); - assert(ED && "EnumType has no EnumDecl"); + EnumDecl *ED = BaseType->castAs()->getOriginalDecl(); S.DiagnoseUseOfDecl(ED, Loc); diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp index a541f1ff692bd..eddad958a7ceb 100644 --- a/clang/lib/Sema/SemaTypeTraits.cpp +++ b/clang/lib/Sema/SemaTypeTraits.cpp @@ -561,7 +561,8 @@ static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op, bool (CXXRecordDecl::*HasTrivial)() const, bool (CXXRecordDecl::*HasNonTrivial)() const, bool (CXXMethodDecl::*IsDesiredOp)() const) { - CXXRecordDecl *RD = cast(RT->getDecl()); + CXXRecordDecl *RD = + cast(RT->getOriginalDecl())->getDefinitionOrSelf(); if ((RD->*HasTrivial)() && !(RD->*HasNonTrivial)()) return true; @@ -1609,9 +1610,9 @@ bool Sema::BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, // Unions are never base classes, and never have base classes. // It doesn't matter if they are complete or not. See PR#41843 - if (lhsRecord && lhsRecord->getDecl()->isUnion()) + if (lhsRecord && lhsRecord->getOriginalDecl()->isUnion()) return false; - if (rhsRecord && rhsRecord->getDecl()->isUnion()) + if (rhsRecord && rhsRecord->getOriginalDecl()->isUnion()) return false; if (lhsRecord == rhsRecord) @@ -1625,8 +1626,8 @@ bool Sema::BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, diag::err_incomplete_type_used_in_type_trait_expr)) return false; - return cast(rhsRecord->getDecl()) - ->isDerivedFrom(cast(lhsRecord->getDecl())); + return cast(rhsRecord->getOriginalDecl()) + ->isDerivedFrom(cast(lhsRecord->getOriginalDecl())); } static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, @@ -1666,8 +1667,9 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, diag::err_incomplete_type)) return false; - return cast(DerivedRecord->getDecl()) - ->isVirtuallyDerivedFrom(cast(BaseRecord->getDecl())); + return cast(DerivedRecord->getOriginalDecl()) + ->isVirtuallyDerivedFrom( + cast(BaseRecord->getOriginalDecl())); } case BTT_IsSame: return Self.Context.hasSameType(LhsT, RhsT); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 6327e82a8cbae..6777aa6538113 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -14100,7 +14100,7 @@ TreeTransform::TransformCXXTypeidExpr(CXXTypeidExpr *E) { auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated; if (E->isGLValue()) if (auto *RecordT = Op->getType()->getAs()) - if (cast(RecordT->getDecl())->isPolymorphic()) + if (cast(RecordT->getOriginalDecl())->isPolymorphic()) EvalCtx = SemaRef.ExprEvalContexts.back().Context; EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx, @@ -14340,7 +14340,8 @@ TreeTransform::TransformCXXNewExpr(CXXNewExpr *E) { QualType ElementType = SemaRef.Context.getBaseElementType(E->getAllocatedType()); if (const RecordType *RecordT = ElementType->getAs()) { - CXXRecordDecl *Record = cast(RecordT->getDecl()); + CXXRecordDecl *Record = cast(RecordT->getOriginalDecl()) + ->getDefinitionOrSelf(); if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) { SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor); } @@ -14410,7 +14411,9 @@ TreeTransform::TransformCXXDeleteExpr(CXXDeleteExpr *E) { QualType Destroyed = SemaRef.Context.getBaseElementType( E->getDestroyedType()); if (const RecordType *DestroyedRec = Destroyed->getAs()) { - CXXRecordDecl *Record = cast(DestroyedRec->getDecl()); + CXXRecordDecl *Record = + cast(DestroyedRec->getOriginalDecl()) + ->getDefinitionOrSelf(); SemaRef.MarkFunctionReferenced(E->getBeginLoc(), SemaRef.LookupDestructor(Record)); } diff --git a/clang/lib/Sema/UsedDeclVisitor.h b/clang/lib/Sema/UsedDeclVisitor.h index 580d702f96fe5..ad475ab0f42ae 100644 --- a/clang/lib/Sema/UsedDeclVisitor.h +++ b/clang/lib/Sema/UsedDeclVisitor.h @@ -71,9 +71,10 @@ class UsedDeclVisitor : public EvaluatedExprVisitor { if (!DestroyedOrNull.isNull()) { QualType Destroyed = S.Context.getBaseElementType(DestroyedOrNull); if (const RecordType *DestroyedRec = Destroyed->getAs()) { - CXXRecordDecl *Record = cast(DestroyedRec->getDecl()); - if (Record->getDefinition()) - asImpl().visitUsedDecl(E->getBeginLoc(), S.LookupDestructor(Record)); + CXXRecordDecl *Record = + cast(DestroyedRec->getOriginalDecl()); + if (auto *Def = Record->getDefinition()) + asImpl().visitUsedDecl(E->getBeginLoc(), S.LookupDestructor(Def)); } } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index c517cfffcf0f8..ce2edcc25a099 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -5501,7 +5501,7 @@ void ASTReader::InitializeContext() { Error("Invalid FILE type in AST file"); return; } - Context.setFILEDecl(Tag->getDecl()); + Context.setFILEDecl(Tag->getOriginalDecl()); } } } @@ -5522,7 +5522,7 @@ void ASTReader::InitializeContext() { Error("Invalid jmp_buf type in AST file"); return; } - Context.setjmp_bufDecl(Tag->getDecl()); + Context.setjmp_bufDecl(Tag->getOriginalDecl()); } } } @@ -5540,7 +5540,7 @@ void ASTReader::InitializeContext() { else { const TagType *Tag = Sigjmp_bufType->getAs(); assert(Tag && "Invalid sigjmp_buf type in AST file"); - Context.setsigjmp_bufDecl(Tag->getDecl()); + Context.setsigjmp_bufDecl(Tag->getOriginalDecl()); } } } @@ -5575,7 +5575,7 @@ void ASTReader::InitializeContext() { else { const TagType *Tag = Ucontext_tType->getAs(); assert(Tag && "Invalid ucontext_t type in AST file"); - Context.setucontext_tDecl(Tag->getDecl()); + Context.setucontext_tDecl(Tag->getOriginalDecl()); } } } diff --git a/clang/lib/Serialization/TemplateArgumentHasher.cpp b/clang/lib/Serialization/TemplateArgumentHasher.cpp index 353e8a2daa925..3e8ffea78c2f1 100644 --- a/clang/lib/Serialization/TemplateArgumentHasher.cpp +++ b/clang/lib/Serialization/TemplateArgumentHasher.cpp @@ -358,7 +358,7 @@ class TypeVisitorHelper : public TypeVisitor { AddQualType(T->getReplacementType()); } - void VisitTagType(const TagType *T) { AddDecl(T->getDecl()); } + void VisitTagType(const TagType *T) { AddDecl(T->getOriginalDecl()); } void VisitRecordType(const RecordType *T) { VisitTagType(T); } void VisitEnumType(const EnumType *T) { VisitTagType(T); } diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp index 23935647a5826..731e506a5d259 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -250,7 +250,7 @@ class FindUninitializedField { bool Find(const TypedValueRegion *R) { QualType T = R->getValueType(); if (const RecordType *RT = T->getAsStructureType()) { - const RecordDecl *RD = RT->getDecl()->getDefinition(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinition(); assert(RD && "Referred record has no definition"); for (const auto *I : RD->fields()) { if (I->isUnnamedBitField()) diff --git a/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp index 0b52c9bd8ac2a..90c6537d71d9d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp @@ -53,7 +53,7 @@ static bool evenFlexibleArraySize(ASTContext &Ctx, CharUnits RegionSize, if (!RT) return false; - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); RecordDecl::field_iterator Iter(RD->field_begin()); RecordDecl::field_iterator End(RD->field_end()); const FieldDecl *Last = nullptr; diff --git a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp index 355e82e465e82..054b2e96bd13b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp @@ -148,7 +148,8 @@ void EnumCastOutOfRangeChecker::checkPreStmt(const CastExpr *CE, // 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()->getDecl(); + const EnumDecl *ED = + T->castAs()->getOriginalDecl()->getDefinitionOrSelf(); // [[clang::flag_enum]] annotated enums are by definition should be ignored. if (ED->hasAttr()) diff --git a/clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp index 29ed4ad171aec..828b6f91d81c2 100644 --- a/clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp @@ -198,7 +198,7 @@ static bool IsPartOfAST(const CXXRecordDecl *R) { for (const auto &BS : R->bases()) { QualType T = BS.getType(); if (const RecordType *baseT = T->getAs()) { - CXXRecordDecl *baseD = cast(baseT->getDecl()); + CXXRecordDecl *baseD = cast(baseT->getOriginalDecl()); if (IsPartOfAST(baseD)) return true; } @@ -244,7 +244,7 @@ void ASTFieldVisitor::Visit(FieldDecl *D) { ReportError(T); if (const RecordType *RT = T->getAs()) { - const RecordDecl *RD = RT->getDecl()->getDefinition(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinition(); for (auto *I : RD->fields()) Visit(I); } diff --git a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp index 0aea981252259..b1a7cd7620424 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp @@ -148,7 +148,9 @@ void NonNullParamChecker::checkPreCall(const CallEvent &Call, QualType T = ArgE->getType(); const RecordType *UT = T->getAsUnionType(); - if (!UT || !UT->getDecl()->hasAttr()) + if (!UT || !UT->getOriginalDecl() + ->getMostRecentDecl() + ->hasAttr()) continue; auto CSV = DV->getAs(); diff --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp index 844316c4a8f7d..7ef659518ab1b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp @@ -123,7 +123,7 @@ class PaddingChecker : public Checker> { return; // TODO: Recurse into the fields to see if they have excess padding. - visitRecord(RT->getDecl(), Elts); + visitRecord(RT->getOriginalDecl()->getDefinitionOrSelf(), Elts); } bool shouldSkipDecl(const RecordDecl *RD) const { diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp index d53aad46d7699..36c12582a5787 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp @@ -252,7 +252,7 @@ void RetainTypeChecker::visitTypedef(const TypedefDecl *TD) { return; } - for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) { + for (auto *Redecl : RT->getOriginalDecl()->getMostRecentDecl()->redecls()) { if (Redecl->getAttr() || Redecl->getAttr()) { CFPointees.insert(RT); @@ -293,7 +293,7 @@ std::optional isUnretained(const QualType T, bool IsARCEnabled) { auto *Record = PointeeType->getAsStructureType(); if (!Record) return false; - auto *Decl = Record->getDecl(); + auto *Decl = Record->getOriginalDecl(); if (!Decl) return false; auto TypeName = Decl->getName(); diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp index 3be2b19574e40..6f3a280971cb8 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp @@ -121,13 +121,13 @@ class DerefFuncDeleteExprVisitor return true; } } else if (auto *RD = dyn_cast(PointeeType)) { - if (RD->getDecl() == ClassDecl) + if (declaresSameEntity(RD->getOriginalDecl(), ClassDecl)) return true; } else if (auto *ST = dyn_cast(PointeeType)) { auto Type = ST->getReplacementType(); if (auto *RD = dyn_cast(Type)) { - if (RD->getDecl() == ClassDecl) + if (declaresSameEntity(RD->getOriginalDecl(), ClassDecl)) return true; } } diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index e99816fa782d8..180056cf68b64 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -89,7 +89,7 @@ static bool isCallback(QualType T) { T = T->getPointeeType(); if (const RecordType *RT = T->getAsStructureType()) { - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); for (const auto *I : RD->fields()) { QualType FieldT = I->getType(); if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType()) @@ -391,7 +391,9 @@ bool CallEvent::isVariadic(const Decl *D) { static bool isTransparentUnion(QualType T) { const RecordType *UT = T->getAsUnionType(); - return UT && UT->getDecl()->hasAttr(); + return UT && UT->getOriginalDecl() + ->getMostRecentDecl() + ->hasAttr(); } // In some cases, symbolic cases should be transformed before we associate diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 388034b087789..02375b0c3469a 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -2453,7 +2453,8 @@ NonLoc RegionStoreManager::createLazyBinding(RegionBindingsConstRef B, SVal RegionStoreManager::getBindingForStruct(RegionBindingsConstRef B, const TypedValueRegion *R) { - const RecordDecl *RD = R->getValueType()->castAs()->getDecl(); + const RecordDecl *RD = + R->getValueType()->castAs()->getOriginalDecl(); if (!RD->getDefinition()) return UnknownVal(); @@ -2844,7 +2845,7 @@ RegionStoreManager::bindStruct(LimitedRegionBindingsConstRef B, assert(T->isStructureOrClassType()); const RecordType* RT = T->castAs(); - const RecordDecl *RD = RT->getDecl(); + const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); if (!RD->isCompleteDefinition()) return B; diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 27ab412e1e685..d4f0794a8e0af 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -1688,9 +1688,9 @@ bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) { return true; if (TL.isDefinition()) - return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest)); + return Visit(MakeCXCursor(TL.getOriginalDecl(), TU, RegionOfInterest)); - return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); + return Visit(MakeCursorTypeRef(TL.getOriginalDecl(), TL.getNameLoc(), TU)); } bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { @@ -1910,7 +1910,7 @@ bool CursorVisitor::VisitPackIndexingTypeLoc(PackIndexingTypeLoc TL) { } bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { - return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); + return Visit(MakeCursorTypeRef(TL.getOriginalDecl(), TL.getNameLoc(), TU)); } bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) { diff --git a/clang/tools/libclang/CIndexCodeCompletion.cpp b/clang/tools/libclang/CIndexCodeCompletion.cpp index 8f6729b83ffa0..1636e1e5e0a7b 100644 --- a/clang/tools/libclang/CIndexCodeCompletion.cpp +++ b/clang/tools/libclang/CIndexCodeCompletion.cpp @@ -616,7 +616,7 @@ namespace { if (!baseType.isNull()) { // Get the declaration for a class/struct/union/enum type if (const TagType *Tag = baseType->getAs()) - D = Tag->getDecl(); + D = Tag->getOriginalDecl(); // Get the @interface declaration for a (possibly-qualified) Objective-C // object pointer type, e.g., NSString* else if (const ObjCObjectPointerType *ObjPtr = @@ -628,7 +628,7 @@ namespace { // Get the class for a C++ injected-class-name else if (const InjectedClassNameType *Injected = baseType->getAs()) - D = Injected->getDecl(); + D = Injected->getOriginalDecl(); } if (D != nullptr) { diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index a51efe28c0b01..3c4062410eac1 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -1335,7 +1335,7 @@ CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) { if (const TypedefType *Typedef = Ty->getAs()) return MakeCursorTypeRef(Typedef->getDecl(), Loc, TU); if (const TagType *Tag = Ty->getAs()) - return MakeCursorTypeRef(Tag->getDecl(), Loc, TU); + return MakeCursorTypeRef(Tag->getOriginalDecl(), Loc, TU); if (const TemplateTypeParmType *TemplP = Ty->getAs()) return MakeCursorTypeRef(TemplP->getDecl(), Loc, TU); diff --git a/clang/tools/libclang/CXIndexDataConsumer.cpp b/clang/tools/libclang/CXIndexDataConsumer.cpp index ebab5135605b6..941e39a582758 100644 --- a/clang/tools/libclang/CXIndexDataConsumer.cpp +++ b/clang/tools/libclang/CXIndexDataConsumer.cpp @@ -357,7 +357,7 @@ CXIndexDataConsumer::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl *D, TST = T->getAs()) { BaseD = TST->getTemplateName().getAsTemplateDecl(); } else if (const RecordType *RT = T->getAs()) { - BaseD = RT->getDecl(); + BaseD = RT->getOriginalDecl(); } if (BaseD) diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp index 3feb56334d79c..d21ac7cceed9a 100644 --- a/clang/tools/libclang/CXType.cpp +++ b/clang/tools/libclang/CXType.cpp @@ -546,11 +546,11 @@ CXCursor clang_getTypeDeclaration(CXType CT) { break; case Type::Record: case Type::Enum: - D = cast(TP)->getDecl(); + D = cast(TP)->getOriginalDecl(); break; case Type::TemplateSpecialization: if (const RecordType *Record = TP->getAs()) - D = Record->getDecl(); + D = Record->getOriginalDecl(); else D = cast(TP)->getTemplateName() .getAsTemplateDecl(); @@ -564,7 +564,7 @@ CXCursor clang_getTypeDeclaration(CXType CT) { break; case Type::InjectedClassName: - D = cast(TP)->getDecl(); + D = cast(TP)->getOriginalDecl(); break; // FIXME: Template type parameters! @@ -1037,7 +1037,7 @@ static long long visitRecordForValidation(const RecordDecl *RD) { return CXTypeLayoutError_Dependent; // recurse if (const RecordType *ChildType = I->getType()->getAs()) { - if (const RecordDecl *Child = ChildType->getDecl()) { + if (const RecordDecl *Child = ChildType->getOriginalDecl()) { long long ret = visitRecordForValidation(Child); if (ret < 0) return ret; diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 9b45145c2eac1..e3e2a9b1adc13 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -29,7 +29,7 @@ using internal::Matcher; static const RecordDecl *getRecordDeclOfFriend(FriendDecl *FD) { QualType Ty = FD->getFriendType()->getType().getCanonicalType(); - return cast(Ty)->getDecl(); + return cast(Ty)->getOriginalDecl(); } struct ImportExpr : TestImportBase {}; @@ -4614,7 +4614,7 @@ TEST_P(ImportFriendClasses, ImportOfClassDefinitionAndFwdFriendShouldBeLinked) { auto *Friend = FirstDeclMatcher().match(FromTU0, friendDecl()); QualType FT = Friend->getFriendType()->getType(); FT = FromTU0->getASTContext().getCanonicalType(FT); - auto *Fwd = cast(FT)->getDecl(); + auto *Fwd = cast(FT)->getOriginalDecl(); auto *ImportedFwd = Import(Fwd, Lang_CXX03); Decl *FromTU1 = getTuDecl( R"( diff --git a/clang/unittests/AST/RandstructTest.cpp b/clang/unittests/AST/RandstructTest.cpp index c22d866ed4fad..cba446fc529e1 100644 --- a/clang/unittests/AST/RandstructTest.cpp +++ b/clang/unittests/AST/RandstructTest.cpp @@ -532,7 +532,7 @@ TEST(RANDSTRUCT_TEST, AnonymousStructsAndUnionsRetainFieldOrder) { for (const Decl *D : RD->decls()) if (const FieldDecl *FD = dyn_cast(D)) { if (const auto *Record = FD->getType()->getAs()) { - RD = Record->getDecl(); + RD = Record->getOriginalDecl()->getDefinitionOrSelf(); if (RD->isAnonymousStructOrUnion()) { // These field orders shouldn't change. if (RD->isUnion()) { diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp b/clang/unittests/AST/StructuralEquivalenceTest.cpp index 24e20c7471f3c..bee288dbfe436 100644 --- a/clang/unittests/AST/StructuralEquivalenceTest.cpp +++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp @@ -719,11 +719,13 @@ TEST_F(StructuralEquivalenceRecordTest, AnonymousRecordsShouldBeInequivalent) { auto *A = FirstDeclMatcher().match( TU, indirectFieldDecl(hasName("a"))); auto *FA = cast(A->chain().front()); - RecordDecl *RA = cast(FA->getType().getTypePtr())->getDecl(); + RecordDecl *RA = + cast(FA->getType().getTypePtr())->getOriginalDecl(); auto *B = FirstDeclMatcher().match( TU, indirectFieldDecl(hasName("b"))); auto *FB = cast(B->chain().front()); - RecordDecl *RB = cast(FB->getType().getTypePtr())->getDecl(); + RecordDecl *RB = + cast(FB->getType().getTypePtr())->getOriginalDecl(); ASSERT_NE(RA, RB); EXPECT_TRUE(testStructuralMatch(RA, RA)); @@ -752,13 +754,15 @@ TEST_F(StructuralEquivalenceRecordTest, auto *A = FirstDeclMatcher().match( TU, indirectFieldDecl(hasName("a"))); auto *FA = cast(A->chain().front()); - RecordDecl *RA = cast(FA->getType().getTypePtr())->getDecl(); + RecordDecl *RA = + cast(FA->getType().getTypePtr())->getOriginalDecl(); auto *TU1 = get<1>(t); auto *A1 = FirstDeclMatcher().match( TU1, indirectFieldDecl(hasName("a"))); auto *FA1 = cast(A1->chain().front()); - RecordDecl *RA1 = cast(FA1->getType().getTypePtr())->getDecl(); + RecordDecl *RA1 = + cast(FA1->getType().getTypePtr())->getOriginalDecl(); RecordDecl *X = FirstDeclMatcher().match(TU, recordDecl(hasName("X"))); diff --git a/clang/unittests/StaticAnalyzer/SValTest.cpp b/clang/unittests/StaticAnalyzer/SValTest.cpp index d8897b0f2183d..a5781518c23d9 100644 --- a/clang/unittests/StaticAnalyzer/SValTest.cpp +++ b/clang/unittests/StaticAnalyzer/SValTest.cpp @@ -301,13 +301,13 @@ void foo(int x) { ASSERT_FALSE(B.getType(Context).isNull()); const auto *BRecordType = dyn_cast(B.getType(Context)); ASSERT_NE(BRecordType, nullptr); - EXPECT_EQ("TestStruct", BRecordType->getDecl()->getName()); + EXPECT_EQ("TestStruct", BRecordType->getOriginalDecl()->getName()); SVal C = getByName("c"); ASSERT_FALSE(C.getType(Context).isNull()); const auto *CRecordType = dyn_cast(C.getType(Context)); ASSERT_NE(CRecordType, nullptr); - EXPECT_EQ("TestUnion", CRecordType->getDecl()->getName()); + EXPECT_EQ("TestUnion", CRecordType->getOriginalDecl()->getName()); auto D = getByName("d").getAs(); ASSERT_TRUE(D.has_value()); @@ -319,12 +319,9 @@ void foo(int x) { ASSERT_TRUE(LD.has_value()); auto LDT = LD->getType(Context); ASSERT_FALSE(LDT.isNull()); - const auto *DElaboratedType = dyn_cast(LDT); - ASSERT_NE(DElaboratedType, nullptr); - const auto *DRecordType = - dyn_cast(DElaboratedType->getNamedType()); + const auto *DRecordType = dyn_cast(LDT); ASSERT_NE(DRecordType, nullptr); - EXPECT_EQ("TestStruct", DRecordType->getDecl()->getName()); + EXPECT_EQ("TestStruct", DRecordType->getOriginalDecl()->getName()); } SVAL_TEST(GetStringType, R"( @@ -353,7 +350,7 @@ void TestClass::foo() { ASSERT_NE(APtrTy, nullptr); const auto *ARecordType = dyn_cast(APtrTy->getPointeeType()); ASSERT_NE(ARecordType, nullptr); - EXPECT_EQ("TestClass", ARecordType->getDecl()->getName()); + EXPECT_EQ("TestClass", ARecordType->getOriginalDecl()->getName()); } SVAL_TEST(GetFunctionPtrType, R"( diff --git a/clang/unittests/Tooling/LookupTest.cpp b/clang/unittests/Tooling/LookupTest.cpp index ed6f5d4f3092c..4c49ebe47acb9 100644 --- a/clang/unittests/Tooling/LookupTest.cpp +++ b/clang/unittests/Tooling/LookupTest.cpp @@ -200,9 +200,9 @@ TEST(LookupTest, replaceNestedClassName) { Visitor.OnRecordTypeLoc = [&](RecordTypeLoc Type) { // Filter Types by name since there are other `RecordTypeLoc` in the test // file. - if (Type.getDecl()->getQualifiedNameAsString() == "a::b::Foo") { - EXPECT_EQ("x::Bar", replaceTypeLoc(Type.getDecl(), Type.getBeginLoc(), - "::a::x::Bar")); + if (Type.getOriginalDecl()->getQualifiedNameAsString() == "a::b::Foo") { + EXPECT_EQ("x::Bar", replaceTypeLoc(Type.getOriginalDecl(), + Type.getBeginLoc(), "::a::x::Bar")); } }; Visitor.runOver("namespace a { namespace b {\n" @@ -227,9 +227,9 @@ TEST(LookupTest, replaceNestedClassName) { // `x::y::Foo` in c.cc [1], it should not make "Foo" at [0] ambiguous because // it's not visible at [0]. Visitor.OnRecordTypeLoc = [&](RecordTypeLoc Type) { - if (Type.getDecl()->getQualifiedNameAsString() == "x::y::Old") { - EXPECT_EQ("Foo", - replaceTypeLoc(Type.getDecl(), Type.getBeginLoc(), "::x::Foo")); + if (Type.getOriginalDecl()->getQualifiedNameAsString() == "x::y::Old") { + EXPECT_EQ("Foo", replaceTypeLoc(Type.getOriginalDecl(), + Type.getBeginLoc(), "::x::Foo")); } }; Visitor.runOver(R"( diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp index 587a00dd27051..88cebb7c28033 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp @@ -24,7 +24,7 @@ class MemberPointerTypeLocVisitor : public ExpectedLocationVisitor { bool VisitRecordTypeLoc(RecordTypeLoc RTL) override { if (!RTL) return true; - Match(RTL.getDecl()->getName(), RTL.getNameLoc()); + Match(RTL.getOriginalDecl()->getName(), RTL.getNameLoc()); return true; } }; diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp index 23a2df42ff08c..64bad8a134111 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp @@ -18,7 +18,7 @@ class NestedNameSpecifiersVisitor : public ExpectedLocationVisitor { bool VisitRecordTypeLoc(RecordTypeLoc RTL) override { if (!RTL) return true; - Match(RTL.getDecl()->getName(), RTL.getNameLoc()); + Match(RTL.getOriginalDecl()->getName(), RTL.getNameLoc()); return true; }