Skip to content

Conversation

mizvekov
Copy link
Contributor

This changes a bunch of places which use getAs, including derived types, just to obtain the tag definition.

This is preparation for #155028, offloading all the changes that PR used to introduce which don't depend on any new helpers.

This changes a bunch of places which use getAs<TagType>, including
derived types, just to obtain the tag definition.

This is preparation for #155028, offloading all the changes that
PR used to introduce which don't depend on any new helpers.
@mizvekov mizvekov self-assigned this Aug 25, 2025
@llvmbot llvmbot added clang Clang issues not falling into any other category clang-tools-extra backend:ARM backend:AArch64 backend:AMDGPU backend:PowerPC backend:SystemZ backend:X86 clang-tidy clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules clang:codegen IR generation bugs: mangling, exceptions, etc. clang:as-a-library libclang and C++ API clang:static analyzer backend:CSKY HLSL HLSL Language Support clang:analysis ClangIR Anything related to the ClangIR project clang:bytecode Issues for the clang bytecode constexpr interpreter labels Aug 25, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 25, 2025

@llvm/pr-subscribers-clang-static-analyzer-1
@llvm/pr-subscribers-backend-powerpc
@llvm/pr-subscribers-clang
@llvm/pr-subscribers-clang-modules
@llvm/pr-subscribers-clang-tools-extra

@llvm/pr-subscribers-clangir

Author: Matheus Izvekov (mizvekov)

Changes

This changes a bunch of places which use getAs<TagType>, including derived types, just to obtain the tag definition.

This is preparation for #155028, offloading all the changes that PR used to introduce which don't depend on any new helpers.


Patch is 172.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/155313.diff

100 Files Affected:

  • (modified) clang-tools-extra/clang-doc/Serialize.cpp (+2-3)
  • (modified) clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp (+2-3)
  • (modified) clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp (+9-14)
  • (modified) clang-tools-extra/clang-tidy/utils/TypeTraits.cpp (+2-3)
  • (modified) clang/include/clang/AST/AbstractBasicReader.h (+1-1)
  • (modified) clang/include/clang/AST/AbstractBasicWriter.h (+1-1)
  • (modified) clang/include/clang/AST/DeclCXX.h (+3-1)
  • (modified) clang/include/clang/Sema/Sema.h (+1-1)
  • (modified) clang/lib/AST/ASTContext.cpp (+12-22)
  • (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+2-2)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+7-14)
  • (modified) clang/lib/AST/ByteCode/Program.cpp (+4-6)
  • (modified) clang/lib/AST/ByteCode/Record.cpp (+1-3)
  • (modified) clang/lib/AST/CXXInheritance.cpp (+7-20)
  • (modified) clang/lib/AST/Decl.cpp (+7-13)
  • (modified) clang/lib/AST/DeclCXX.cpp (+13-18)
  • (modified) clang/lib/AST/DeclTemplate.cpp (+3-3)
  • (modified) clang/lib/AST/ExprConstant.cpp (+7-10)
  • (modified) clang/lib/AST/FormatString.cpp (+1-1)
  • (modified) clang/lib/AST/ItaniumMangle.cpp (+4-4)
  • (modified) clang/lib/AST/RecordLayoutBuilder.cpp (+11-15)
  • (modified) clang/lib/AST/Type.cpp (+41-56)
  • (modified) clang/lib/Analysis/ExprMutationAnalyzer.cpp (+2-1)
  • (modified) clang/lib/Analysis/ThreadSafetyCommon.cpp (+5-7)
  • (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+4-10)
  • (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+1-1)
  • (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+5-14)
  • (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+1-2)
  • (modified) clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp (+3-2)
  • (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+3-6)
  • (modified) clang/lib/CIR/CodeGen/TargetInfo.cpp (+2-4)
  • (modified) clang/lib/CodeGen/ABIInfo.cpp (+1-2)
  • (modified) clang/lib/CodeGen/ABIInfoImpl.cpp (+13-20)
  • (modified) clang/lib/CodeGen/CGBlocks.cpp (+3-6)
  • (modified) clang/lib/CodeGen/CGBuiltin.cpp (+4-5)
  • (modified) clang/lib/CodeGen/CGCXXABI.cpp (+1-4)
  • (modified) clang/lib/CodeGen/CGCall.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CGClass.cpp (+4-10)
  • (modified) clang/lib/CodeGen/CGDecl.cpp (+3-4)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+5-8)
  • (modified) clang/lib/CodeGen/CGExprAgg.cpp (+7-12)
  • (modified) clang/lib/CodeGen/CGExprCXX.cpp (+1-3)
  • (modified) clang/lib/CodeGen/CGExprConstant.cpp (+5-8)
  • (modified) clang/lib/CodeGen/CGObjC.cpp (+2-4)
  • (modified) clang/lib/CodeGen/CGObjCMac.cpp (+2-3)
  • (modified) clang/lib/CodeGen/CGObjCRuntime.cpp (+2-4)
  • (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+3-8)
  • (modified) clang/lib/CodeGen/CodeGenFunction.h (+1-3)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+2-3)
  • (modified) clang/lib/CodeGen/CodeGenTypes.cpp (+5-7)
  • (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+12-15)
  • (modified) clang/lib/CodeGen/Targets/AArch64.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/AMDGPU.cpp (+7-12)
  • (modified) clang/lib/CodeGen/Targets/ARM.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/CSKY.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/NVPTX.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/PPC.cpp (+1-4)
  • (modified) clang/lib/CodeGen/Targets/SPIR.cpp (+7-12)
  • (modified) clang/lib/CodeGen/Targets/SystemZ.cpp (+2-4)
  • (modified) clang/lib/CodeGen/Targets/X86.cpp (+10-15)
  • (modified) clang/lib/Edit/RewriteObjCFoundationAPI.cpp (+1-1)
  • (modified) clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp (+1-9)
  • (modified) clang/lib/Interpreter/Value.cpp (+6-9)
  • (modified) clang/lib/Sema/Sema.cpp (+15-18)
  • (modified) clang/lib/Sema/SemaAccess.cpp (+2-4)
  • (modified) clang/lib/Sema/SemaCUDA.cpp (+5-12)
  • (modified) clang/lib/Sema/SemaCast.cpp (+9-11)
  • (modified) clang/lib/Sema/SemaChecking.cpp (+5-12)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+69-91)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+24-30)
  • (modified) clang/lib/Sema/SemaDeclCXX.cpp (+21-38)
  • (modified) clang/lib/Sema/SemaDeclObjC.cpp (+9-18)
  • (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+2-3)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+18-28)
  • (modified) clang/lib/Sema/SemaExprCXX.cpp (+4-9)
  • (modified) clang/lib/Sema/SemaHLSL.cpp (+5-10)
  • (modified) clang/lib/Sema/SemaInit.cpp (+63-75)
  • (modified) clang/lib/Sema/SemaLookup.cpp (+4-7)
  • (modified) clang/lib/Sema/SemaObjCProperty.cpp (+2-4)
  • (modified) clang/lib/Sema/SemaOverload.cpp (+11-12)
  • (modified) clang/lib/Sema/SemaStmtAsm.cpp (+3-4)
  • (modified) clang/lib/Sema/SemaSwift.cpp (+7-9)
  • (modified) clang/lib/Sema/SemaTemplate.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+2-2)
  • (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+5-9)
  • (modified) clang/lib/Sema/SemaType.cpp (+3-8)
  • (modified) clang/lib/Sema/SemaTypeTraits.cpp (+5-7)
  • (modified) clang/lib/Sema/TreeTransform.h (+11-20)
  • (modified) clang/lib/Sema/UsedDeclVisitor.h (+4-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp (+2-3)
  • (modified) clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp (+5-11)
  • (modified) clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp (+3-3)
  • (modified) clang/lib/StaticAnalyzer/Core/ExprEngine.cpp (+1-1)
  • (modified) clang/tools/libclang/CIndex.cpp (+1-1)
  • (modified) clang/unittests/AST/ASTImporterTest.cpp (+1-3)
  • (modified) clang/unittests/AST/RandstructTest.cpp (+1-2)
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index bcab4f1b8a729..506cc0a3b0e8f 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -901,9 +901,8 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
   if (!D->isThisDeclarationADefinition())
     return;
   for (const CXXBaseSpecifier &B : D->bases()) {
-    if (const RecordType *Ty = B.getType()->getAs<RecordType>()) {
-      if (const CXXRecordDecl *Base = cast_or_null<CXXRecordDecl>(
-              Ty->getOriginalDecl()->getDefinition())) {
+    if (const auto *Base = B.getType()->getAsCXXRecordDecl()) {
+      if (Base->isCompleteDefinition()) {
         // 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/cert/DefaultOperatorNewAlignmentCheck.cpp b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
index 2a0d0ada42b28..2c2248afb69e7 100644
--- a/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
@@ -31,7 +31,7 @@ void DefaultOperatorNewAlignmentCheck::check(
     return;
   const TagDecl *D = T->getAsTagDecl();
   // Alignment can not be obtained for undefined type.
-  if (!D || !D->getDefinition() || !D->isCompleteDefinition())
+  if (!D || !D->isCompleteDefinition())
     return;
 
   ASTContext &Context = D->getASTContext();
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
index 40fd15c08f0a1..6508bfd5ca808 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
@@ -90,9 +90,8 @@ void SlicingCheck::diagnoseSlicedOverriddenMethods(
   }
   // Recursively process bases.
   for (const auto &Base : DerivedDecl.bases()) {
-    if (const auto *BaseRecordType = Base.getType()->getAs<RecordType>()) {
-      if (const auto *BaseRecord = cast_or_null<CXXRecordDecl>(
-              BaseRecordType->getOriginalDecl()->getDefinition()))
+    if (const auto *BaseRecord = Base.getType()->getAsCXXRecordDecl()) {
+      if (BaseRecord->isCompleteDefinition())
         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 0302a5ad4957c..36b6007b58a51 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
@@ -71,13 +71,10 @@ bool MultipleInheritanceCheck::isInterface(const CXXRecordDecl *Node) {
   for (const auto &I : Node->bases()) {
     if (I.isVirtual())
       continue;
-    const auto *Ty = I.getType()->getAs<RecordType>();
-    if (!Ty)
+    const auto *Base = I.getType()->getAsCXXRecordDecl();
+    if (!Base)
       continue;
-    const RecordDecl *D = Ty->getOriginalDecl()->getDefinition();
-    if (!D)
-      continue;
-    const auto *Base = cast<CXXRecordDecl>(D);
+    assert(Base->isCompleteDefinition());
     if (!isInterface(Base)) {
       addNodeToInterfaceMap(Node, false);
       return false;
@@ -103,11 +100,10 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
     for (const auto &I : D->bases()) {
       if (I.isVirtual())
         continue;
-      const auto *Ty = I.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = I.getType()->getAsCXXRecordDecl();
+      if (!Base)
         continue;
-      const auto *Base =
-          cast<CXXRecordDecl>(Ty->getOriginalDecl()->getDefinition());
+      assert(Base->isCompleteDefinition());
       if (!isInterface(Base))
         NumConcrete++;
     }
@@ -115,11 +111,10 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
     // Check virtual bases to see if there is more than one concrete
     // non-virtual base.
     for (const auto &V : D->vbases()) {
-      const auto *Ty = V.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = V.getType()->getAsCXXRecordDecl();
+      if (!Base)
         continue;
-      const auto *Base =
-          cast<CXXRecordDecl>(Ty->getOriginalDecl()->getDefinition());
+      assert(Base->isCompleteDefinition());
       if (!isInterface(Base))
         NumConcrete++;
     }
diff --git a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
index 5518afd32e7f0..f944306171135 100644
--- a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
+++ b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
@@ -119,9 +119,8 @@ bool isTriviallyDefaultConstructible(QualType Type, const ASTContext &Context) {
   if (CanonicalType->isScalarType() || CanonicalType->isVectorType())
     return true;
 
-  if (const auto *RT = CanonicalType->getAs<RecordType>()) {
-    return recordIsTriviallyDefaultConstructible(
-        *RT->getOriginalDecl()->getDefinitionOrSelf(), Context);
+  if (const auto *RD = CanonicalType->getAsRecordDecl()) {
+    return recordIsTriviallyDefaultConstructible(*RD, Context);
   }
 
   // No other types can match.
diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h
index 26052b8086cf7..0d187eb49d6ca 100644
--- a/clang/include/clang/AST/AbstractBasicReader.h
+++ b/clang/include/clang/AST/AbstractBasicReader.h
@@ -193,7 +193,7 @@ class DataStreamBasicReader : public BasicReaderBase<Impl> {
     auto elemTy = origTy;
     unsigned pathLength = asImpl().readUInt32();
     for (unsigned i = 0; i < pathLength; ++i) {
-      if (elemTy->template getAs<RecordType>()) {
+      if (elemTy->isRecordType()) {
         unsigned int_ = asImpl().readUInt32();
         Decl *decl = asImpl().template readDeclAs<Decl>();
         if (auto *recordDecl = dyn_cast<CXXRecordDecl>(decl))
diff --git a/clang/include/clang/AST/AbstractBasicWriter.h b/clang/include/clang/AST/AbstractBasicWriter.h
index d41e655986ef9..8ea0c29cf5070 100644
--- a/clang/include/clang/AST/AbstractBasicWriter.h
+++ b/clang/include/clang/AST/AbstractBasicWriter.h
@@ -176,7 +176,7 @@ class DataStreamBasicWriter : public BasicWriterBase<Impl> {
     asImpl().writeUInt32(path.size());
     auto &ctx = ((BasicWriterBase<Impl> *)this)->getASTContext();
     for (auto elem : path) {
-      if (elemTy->getAs<RecordType>()) {
+      if (elemTy->isRecordType()) {
         asImpl().writeUInt32(elem.getAsBaseOrMember().getInt());
         const Decl *baseOrMember = elem.getAsBaseOrMember().getPointer();
         if (const auto *recordDecl = dyn_cast<CXXRecordDecl>(baseOrMember)) {
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 1d2ef0f4f2319..3ee03122f50cf 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -3825,7 +3825,9 @@ class UsingEnumDecl : public BaseUsingDecl, public Mergeable<UsingEnumDecl> {
   void setEnumType(TypeSourceInfo *TSI) { EnumType = TSI; }
 
 public:
-  EnumDecl *getEnumDecl() const { return cast<EnumDecl>(EnumType->getType()->getAsTagDecl()); }
+  EnumDecl *getEnumDecl() const {
+    return cast<clang::EnumType>(EnumType->getType())->getOriginalDecl();
+  }
 
   static UsingEnumDecl *Create(ASTContext &C, DeclContext *DC,
                                SourceLocation UsingL, SourceLocation EnumL,
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a78f5635f44da..c3fb57774c8dc 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5404,7 +5404,7 @@ class Sema final : public SemaBase {
 
   /// FinalizeVarWithDestructor - Prepare for calling destructor on the
   /// constructed variable.
-  void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType);
+  void FinalizeVarWithDestructor(VarDecl *VD, CXXRecordDecl *DeclInit);
 
   /// Helper class that collects exception specifications for
   /// implicitly-declared special member functions.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index bbb957067c4c8..036df53063568 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -654,9 +654,9 @@ comments::FullComment *ASTContext::getCommentForDecl(
       // does not have one of its own.
       QualType QT = TD->getUnderlyingType();
       if (const auto *TT = QT->getAs<TagType>())
-        if (const Decl *TD = TT->getOriginalDecl())
-          if (comments::FullComment *FC = getCommentForDecl(TD, PP))
-            return cloneFullComment(FC, D);
+        if (comments::FullComment *FC =
+                getCommentForDecl(TT->getOriginalDecl(), PP))
+          return cloneFullComment(FC, D);
     }
     else if (const auto *IC = dyn_cast<ObjCInterfaceDecl>(D)) {
       while (IC->getSuperClass()) {
@@ -1933,12 +1933,9 @@ 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<RecordType>()) {
-      const auto *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (!RD->isInvalidDecl()) {
-        const ASTRecordLayout &layout = getASTRecordLayout(RD);
-        Info.Width = layout.getDataSize();
-      }
+    if (const auto *RD = T->getAsCXXRecordDecl(); RD && !RD->isInvalidDecl()) {
+      const ASTRecordLayout &layout = getASTRecordLayout(RD);
+      Info.Width = layout.getDataSize();
     }
   }
 
@@ -2694,9 +2691,7 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
   if (!Target->allowsLargerPreferedTypeAlignment())
     return ABIAlign;
 
-  if (const auto *RT = T->getAs<RecordType>()) {
-    const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-
+  if (const auto *RD = T->getAsRecordDecl()) {
     // 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
     // 'packed' case is already taken into consideration when computing the
@@ -2887,12 +2882,10 @@ structHasUniqueObjectRepresentations(const ASTContext &Context,
 static std::optional<int64_t>
 getSubobjectSizeInBits(const FieldDecl *Field, const ASTContext &Context,
                        bool CheckIfTriviallyCopyable) {
-  if (Field->getType()->isRecordType()) {
-    const RecordDecl *RD = Field->getType()->getAsRecordDecl();
-    if (!RD->isUnion())
-      return structHasUniqueObjectRepresentations(Context, RD,
-                                                  CheckIfTriviallyCopyable);
-  }
+  if (const auto *RD = Field->getType()->getAsRecordDecl();
+      RD && !RD->isUnion())
+    return structHasUniqueObjectRepresentations(Context, RD,
+                                                CheckIfTriviallyCopyable);
 
   // A _BitInt type may not be unique if it has padding bits
   // but if it is a bitfield the padding bits are not used.
@@ -3047,10 +3040,7 @@ bool ASTContext::hasUniqueObjectRepresentations(
   if (const auto *MPT = Ty->getAs<MemberPointerType>())
     return !ABI->getMemberPointerInfo(MPT).HasPadding;
 
-  if (Ty->isRecordType()) {
-    const RecordDecl *Record =
-        Ty->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
-
+  if (const auto *Record = Ty->getAsRecordDecl()) {
     if (Record->isInvalidDecl())
       return false;
 
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 6d83de384ee10..1292c30d47589 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -878,10 +878,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
       // Treat the enumeration as its underlying type and use the builtin type
       // class comparison.
       if (T1->getTypeClass() == Type::Enum) {
-        T1 = T1->getAs<EnumType>()->getOriginalDecl()->getIntegerType();
+        T1 = cast<EnumType>(T1)->getOriginalDecl()->getIntegerType();
         assert(T2->isBuiltinType() && !T1.isNull()); // Sanity check
       } else if (T2->getTypeClass() == Type::Enum) {
-        T2 = T2->getAs<EnumType>()->getOriginalDecl()->getIntegerType();
+        T2 = cast<EnumType>(T2)->getOriginalDecl()->getIntegerType();
         assert(T1->isBuiltinType() && !T2.isNull()); // Sanity check
       }
       TC = Type::Builtin;
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 2e28814abfddb..e245f24e614e5 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -3303,11 +3303,8 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
     switch (Node.getKind()) {
     case OffsetOfNode::Field: {
       const FieldDecl *MemberDecl = Node.getField();
-      const RecordType *RT = CurrentType->getAs<RecordType>();
-      if (!RT)
-        return false;
-      const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (RD->isInvalidDecl())
+      const auto *RD = CurrentType->getAsRecordDecl();
+      if (!RD || RD->isInvalidDecl())
         return false;
       const ASTRecordLayout &RL = S.getASTContext().getASTRecordLayout(RD);
       unsigned FieldIndex = MemberDecl->getFieldIndex();
@@ -3336,23 +3333,19 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
         return false;
 
       // Find the layout of the class whose base we are looking into.
-      const RecordType *RT = CurrentType->getAs<RecordType>();
-      if (!RT)
-        return false;
-      const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (RD->isInvalidDecl())
+      const auto *RD = CurrentType->getAsCXXRecordDecl();
+      if (!RD || RD->isInvalidDecl())
         return false;
       const ASTRecordLayout &RL = S.getASTContext().getASTRecordLayout(RD);
 
       // Find the base class itself.
       CurrentType = BaseSpec->getType();
-      const RecordType *BaseRT = CurrentType->getAs<RecordType>();
-      if (!BaseRT)
+      const auto *BaseRD = CurrentType->getAsCXXRecordDecl();
+      if (!BaseRD)
         return false;
 
       // Add the offset to the base.
-      Result += RL.getBaseClassOffset(cast<CXXRecordDecl>(
-          BaseRT->getOriginalDecl()->getDefinitionOrSelf()));
+      Result += RL.getBaseClassOffset(BaseRD);
       break;
     }
     case OffsetOfNode::Identifier:
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index 5d72044af969e..139cae7afc87e 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -332,10 +332,9 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
         continue;
 
       // In error cases, the base might not be a RecordType.
-      const auto *RT = Spec.getType()->getAs<RecordType>();
-      if (!RT)
+      const auto *BD = Spec.getType()->getAsCXXRecordDecl();
+      if (!BD)
         return nullptr;
-      const RecordDecl *BD = RT->getOriginalDecl()->getDefinitionOrSelf();
       const Record *BR = getOrCreateRecord(BD);
 
       const Descriptor *Desc = GetBaseDesc(BD, BR);
@@ -408,9 +407,8 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
                                       const Expr *Init) {
 
   // Classes and structures.
-  if (const auto *RT = Ty->getAs<RecordType>()) {
-    if (const auto *Record =
-            getOrCreateRecord(RT->getOriginalDecl()->getDefinitionOrSelf()))
+  if (const auto *RD = Ty->getAsRecordDecl()) {
+    if (const auto *Record = getOrCreateRecord(RD))
       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 a7934ccb4e55e..c20ec184f34f4 100644
--- a/clang/lib/AST/ByteCode/Record.cpp
+++ b/clang/lib/AST/ByteCode/Record.cpp
@@ -50,10 +50,8 @@ const Record::Base *Record::getBase(const RecordDecl *FD) const {
 }
 
 const Record::Base *Record::getBase(QualType T) const {
-  if (auto *RT = T->getAs<RecordType>()) {
-    const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+  if (auto *RD = T->getAsCXXRecordDecl())
     return BaseMap.lookup(RD);
-  }
   return nullptr;
 }
 
diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp
index e4b77edc063dc..0ced210900b1a 100644
--- a/clang/lib/AST/CXXInheritance.cpp
+++ b/clang/lib/AST/CXXInheritance.cpp
@@ -128,17 +128,11 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches) const {
   const CXXRecordDecl *Record = this;
   while (true) {
     for (const auto &I : Record->bases()) {
-      const RecordType *Ty = I.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = I.getType()->getAsCXXRecordDecl();
+      if (!Base || !(Base->isBeingDefined() || Base->isCompleteDefinition()))
         return false;
-
-      CXXRecordDecl *Base = cast_if_present<CXXRecordDecl>(
-          Ty->getOriginalDecl()->getDefinition());
-      if (!Base ||
-          (Base->isDependentContext() &&
-           !Base->isCurrentInstantiation(Record))) {
+      if (Base->isDependentContext() && !Base->isCurrentInstantiation(Record))
         return false;
-      }
 
       Queue.push_back(Base);
       if (!BaseMatches(Base))
@@ -255,9 +249,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
         const TemplateSpecializationType *TST =
             BaseSpec.getType()->getAs<TemplateSpecializationType>();
         if (!TST) {
-          if (auto *RT = BaseSpec.getType()->getAs<RecordType>())
-            BaseRecord = cast<CXXRecordDecl>(RT->getOriginalDecl())
-                             ->getDefinitionOrSelf();
+          BaseRecord = BaseSpec.getType()->getAsCXXRecordDecl();
         } else {
           TemplateName TN = TST->getTemplateName();
           if (auto *TD =
@@ -347,11 +339,8 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches,
       // base is a subobject of any other path; if so, then the
       // declaration in this path are hidden by that patch.
       for (const CXXBasePath &HidingP : Paths) {
-        CXXRecordDecl *HidingClass = nullptr;
-        if (const RecordType *Record =
-                HidingP.back().Base->getType()->getAs<RecordType>())
-          HidingClass = cast<CXXRecordDecl>(Record->getOriginalDecl())
-                            ->getDefinitionOrSelf();
+        auto *HidingClass =
+            HidingP.back().Base->getType()->getAsCXXRecordDecl();
         if (!HidingClass)
           break;
 
@@ -470,9 +459,7 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
       = ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())];
 
   for (const auto &Base : RD->bases()) {
-    if (const RecordType *RT = Base.getType()->getAs<RecordType>()) {
-      const CXXRecordDecl *BaseDecl =
-          cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
+    if (const auto *BaseDecl = Base.getType()->getAsCXXRecordDecl()) {
       if (!BaseDecl->isPolymorphic())
         continue;
 
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 4507f415ce606..c44bf739dca2d 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2861,9 +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<RecordType>();
-  if (!Ty ||
-      !Ty->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
+  auto *D = getType()->getAsRecordDecl();
+  if (!D || !D->hasFlexibleArrayMember())
     return false;
   auto *List = dyn_cast<InitListExpr>(getInit()->IgnoreParens());
   if (!List)
@@ -2877,11 +2876,8 @@ bool VarDecl::hasFlexibleArrayInit(const ASTContext &Ctx) const {
 
 CharUnits VarDecl::getFlexibleArrayInitChars(const ASTContext &Ctx) const {
   assert(hasInit() && "Expect initializer to check for flexible a...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Aug 25, 2025

@llvm/pr-subscribers-backend-x86

Author: Matheus Izvekov (mizvekov)

Changes

This changes a bunch of places which use getAs<TagType>, including derived types, just to obtain the tag definition.

This is preparation for #155028, offloading all the changes that PR used to introduce which don't depend on any new helpers.


Patch is 172.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/155313.diff

100 Files Affected:

  • (modified) clang-tools-extra/clang-doc/Serialize.cpp (+2-3)
  • (modified) clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp (+2-3)
  • (modified) clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp (+9-14)
  • (modified) clang-tools-extra/clang-tidy/utils/TypeTraits.cpp (+2-3)
  • (modified) clang/include/clang/AST/AbstractBasicReader.h (+1-1)
  • (modified) clang/include/clang/AST/AbstractBasicWriter.h (+1-1)
  • (modified) clang/include/clang/AST/DeclCXX.h (+3-1)
  • (modified) clang/include/clang/Sema/Sema.h (+1-1)
  • (modified) clang/lib/AST/ASTContext.cpp (+12-22)
  • (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+2-2)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+7-14)
  • (modified) clang/lib/AST/ByteCode/Program.cpp (+4-6)
  • (modified) clang/lib/AST/ByteCode/Record.cpp (+1-3)
  • (modified) clang/lib/AST/CXXInheritance.cpp (+7-20)
  • (modified) clang/lib/AST/Decl.cpp (+7-13)
  • (modified) clang/lib/AST/DeclCXX.cpp (+13-18)
  • (modified) clang/lib/AST/DeclTemplate.cpp (+3-3)
  • (modified) clang/lib/AST/ExprConstant.cpp (+7-10)
  • (modified) clang/lib/AST/FormatString.cpp (+1-1)
  • (modified) clang/lib/AST/ItaniumMangle.cpp (+4-4)
  • (modified) clang/lib/AST/RecordLayoutBuilder.cpp (+11-15)
  • (modified) clang/lib/AST/Type.cpp (+41-56)
  • (modified) clang/lib/Analysis/ExprMutationAnalyzer.cpp (+2-1)
  • (modified) clang/lib/Analysis/ThreadSafetyCommon.cpp (+5-7)
  • (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+4-10)
  • (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+1-1)
  • (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+5-14)
  • (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+1-2)
  • (modified) clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp (+3-2)
  • (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+3-6)
  • (modified) clang/lib/CIR/CodeGen/TargetInfo.cpp (+2-4)
  • (modified) clang/lib/CodeGen/ABIInfo.cpp (+1-2)
  • (modified) clang/lib/CodeGen/ABIInfoImpl.cpp (+13-20)
  • (modified) clang/lib/CodeGen/CGBlocks.cpp (+3-6)
  • (modified) clang/lib/CodeGen/CGBuiltin.cpp (+4-5)
  • (modified) clang/lib/CodeGen/CGCXXABI.cpp (+1-4)
  • (modified) clang/lib/CodeGen/CGCall.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CGClass.cpp (+4-10)
  • (modified) clang/lib/CodeGen/CGDecl.cpp (+3-4)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+5-8)
  • (modified) clang/lib/CodeGen/CGExprAgg.cpp (+7-12)
  • (modified) clang/lib/CodeGen/CGExprCXX.cpp (+1-3)
  • (modified) clang/lib/CodeGen/CGExprConstant.cpp (+5-8)
  • (modified) clang/lib/CodeGen/CGObjC.cpp (+2-4)
  • (modified) clang/lib/CodeGen/CGObjCMac.cpp (+2-3)
  • (modified) clang/lib/CodeGen/CGObjCRuntime.cpp (+2-4)
  • (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+3-8)
  • (modified) clang/lib/CodeGen/CodeGenFunction.h (+1-3)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+2-3)
  • (modified) clang/lib/CodeGen/CodeGenTypes.cpp (+5-7)
  • (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+12-15)
  • (modified) clang/lib/CodeGen/Targets/AArch64.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/AMDGPU.cpp (+7-12)
  • (modified) clang/lib/CodeGen/Targets/ARM.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/CSKY.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/NVPTX.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/PPC.cpp (+1-4)
  • (modified) clang/lib/CodeGen/Targets/SPIR.cpp (+7-12)
  • (modified) clang/lib/CodeGen/Targets/SystemZ.cpp (+2-4)
  • (modified) clang/lib/CodeGen/Targets/X86.cpp (+10-15)
  • (modified) clang/lib/Edit/RewriteObjCFoundationAPI.cpp (+1-1)
  • (modified) clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp (+1-9)
  • (modified) clang/lib/Interpreter/Value.cpp (+6-9)
  • (modified) clang/lib/Sema/Sema.cpp (+15-18)
  • (modified) clang/lib/Sema/SemaAccess.cpp (+2-4)
  • (modified) clang/lib/Sema/SemaCUDA.cpp (+5-12)
  • (modified) clang/lib/Sema/SemaCast.cpp (+9-11)
  • (modified) clang/lib/Sema/SemaChecking.cpp (+5-12)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+69-91)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+24-30)
  • (modified) clang/lib/Sema/SemaDeclCXX.cpp (+21-38)
  • (modified) clang/lib/Sema/SemaDeclObjC.cpp (+9-18)
  • (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+2-3)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+18-28)
  • (modified) clang/lib/Sema/SemaExprCXX.cpp (+4-9)
  • (modified) clang/lib/Sema/SemaHLSL.cpp (+5-10)
  • (modified) clang/lib/Sema/SemaInit.cpp (+63-75)
  • (modified) clang/lib/Sema/SemaLookup.cpp (+4-7)
  • (modified) clang/lib/Sema/SemaObjCProperty.cpp (+2-4)
  • (modified) clang/lib/Sema/SemaOverload.cpp (+11-12)
  • (modified) clang/lib/Sema/SemaStmtAsm.cpp (+3-4)
  • (modified) clang/lib/Sema/SemaSwift.cpp (+7-9)
  • (modified) clang/lib/Sema/SemaTemplate.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+2-2)
  • (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+5-9)
  • (modified) clang/lib/Sema/SemaType.cpp (+3-8)
  • (modified) clang/lib/Sema/SemaTypeTraits.cpp (+5-7)
  • (modified) clang/lib/Sema/TreeTransform.h (+11-20)
  • (modified) clang/lib/Sema/UsedDeclVisitor.h (+4-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp (+2-3)
  • (modified) clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp (+5-11)
  • (modified) clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp (+3-3)
  • (modified) clang/lib/StaticAnalyzer/Core/ExprEngine.cpp (+1-1)
  • (modified) clang/tools/libclang/CIndex.cpp (+1-1)
  • (modified) clang/unittests/AST/ASTImporterTest.cpp (+1-3)
  • (modified) clang/unittests/AST/RandstructTest.cpp (+1-2)
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index bcab4f1b8a729..506cc0a3b0e8f 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -901,9 +901,8 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
   if (!D->isThisDeclarationADefinition())
     return;
   for (const CXXBaseSpecifier &B : D->bases()) {
-    if (const RecordType *Ty = B.getType()->getAs<RecordType>()) {
-      if (const CXXRecordDecl *Base = cast_or_null<CXXRecordDecl>(
-              Ty->getOriginalDecl()->getDefinition())) {
+    if (const auto *Base = B.getType()->getAsCXXRecordDecl()) {
+      if (Base->isCompleteDefinition()) {
         // 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/cert/DefaultOperatorNewAlignmentCheck.cpp b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
index 2a0d0ada42b28..2c2248afb69e7 100644
--- a/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
@@ -31,7 +31,7 @@ void DefaultOperatorNewAlignmentCheck::check(
     return;
   const TagDecl *D = T->getAsTagDecl();
   // Alignment can not be obtained for undefined type.
-  if (!D || !D->getDefinition() || !D->isCompleteDefinition())
+  if (!D || !D->isCompleteDefinition())
     return;
 
   ASTContext &Context = D->getASTContext();
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
index 40fd15c08f0a1..6508bfd5ca808 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
@@ -90,9 +90,8 @@ void SlicingCheck::diagnoseSlicedOverriddenMethods(
   }
   // Recursively process bases.
   for (const auto &Base : DerivedDecl.bases()) {
-    if (const auto *BaseRecordType = Base.getType()->getAs<RecordType>()) {
-      if (const auto *BaseRecord = cast_or_null<CXXRecordDecl>(
-              BaseRecordType->getOriginalDecl()->getDefinition()))
+    if (const auto *BaseRecord = Base.getType()->getAsCXXRecordDecl()) {
+      if (BaseRecord->isCompleteDefinition())
         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 0302a5ad4957c..36b6007b58a51 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
@@ -71,13 +71,10 @@ bool MultipleInheritanceCheck::isInterface(const CXXRecordDecl *Node) {
   for (const auto &I : Node->bases()) {
     if (I.isVirtual())
       continue;
-    const auto *Ty = I.getType()->getAs<RecordType>();
-    if (!Ty)
+    const auto *Base = I.getType()->getAsCXXRecordDecl();
+    if (!Base)
       continue;
-    const RecordDecl *D = Ty->getOriginalDecl()->getDefinition();
-    if (!D)
-      continue;
-    const auto *Base = cast<CXXRecordDecl>(D);
+    assert(Base->isCompleteDefinition());
     if (!isInterface(Base)) {
       addNodeToInterfaceMap(Node, false);
       return false;
@@ -103,11 +100,10 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
     for (const auto &I : D->bases()) {
       if (I.isVirtual())
         continue;
-      const auto *Ty = I.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = I.getType()->getAsCXXRecordDecl();
+      if (!Base)
         continue;
-      const auto *Base =
-          cast<CXXRecordDecl>(Ty->getOriginalDecl()->getDefinition());
+      assert(Base->isCompleteDefinition());
       if (!isInterface(Base))
         NumConcrete++;
     }
@@ -115,11 +111,10 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
     // Check virtual bases to see if there is more than one concrete
     // non-virtual base.
     for (const auto &V : D->vbases()) {
-      const auto *Ty = V.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = V.getType()->getAsCXXRecordDecl();
+      if (!Base)
         continue;
-      const auto *Base =
-          cast<CXXRecordDecl>(Ty->getOriginalDecl()->getDefinition());
+      assert(Base->isCompleteDefinition());
       if (!isInterface(Base))
         NumConcrete++;
     }
diff --git a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
index 5518afd32e7f0..f944306171135 100644
--- a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
+++ b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
@@ -119,9 +119,8 @@ bool isTriviallyDefaultConstructible(QualType Type, const ASTContext &Context) {
   if (CanonicalType->isScalarType() || CanonicalType->isVectorType())
     return true;
 
-  if (const auto *RT = CanonicalType->getAs<RecordType>()) {
-    return recordIsTriviallyDefaultConstructible(
-        *RT->getOriginalDecl()->getDefinitionOrSelf(), Context);
+  if (const auto *RD = CanonicalType->getAsRecordDecl()) {
+    return recordIsTriviallyDefaultConstructible(*RD, Context);
   }
 
   // No other types can match.
diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h
index 26052b8086cf7..0d187eb49d6ca 100644
--- a/clang/include/clang/AST/AbstractBasicReader.h
+++ b/clang/include/clang/AST/AbstractBasicReader.h
@@ -193,7 +193,7 @@ class DataStreamBasicReader : public BasicReaderBase<Impl> {
     auto elemTy = origTy;
     unsigned pathLength = asImpl().readUInt32();
     for (unsigned i = 0; i < pathLength; ++i) {
-      if (elemTy->template getAs<RecordType>()) {
+      if (elemTy->isRecordType()) {
         unsigned int_ = asImpl().readUInt32();
         Decl *decl = asImpl().template readDeclAs<Decl>();
         if (auto *recordDecl = dyn_cast<CXXRecordDecl>(decl))
diff --git a/clang/include/clang/AST/AbstractBasicWriter.h b/clang/include/clang/AST/AbstractBasicWriter.h
index d41e655986ef9..8ea0c29cf5070 100644
--- a/clang/include/clang/AST/AbstractBasicWriter.h
+++ b/clang/include/clang/AST/AbstractBasicWriter.h
@@ -176,7 +176,7 @@ class DataStreamBasicWriter : public BasicWriterBase<Impl> {
     asImpl().writeUInt32(path.size());
     auto &ctx = ((BasicWriterBase<Impl> *)this)->getASTContext();
     for (auto elem : path) {
-      if (elemTy->getAs<RecordType>()) {
+      if (elemTy->isRecordType()) {
         asImpl().writeUInt32(elem.getAsBaseOrMember().getInt());
         const Decl *baseOrMember = elem.getAsBaseOrMember().getPointer();
         if (const auto *recordDecl = dyn_cast<CXXRecordDecl>(baseOrMember)) {
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 1d2ef0f4f2319..3ee03122f50cf 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -3825,7 +3825,9 @@ class UsingEnumDecl : public BaseUsingDecl, public Mergeable<UsingEnumDecl> {
   void setEnumType(TypeSourceInfo *TSI) { EnumType = TSI; }
 
 public:
-  EnumDecl *getEnumDecl() const { return cast<EnumDecl>(EnumType->getType()->getAsTagDecl()); }
+  EnumDecl *getEnumDecl() const {
+    return cast<clang::EnumType>(EnumType->getType())->getOriginalDecl();
+  }
 
   static UsingEnumDecl *Create(ASTContext &C, DeclContext *DC,
                                SourceLocation UsingL, SourceLocation EnumL,
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a78f5635f44da..c3fb57774c8dc 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5404,7 +5404,7 @@ class Sema final : public SemaBase {
 
   /// FinalizeVarWithDestructor - Prepare for calling destructor on the
   /// constructed variable.
-  void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType);
+  void FinalizeVarWithDestructor(VarDecl *VD, CXXRecordDecl *DeclInit);
 
   /// Helper class that collects exception specifications for
   /// implicitly-declared special member functions.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index bbb957067c4c8..036df53063568 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -654,9 +654,9 @@ comments::FullComment *ASTContext::getCommentForDecl(
       // does not have one of its own.
       QualType QT = TD->getUnderlyingType();
       if (const auto *TT = QT->getAs<TagType>())
-        if (const Decl *TD = TT->getOriginalDecl())
-          if (comments::FullComment *FC = getCommentForDecl(TD, PP))
-            return cloneFullComment(FC, D);
+        if (comments::FullComment *FC =
+                getCommentForDecl(TT->getOriginalDecl(), PP))
+          return cloneFullComment(FC, D);
     }
     else if (const auto *IC = dyn_cast<ObjCInterfaceDecl>(D)) {
       while (IC->getSuperClass()) {
@@ -1933,12 +1933,9 @@ 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<RecordType>()) {
-      const auto *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (!RD->isInvalidDecl()) {
-        const ASTRecordLayout &layout = getASTRecordLayout(RD);
-        Info.Width = layout.getDataSize();
-      }
+    if (const auto *RD = T->getAsCXXRecordDecl(); RD && !RD->isInvalidDecl()) {
+      const ASTRecordLayout &layout = getASTRecordLayout(RD);
+      Info.Width = layout.getDataSize();
     }
   }
 
@@ -2694,9 +2691,7 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
   if (!Target->allowsLargerPreferedTypeAlignment())
     return ABIAlign;
 
-  if (const auto *RT = T->getAs<RecordType>()) {
-    const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-
+  if (const auto *RD = T->getAsRecordDecl()) {
     // 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
     // 'packed' case is already taken into consideration when computing the
@@ -2887,12 +2882,10 @@ structHasUniqueObjectRepresentations(const ASTContext &Context,
 static std::optional<int64_t>
 getSubobjectSizeInBits(const FieldDecl *Field, const ASTContext &Context,
                        bool CheckIfTriviallyCopyable) {
-  if (Field->getType()->isRecordType()) {
-    const RecordDecl *RD = Field->getType()->getAsRecordDecl();
-    if (!RD->isUnion())
-      return structHasUniqueObjectRepresentations(Context, RD,
-                                                  CheckIfTriviallyCopyable);
-  }
+  if (const auto *RD = Field->getType()->getAsRecordDecl();
+      RD && !RD->isUnion())
+    return structHasUniqueObjectRepresentations(Context, RD,
+                                                CheckIfTriviallyCopyable);
 
   // A _BitInt type may not be unique if it has padding bits
   // but if it is a bitfield the padding bits are not used.
@@ -3047,10 +3040,7 @@ bool ASTContext::hasUniqueObjectRepresentations(
   if (const auto *MPT = Ty->getAs<MemberPointerType>())
     return !ABI->getMemberPointerInfo(MPT).HasPadding;
 
-  if (Ty->isRecordType()) {
-    const RecordDecl *Record =
-        Ty->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
-
+  if (const auto *Record = Ty->getAsRecordDecl()) {
     if (Record->isInvalidDecl())
       return false;
 
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 6d83de384ee10..1292c30d47589 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -878,10 +878,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
       // Treat the enumeration as its underlying type and use the builtin type
       // class comparison.
       if (T1->getTypeClass() == Type::Enum) {
-        T1 = T1->getAs<EnumType>()->getOriginalDecl()->getIntegerType();
+        T1 = cast<EnumType>(T1)->getOriginalDecl()->getIntegerType();
         assert(T2->isBuiltinType() && !T1.isNull()); // Sanity check
       } else if (T2->getTypeClass() == Type::Enum) {
-        T2 = T2->getAs<EnumType>()->getOriginalDecl()->getIntegerType();
+        T2 = cast<EnumType>(T2)->getOriginalDecl()->getIntegerType();
         assert(T1->isBuiltinType() && !T2.isNull()); // Sanity check
       }
       TC = Type::Builtin;
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 2e28814abfddb..e245f24e614e5 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -3303,11 +3303,8 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
     switch (Node.getKind()) {
     case OffsetOfNode::Field: {
       const FieldDecl *MemberDecl = Node.getField();
-      const RecordType *RT = CurrentType->getAs<RecordType>();
-      if (!RT)
-        return false;
-      const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (RD->isInvalidDecl())
+      const auto *RD = CurrentType->getAsRecordDecl();
+      if (!RD || RD->isInvalidDecl())
         return false;
       const ASTRecordLayout &RL = S.getASTContext().getASTRecordLayout(RD);
       unsigned FieldIndex = MemberDecl->getFieldIndex();
@@ -3336,23 +3333,19 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
         return false;
 
       // Find the layout of the class whose base we are looking into.
-      const RecordType *RT = CurrentType->getAs<RecordType>();
-      if (!RT)
-        return false;
-      const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (RD->isInvalidDecl())
+      const auto *RD = CurrentType->getAsCXXRecordDecl();
+      if (!RD || RD->isInvalidDecl())
         return false;
       const ASTRecordLayout &RL = S.getASTContext().getASTRecordLayout(RD);
 
       // Find the base class itself.
       CurrentType = BaseSpec->getType();
-      const RecordType *BaseRT = CurrentType->getAs<RecordType>();
-      if (!BaseRT)
+      const auto *BaseRD = CurrentType->getAsCXXRecordDecl();
+      if (!BaseRD)
         return false;
 
       // Add the offset to the base.
-      Result += RL.getBaseClassOffset(cast<CXXRecordDecl>(
-          BaseRT->getOriginalDecl()->getDefinitionOrSelf()));
+      Result += RL.getBaseClassOffset(BaseRD);
       break;
     }
     case OffsetOfNode::Identifier:
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index 5d72044af969e..139cae7afc87e 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -332,10 +332,9 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
         continue;
 
       // In error cases, the base might not be a RecordType.
-      const auto *RT = Spec.getType()->getAs<RecordType>();
-      if (!RT)
+      const auto *BD = Spec.getType()->getAsCXXRecordDecl();
+      if (!BD)
         return nullptr;
-      const RecordDecl *BD = RT->getOriginalDecl()->getDefinitionOrSelf();
       const Record *BR = getOrCreateRecord(BD);
 
       const Descriptor *Desc = GetBaseDesc(BD, BR);
@@ -408,9 +407,8 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
                                       const Expr *Init) {
 
   // Classes and structures.
-  if (const auto *RT = Ty->getAs<RecordType>()) {
-    if (const auto *Record =
-            getOrCreateRecord(RT->getOriginalDecl()->getDefinitionOrSelf()))
+  if (const auto *RD = Ty->getAsRecordDecl()) {
+    if (const auto *Record = getOrCreateRecord(RD))
       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 a7934ccb4e55e..c20ec184f34f4 100644
--- a/clang/lib/AST/ByteCode/Record.cpp
+++ b/clang/lib/AST/ByteCode/Record.cpp
@@ -50,10 +50,8 @@ const Record::Base *Record::getBase(const RecordDecl *FD) const {
 }
 
 const Record::Base *Record::getBase(QualType T) const {
-  if (auto *RT = T->getAs<RecordType>()) {
-    const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+  if (auto *RD = T->getAsCXXRecordDecl())
     return BaseMap.lookup(RD);
-  }
   return nullptr;
 }
 
diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp
index e4b77edc063dc..0ced210900b1a 100644
--- a/clang/lib/AST/CXXInheritance.cpp
+++ b/clang/lib/AST/CXXInheritance.cpp
@@ -128,17 +128,11 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches) const {
   const CXXRecordDecl *Record = this;
   while (true) {
     for (const auto &I : Record->bases()) {
-      const RecordType *Ty = I.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = I.getType()->getAsCXXRecordDecl();
+      if (!Base || !(Base->isBeingDefined() || Base->isCompleteDefinition()))
         return false;
-
-      CXXRecordDecl *Base = cast_if_present<CXXRecordDecl>(
-          Ty->getOriginalDecl()->getDefinition());
-      if (!Base ||
-          (Base->isDependentContext() &&
-           !Base->isCurrentInstantiation(Record))) {
+      if (Base->isDependentContext() && !Base->isCurrentInstantiation(Record))
         return false;
-      }
 
       Queue.push_back(Base);
       if (!BaseMatches(Base))
@@ -255,9 +249,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
         const TemplateSpecializationType *TST =
             BaseSpec.getType()->getAs<TemplateSpecializationType>();
         if (!TST) {
-          if (auto *RT = BaseSpec.getType()->getAs<RecordType>())
-            BaseRecord = cast<CXXRecordDecl>(RT->getOriginalDecl())
-                             ->getDefinitionOrSelf();
+          BaseRecord = BaseSpec.getType()->getAsCXXRecordDecl();
         } else {
           TemplateName TN = TST->getTemplateName();
           if (auto *TD =
@@ -347,11 +339,8 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches,
       // base is a subobject of any other path; if so, then the
       // declaration in this path are hidden by that patch.
       for (const CXXBasePath &HidingP : Paths) {
-        CXXRecordDecl *HidingClass = nullptr;
-        if (const RecordType *Record =
-                HidingP.back().Base->getType()->getAs<RecordType>())
-          HidingClass = cast<CXXRecordDecl>(Record->getOriginalDecl())
-                            ->getDefinitionOrSelf();
+        auto *HidingClass =
+            HidingP.back().Base->getType()->getAsCXXRecordDecl();
         if (!HidingClass)
           break;
 
@@ -470,9 +459,7 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
       = ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())];
 
   for (const auto &Base : RD->bases()) {
-    if (const RecordType *RT = Base.getType()->getAs<RecordType>()) {
-      const CXXRecordDecl *BaseDecl =
-          cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
+    if (const auto *BaseDecl = Base.getType()->getAsCXXRecordDecl()) {
       if (!BaseDecl->isPolymorphic())
         continue;
 
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 4507f415ce606..c44bf739dca2d 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2861,9 +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<RecordType>();
-  if (!Ty ||
-      !Ty->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
+  auto *D = getType()->getAsRecordDecl();
+  if (!D || !D->hasFlexibleArrayMember())
     return false;
   auto *List = dyn_cast<InitListExpr>(getInit()->IgnoreParens());
   if (!List)
@@ -2877,11 +2876,8 @@ bool VarDecl::hasFlexibleArrayInit(const ASTContext &Ctx) const {
 
 CharUnits VarDecl::getFlexibleArrayInitChars(const ASTContext &Ctx) const {
   assert(hasInit() && "Expect initializer to check for flexible a...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Aug 25, 2025

@llvm/pr-subscribers-clang-analysis

Author: Matheus Izvekov (mizvekov)

Changes

This changes a bunch of places which use getAs<TagType>, including derived types, just to obtain the tag definition.

This is preparation for #155028, offloading all the changes that PR used to introduce which don't depend on any new helpers.


Patch is 172.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/155313.diff

100 Files Affected:

  • (modified) clang-tools-extra/clang-doc/Serialize.cpp (+2-3)
  • (modified) clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp (+2-3)
  • (modified) clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp (+9-14)
  • (modified) clang-tools-extra/clang-tidy/utils/TypeTraits.cpp (+2-3)
  • (modified) clang/include/clang/AST/AbstractBasicReader.h (+1-1)
  • (modified) clang/include/clang/AST/AbstractBasicWriter.h (+1-1)
  • (modified) clang/include/clang/AST/DeclCXX.h (+3-1)
  • (modified) clang/include/clang/Sema/Sema.h (+1-1)
  • (modified) clang/lib/AST/ASTContext.cpp (+12-22)
  • (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+2-2)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+7-14)
  • (modified) clang/lib/AST/ByteCode/Program.cpp (+4-6)
  • (modified) clang/lib/AST/ByteCode/Record.cpp (+1-3)
  • (modified) clang/lib/AST/CXXInheritance.cpp (+7-20)
  • (modified) clang/lib/AST/Decl.cpp (+7-13)
  • (modified) clang/lib/AST/DeclCXX.cpp (+13-18)
  • (modified) clang/lib/AST/DeclTemplate.cpp (+3-3)
  • (modified) clang/lib/AST/ExprConstant.cpp (+7-10)
  • (modified) clang/lib/AST/FormatString.cpp (+1-1)
  • (modified) clang/lib/AST/ItaniumMangle.cpp (+4-4)
  • (modified) clang/lib/AST/RecordLayoutBuilder.cpp (+11-15)
  • (modified) clang/lib/AST/Type.cpp (+41-56)
  • (modified) clang/lib/Analysis/ExprMutationAnalyzer.cpp (+2-1)
  • (modified) clang/lib/Analysis/ThreadSafetyCommon.cpp (+5-7)
  • (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+4-10)
  • (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+1-1)
  • (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+5-14)
  • (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+1-2)
  • (modified) clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp (+3-2)
  • (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+3-6)
  • (modified) clang/lib/CIR/CodeGen/TargetInfo.cpp (+2-4)
  • (modified) clang/lib/CodeGen/ABIInfo.cpp (+1-2)
  • (modified) clang/lib/CodeGen/ABIInfoImpl.cpp (+13-20)
  • (modified) clang/lib/CodeGen/CGBlocks.cpp (+3-6)
  • (modified) clang/lib/CodeGen/CGBuiltin.cpp (+4-5)
  • (modified) clang/lib/CodeGen/CGCXXABI.cpp (+1-4)
  • (modified) clang/lib/CodeGen/CGCall.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CGClass.cpp (+4-10)
  • (modified) clang/lib/CodeGen/CGDecl.cpp (+3-4)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+5-8)
  • (modified) clang/lib/CodeGen/CGExprAgg.cpp (+7-12)
  • (modified) clang/lib/CodeGen/CGExprCXX.cpp (+1-3)
  • (modified) clang/lib/CodeGen/CGExprConstant.cpp (+5-8)
  • (modified) clang/lib/CodeGen/CGObjC.cpp (+2-4)
  • (modified) clang/lib/CodeGen/CGObjCMac.cpp (+2-3)
  • (modified) clang/lib/CodeGen/CGObjCRuntime.cpp (+2-4)
  • (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+3-8)
  • (modified) clang/lib/CodeGen/CodeGenFunction.h (+1-3)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+2-3)
  • (modified) clang/lib/CodeGen/CodeGenTypes.cpp (+5-7)
  • (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+12-15)
  • (modified) clang/lib/CodeGen/Targets/AArch64.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/AMDGPU.cpp (+7-12)
  • (modified) clang/lib/CodeGen/Targets/ARM.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/CSKY.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/NVPTX.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/PPC.cpp (+1-4)
  • (modified) clang/lib/CodeGen/Targets/SPIR.cpp (+7-12)
  • (modified) clang/lib/CodeGen/Targets/SystemZ.cpp (+2-4)
  • (modified) clang/lib/CodeGen/Targets/X86.cpp (+10-15)
  • (modified) clang/lib/Edit/RewriteObjCFoundationAPI.cpp (+1-1)
  • (modified) clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp (+1-9)
  • (modified) clang/lib/Interpreter/Value.cpp (+6-9)
  • (modified) clang/lib/Sema/Sema.cpp (+15-18)
  • (modified) clang/lib/Sema/SemaAccess.cpp (+2-4)
  • (modified) clang/lib/Sema/SemaCUDA.cpp (+5-12)
  • (modified) clang/lib/Sema/SemaCast.cpp (+9-11)
  • (modified) clang/lib/Sema/SemaChecking.cpp (+5-12)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+69-91)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+24-30)
  • (modified) clang/lib/Sema/SemaDeclCXX.cpp (+21-38)
  • (modified) clang/lib/Sema/SemaDeclObjC.cpp (+9-18)
  • (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+2-3)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+18-28)
  • (modified) clang/lib/Sema/SemaExprCXX.cpp (+4-9)
  • (modified) clang/lib/Sema/SemaHLSL.cpp (+5-10)
  • (modified) clang/lib/Sema/SemaInit.cpp (+63-75)
  • (modified) clang/lib/Sema/SemaLookup.cpp (+4-7)
  • (modified) clang/lib/Sema/SemaObjCProperty.cpp (+2-4)
  • (modified) clang/lib/Sema/SemaOverload.cpp (+11-12)
  • (modified) clang/lib/Sema/SemaStmtAsm.cpp (+3-4)
  • (modified) clang/lib/Sema/SemaSwift.cpp (+7-9)
  • (modified) clang/lib/Sema/SemaTemplate.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+2-2)
  • (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+5-9)
  • (modified) clang/lib/Sema/SemaType.cpp (+3-8)
  • (modified) clang/lib/Sema/SemaTypeTraits.cpp (+5-7)
  • (modified) clang/lib/Sema/TreeTransform.h (+11-20)
  • (modified) clang/lib/Sema/UsedDeclVisitor.h (+4-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp (+2-3)
  • (modified) clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp (+5-11)
  • (modified) clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp (+3-3)
  • (modified) clang/lib/StaticAnalyzer/Core/ExprEngine.cpp (+1-1)
  • (modified) clang/tools/libclang/CIndex.cpp (+1-1)
  • (modified) clang/unittests/AST/ASTImporterTest.cpp (+1-3)
  • (modified) clang/unittests/AST/RandstructTest.cpp (+1-2)
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index bcab4f1b8a729..506cc0a3b0e8f 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -901,9 +901,8 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
   if (!D->isThisDeclarationADefinition())
     return;
   for (const CXXBaseSpecifier &B : D->bases()) {
-    if (const RecordType *Ty = B.getType()->getAs<RecordType>()) {
-      if (const CXXRecordDecl *Base = cast_or_null<CXXRecordDecl>(
-              Ty->getOriginalDecl()->getDefinition())) {
+    if (const auto *Base = B.getType()->getAsCXXRecordDecl()) {
+      if (Base->isCompleteDefinition()) {
         // 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/cert/DefaultOperatorNewAlignmentCheck.cpp b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
index 2a0d0ada42b28..2c2248afb69e7 100644
--- a/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
@@ -31,7 +31,7 @@ void DefaultOperatorNewAlignmentCheck::check(
     return;
   const TagDecl *D = T->getAsTagDecl();
   // Alignment can not be obtained for undefined type.
-  if (!D || !D->getDefinition() || !D->isCompleteDefinition())
+  if (!D || !D->isCompleteDefinition())
     return;
 
   ASTContext &Context = D->getASTContext();
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
index 40fd15c08f0a1..6508bfd5ca808 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
@@ -90,9 +90,8 @@ void SlicingCheck::diagnoseSlicedOverriddenMethods(
   }
   // Recursively process bases.
   for (const auto &Base : DerivedDecl.bases()) {
-    if (const auto *BaseRecordType = Base.getType()->getAs<RecordType>()) {
-      if (const auto *BaseRecord = cast_or_null<CXXRecordDecl>(
-              BaseRecordType->getOriginalDecl()->getDefinition()))
+    if (const auto *BaseRecord = Base.getType()->getAsCXXRecordDecl()) {
+      if (BaseRecord->isCompleteDefinition())
         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 0302a5ad4957c..36b6007b58a51 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
@@ -71,13 +71,10 @@ bool MultipleInheritanceCheck::isInterface(const CXXRecordDecl *Node) {
   for (const auto &I : Node->bases()) {
     if (I.isVirtual())
       continue;
-    const auto *Ty = I.getType()->getAs<RecordType>();
-    if (!Ty)
+    const auto *Base = I.getType()->getAsCXXRecordDecl();
+    if (!Base)
       continue;
-    const RecordDecl *D = Ty->getOriginalDecl()->getDefinition();
-    if (!D)
-      continue;
-    const auto *Base = cast<CXXRecordDecl>(D);
+    assert(Base->isCompleteDefinition());
     if (!isInterface(Base)) {
       addNodeToInterfaceMap(Node, false);
       return false;
@@ -103,11 +100,10 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
     for (const auto &I : D->bases()) {
       if (I.isVirtual())
         continue;
-      const auto *Ty = I.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = I.getType()->getAsCXXRecordDecl();
+      if (!Base)
         continue;
-      const auto *Base =
-          cast<CXXRecordDecl>(Ty->getOriginalDecl()->getDefinition());
+      assert(Base->isCompleteDefinition());
       if (!isInterface(Base))
         NumConcrete++;
     }
@@ -115,11 +111,10 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
     // Check virtual bases to see if there is more than one concrete
     // non-virtual base.
     for (const auto &V : D->vbases()) {
-      const auto *Ty = V.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = V.getType()->getAsCXXRecordDecl();
+      if (!Base)
         continue;
-      const auto *Base =
-          cast<CXXRecordDecl>(Ty->getOriginalDecl()->getDefinition());
+      assert(Base->isCompleteDefinition());
       if (!isInterface(Base))
         NumConcrete++;
     }
diff --git a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
index 5518afd32e7f0..f944306171135 100644
--- a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
+++ b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
@@ -119,9 +119,8 @@ bool isTriviallyDefaultConstructible(QualType Type, const ASTContext &Context) {
   if (CanonicalType->isScalarType() || CanonicalType->isVectorType())
     return true;
 
-  if (const auto *RT = CanonicalType->getAs<RecordType>()) {
-    return recordIsTriviallyDefaultConstructible(
-        *RT->getOriginalDecl()->getDefinitionOrSelf(), Context);
+  if (const auto *RD = CanonicalType->getAsRecordDecl()) {
+    return recordIsTriviallyDefaultConstructible(*RD, Context);
   }
 
   // No other types can match.
diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h
index 26052b8086cf7..0d187eb49d6ca 100644
--- a/clang/include/clang/AST/AbstractBasicReader.h
+++ b/clang/include/clang/AST/AbstractBasicReader.h
@@ -193,7 +193,7 @@ class DataStreamBasicReader : public BasicReaderBase<Impl> {
     auto elemTy = origTy;
     unsigned pathLength = asImpl().readUInt32();
     for (unsigned i = 0; i < pathLength; ++i) {
-      if (elemTy->template getAs<RecordType>()) {
+      if (elemTy->isRecordType()) {
         unsigned int_ = asImpl().readUInt32();
         Decl *decl = asImpl().template readDeclAs<Decl>();
         if (auto *recordDecl = dyn_cast<CXXRecordDecl>(decl))
diff --git a/clang/include/clang/AST/AbstractBasicWriter.h b/clang/include/clang/AST/AbstractBasicWriter.h
index d41e655986ef9..8ea0c29cf5070 100644
--- a/clang/include/clang/AST/AbstractBasicWriter.h
+++ b/clang/include/clang/AST/AbstractBasicWriter.h
@@ -176,7 +176,7 @@ class DataStreamBasicWriter : public BasicWriterBase<Impl> {
     asImpl().writeUInt32(path.size());
     auto &ctx = ((BasicWriterBase<Impl> *)this)->getASTContext();
     for (auto elem : path) {
-      if (elemTy->getAs<RecordType>()) {
+      if (elemTy->isRecordType()) {
         asImpl().writeUInt32(elem.getAsBaseOrMember().getInt());
         const Decl *baseOrMember = elem.getAsBaseOrMember().getPointer();
         if (const auto *recordDecl = dyn_cast<CXXRecordDecl>(baseOrMember)) {
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 1d2ef0f4f2319..3ee03122f50cf 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -3825,7 +3825,9 @@ class UsingEnumDecl : public BaseUsingDecl, public Mergeable<UsingEnumDecl> {
   void setEnumType(TypeSourceInfo *TSI) { EnumType = TSI; }
 
 public:
-  EnumDecl *getEnumDecl() const { return cast<EnumDecl>(EnumType->getType()->getAsTagDecl()); }
+  EnumDecl *getEnumDecl() const {
+    return cast<clang::EnumType>(EnumType->getType())->getOriginalDecl();
+  }
 
   static UsingEnumDecl *Create(ASTContext &C, DeclContext *DC,
                                SourceLocation UsingL, SourceLocation EnumL,
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a78f5635f44da..c3fb57774c8dc 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5404,7 +5404,7 @@ class Sema final : public SemaBase {
 
   /// FinalizeVarWithDestructor - Prepare for calling destructor on the
   /// constructed variable.
-  void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType);
+  void FinalizeVarWithDestructor(VarDecl *VD, CXXRecordDecl *DeclInit);
 
   /// Helper class that collects exception specifications for
   /// implicitly-declared special member functions.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index bbb957067c4c8..036df53063568 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -654,9 +654,9 @@ comments::FullComment *ASTContext::getCommentForDecl(
       // does not have one of its own.
       QualType QT = TD->getUnderlyingType();
       if (const auto *TT = QT->getAs<TagType>())
-        if (const Decl *TD = TT->getOriginalDecl())
-          if (comments::FullComment *FC = getCommentForDecl(TD, PP))
-            return cloneFullComment(FC, D);
+        if (comments::FullComment *FC =
+                getCommentForDecl(TT->getOriginalDecl(), PP))
+          return cloneFullComment(FC, D);
     }
     else if (const auto *IC = dyn_cast<ObjCInterfaceDecl>(D)) {
       while (IC->getSuperClass()) {
@@ -1933,12 +1933,9 @@ 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<RecordType>()) {
-      const auto *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (!RD->isInvalidDecl()) {
-        const ASTRecordLayout &layout = getASTRecordLayout(RD);
-        Info.Width = layout.getDataSize();
-      }
+    if (const auto *RD = T->getAsCXXRecordDecl(); RD && !RD->isInvalidDecl()) {
+      const ASTRecordLayout &layout = getASTRecordLayout(RD);
+      Info.Width = layout.getDataSize();
     }
   }
 
@@ -2694,9 +2691,7 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
   if (!Target->allowsLargerPreferedTypeAlignment())
     return ABIAlign;
 
-  if (const auto *RT = T->getAs<RecordType>()) {
-    const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-
+  if (const auto *RD = T->getAsRecordDecl()) {
     // 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
     // 'packed' case is already taken into consideration when computing the
@@ -2887,12 +2882,10 @@ structHasUniqueObjectRepresentations(const ASTContext &Context,
 static std::optional<int64_t>
 getSubobjectSizeInBits(const FieldDecl *Field, const ASTContext &Context,
                        bool CheckIfTriviallyCopyable) {
-  if (Field->getType()->isRecordType()) {
-    const RecordDecl *RD = Field->getType()->getAsRecordDecl();
-    if (!RD->isUnion())
-      return structHasUniqueObjectRepresentations(Context, RD,
-                                                  CheckIfTriviallyCopyable);
-  }
+  if (const auto *RD = Field->getType()->getAsRecordDecl();
+      RD && !RD->isUnion())
+    return structHasUniqueObjectRepresentations(Context, RD,
+                                                CheckIfTriviallyCopyable);
 
   // A _BitInt type may not be unique if it has padding bits
   // but if it is a bitfield the padding bits are not used.
@@ -3047,10 +3040,7 @@ bool ASTContext::hasUniqueObjectRepresentations(
   if (const auto *MPT = Ty->getAs<MemberPointerType>())
     return !ABI->getMemberPointerInfo(MPT).HasPadding;
 
-  if (Ty->isRecordType()) {
-    const RecordDecl *Record =
-        Ty->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
-
+  if (const auto *Record = Ty->getAsRecordDecl()) {
     if (Record->isInvalidDecl())
       return false;
 
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 6d83de384ee10..1292c30d47589 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -878,10 +878,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
       // Treat the enumeration as its underlying type and use the builtin type
       // class comparison.
       if (T1->getTypeClass() == Type::Enum) {
-        T1 = T1->getAs<EnumType>()->getOriginalDecl()->getIntegerType();
+        T1 = cast<EnumType>(T1)->getOriginalDecl()->getIntegerType();
         assert(T2->isBuiltinType() && !T1.isNull()); // Sanity check
       } else if (T2->getTypeClass() == Type::Enum) {
-        T2 = T2->getAs<EnumType>()->getOriginalDecl()->getIntegerType();
+        T2 = cast<EnumType>(T2)->getOriginalDecl()->getIntegerType();
         assert(T1->isBuiltinType() && !T2.isNull()); // Sanity check
       }
       TC = Type::Builtin;
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 2e28814abfddb..e245f24e614e5 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -3303,11 +3303,8 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
     switch (Node.getKind()) {
     case OffsetOfNode::Field: {
       const FieldDecl *MemberDecl = Node.getField();
-      const RecordType *RT = CurrentType->getAs<RecordType>();
-      if (!RT)
-        return false;
-      const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (RD->isInvalidDecl())
+      const auto *RD = CurrentType->getAsRecordDecl();
+      if (!RD || RD->isInvalidDecl())
         return false;
       const ASTRecordLayout &RL = S.getASTContext().getASTRecordLayout(RD);
       unsigned FieldIndex = MemberDecl->getFieldIndex();
@@ -3336,23 +3333,19 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
         return false;
 
       // Find the layout of the class whose base we are looking into.
-      const RecordType *RT = CurrentType->getAs<RecordType>();
-      if (!RT)
-        return false;
-      const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (RD->isInvalidDecl())
+      const auto *RD = CurrentType->getAsCXXRecordDecl();
+      if (!RD || RD->isInvalidDecl())
         return false;
       const ASTRecordLayout &RL = S.getASTContext().getASTRecordLayout(RD);
 
       // Find the base class itself.
       CurrentType = BaseSpec->getType();
-      const RecordType *BaseRT = CurrentType->getAs<RecordType>();
-      if (!BaseRT)
+      const auto *BaseRD = CurrentType->getAsCXXRecordDecl();
+      if (!BaseRD)
         return false;
 
       // Add the offset to the base.
-      Result += RL.getBaseClassOffset(cast<CXXRecordDecl>(
-          BaseRT->getOriginalDecl()->getDefinitionOrSelf()));
+      Result += RL.getBaseClassOffset(BaseRD);
       break;
     }
     case OffsetOfNode::Identifier:
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index 5d72044af969e..139cae7afc87e 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -332,10 +332,9 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
         continue;
 
       // In error cases, the base might not be a RecordType.
-      const auto *RT = Spec.getType()->getAs<RecordType>();
-      if (!RT)
+      const auto *BD = Spec.getType()->getAsCXXRecordDecl();
+      if (!BD)
         return nullptr;
-      const RecordDecl *BD = RT->getOriginalDecl()->getDefinitionOrSelf();
       const Record *BR = getOrCreateRecord(BD);
 
       const Descriptor *Desc = GetBaseDesc(BD, BR);
@@ -408,9 +407,8 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
                                       const Expr *Init) {
 
   // Classes and structures.
-  if (const auto *RT = Ty->getAs<RecordType>()) {
-    if (const auto *Record =
-            getOrCreateRecord(RT->getOriginalDecl()->getDefinitionOrSelf()))
+  if (const auto *RD = Ty->getAsRecordDecl()) {
+    if (const auto *Record = getOrCreateRecord(RD))
       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 a7934ccb4e55e..c20ec184f34f4 100644
--- a/clang/lib/AST/ByteCode/Record.cpp
+++ b/clang/lib/AST/ByteCode/Record.cpp
@@ -50,10 +50,8 @@ const Record::Base *Record::getBase(const RecordDecl *FD) const {
 }
 
 const Record::Base *Record::getBase(QualType T) const {
-  if (auto *RT = T->getAs<RecordType>()) {
-    const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+  if (auto *RD = T->getAsCXXRecordDecl())
     return BaseMap.lookup(RD);
-  }
   return nullptr;
 }
 
diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp
index e4b77edc063dc..0ced210900b1a 100644
--- a/clang/lib/AST/CXXInheritance.cpp
+++ b/clang/lib/AST/CXXInheritance.cpp
@@ -128,17 +128,11 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches) const {
   const CXXRecordDecl *Record = this;
   while (true) {
     for (const auto &I : Record->bases()) {
-      const RecordType *Ty = I.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = I.getType()->getAsCXXRecordDecl();
+      if (!Base || !(Base->isBeingDefined() || Base->isCompleteDefinition()))
         return false;
-
-      CXXRecordDecl *Base = cast_if_present<CXXRecordDecl>(
-          Ty->getOriginalDecl()->getDefinition());
-      if (!Base ||
-          (Base->isDependentContext() &&
-           !Base->isCurrentInstantiation(Record))) {
+      if (Base->isDependentContext() && !Base->isCurrentInstantiation(Record))
         return false;
-      }
 
       Queue.push_back(Base);
       if (!BaseMatches(Base))
@@ -255,9 +249,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
         const TemplateSpecializationType *TST =
             BaseSpec.getType()->getAs<TemplateSpecializationType>();
         if (!TST) {
-          if (auto *RT = BaseSpec.getType()->getAs<RecordType>())
-            BaseRecord = cast<CXXRecordDecl>(RT->getOriginalDecl())
-                             ->getDefinitionOrSelf();
+          BaseRecord = BaseSpec.getType()->getAsCXXRecordDecl();
         } else {
           TemplateName TN = TST->getTemplateName();
           if (auto *TD =
@@ -347,11 +339,8 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches,
       // base is a subobject of any other path; if so, then the
       // declaration in this path are hidden by that patch.
       for (const CXXBasePath &HidingP : Paths) {
-        CXXRecordDecl *HidingClass = nullptr;
-        if (const RecordType *Record =
-                HidingP.back().Base->getType()->getAs<RecordType>())
-          HidingClass = cast<CXXRecordDecl>(Record->getOriginalDecl())
-                            ->getDefinitionOrSelf();
+        auto *HidingClass =
+            HidingP.back().Base->getType()->getAsCXXRecordDecl();
         if (!HidingClass)
           break;
 
@@ -470,9 +459,7 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
       = ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())];
 
   for (const auto &Base : RD->bases()) {
-    if (const RecordType *RT = Base.getType()->getAs<RecordType>()) {
-      const CXXRecordDecl *BaseDecl =
-          cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
+    if (const auto *BaseDecl = Base.getType()->getAsCXXRecordDecl()) {
       if (!BaseDecl->isPolymorphic())
         continue;
 
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 4507f415ce606..c44bf739dca2d 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2861,9 +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<RecordType>();
-  if (!Ty ||
-      !Ty->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
+  auto *D = getType()->getAsRecordDecl();
+  if (!D || !D->hasFlexibleArrayMember())
     return false;
   auto *List = dyn_cast<InitListExpr>(getInit()->IgnoreParens());
   if (!List)
@@ -2877,11 +2876,8 @@ bool VarDecl::hasFlexibleArrayInit(const ASTContext &Ctx) const {
 
 CharUnits VarDecl::getFlexibleArrayInitChars(const ASTContext &Ctx) const {
   assert(hasInit() && "Expect initializer to check for flexible a...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Aug 25, 2025

@llvm/pr-subscribers-backend-amdgpu

Author: Matheus Izvekov (mizvekov)

Changes

This changes a bunch of places which use getAs<TagType>, including derived types, just to obtain the tag definition.

This is preparation for #155028, offloading all the changes that PR used to introduce which don't depend on any new helpers.


Patch is 172.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/155313.diff

100 Files Affected:

  • (modified) clang-tools-extra/clang-doc/Serialize.cpp (+2-3)
  • (modified) clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp (+2-3)
  • (modified) clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp (+9-14)
  • (modified) clang-tools-extra/clang-tidy/utils/TypeTraits.cpp (+2-3)
  • (modified) clang/include/clang/AST/AbstractBasicReader.h (+1-1)
  • (modified) clang/include/clang/AST/AbstractBasicWriter.h (+1-1)
  • (modified) clang/include/clang/AST/DeclCXX.h (+3-1)
  • (modified) clang/include/clang/Sema/Sema.h (+1-1)
  • (modified) clang/lib/AST/ASTContext.cpp (+12-22)
  • (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+2-2)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+7-14)
  • (modified) clang/lib/AST/ByteCode/Program.cpp (+4-6)
  • (modified) clang/lib/AST/ByteCode/Record.cpp (+1-3)
  • (modified) clang/lib/AST/CXXInheritance.cpp (+7-20)
  • (modified) clang/lib/AST/Decl.cpp (+7-13)
  • (modified) clang/lib/AST/DeclCXX.cpp (+13-18)
  • (modified) clang/lib/AST/DeclTemplate.cpp (+3-3)
  • (modified) clang/lib/AST/ExprConstant.cpp (+7-10)
  • (modified) clang/lib/AST/FormatString.cpp (+1-1)
  • (modified) clang/lib/AST/ItaniumMangle.cpp (+4-4)
  • (modified) clang/lib/AST/RecordLayoutBuilder.cpp (+11-15)
  • (modified) clang/lib/AST/Type.cpp (+41-56)
  • (modified) clang/lib/Analysis/ExprMutationAnalyzer.cpp (+2-1)
  • (modified) clang/lib/Analysis/ThreadSafetyCommon.cpp (+5-7)
  • (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+4-10)
  • (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+1-1)
  • (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+5-14)
  • (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+1-2)
  • (modified) clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp (+3-2)
  • (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+3-6)
  • (modified) clang/lib/CIR/CodeGen/TargetInfo.cpp (+2-4)
  • (modified) clang/lib/CodeGen/ABIInfo.cpp (+1-2)
  • (modified) clang/lib/CodeGen/ABIInfoImpl.cpp (+13-20)
  • (modified) clang/lib/CodeGen/CGBlocks.cpp (+3-6)
  • (modified) clang/lib/CodeGen/CGBuiltin.cpp (+4-5)
  • (modified) clang/lib/CodeGen/CGCXXABI.cpp (+1-4)
  • (modified) clang/lib/CodeGen/CGCall.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CGClass.cpp (+4-10)
  • (modified) clang/lib/CodeGen/CGDecl.cpp (+3-4)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+5-8)
  • (modified) clang/lib/CodeGen/CGExprAgg.cpp (+7-12)
  • (modified) clang/lib/CodeGen/CGExprCXX.cpp (+1-3)
  • (modified) clang/lib/CodeGen/CGExprConstant.cpp (+5-8)
  • (modified) clang/lib/CodeGen/CGObjC.cpp (+2-4)
  • (modified) clang/lib/CodeGen/CGObjCMac.cpp (+2-3)
  • (modified) clang/lib/CodeGen/CGObjCRuntime.cpp (+2-4)
  • (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+3-8)
  • (modified) clang/lib/CodeGen/CodeGenFunction.h (+1-3)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+2-3)
  • (modified) clang/lib/CodeGen/CodeGenTypes.cpp (+5-7)
  • (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+12-15)
  • (modified) clang/lib/CodeGen/Targets/AArch64.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/AMDGPU.cpp (+7-12)
  • (modified) clang/lib/CodeGen/Targets/ARM.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/CSKY.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/NVPTX.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/PPC.cpp (+1-4)
  • (modified) clang/lib/CodeGen/Targets/SPIR.cpp (+7-12)
  • (modified) clang/lib/CodeGen/Targets/SystemZ.cpp (+2-4)
  • (modified) clang/lib/CodeGen/Targets/X86.cpp (+10-15)
  • (modified) clang/lib/Edit/RewriteObjCFoundationAPI.cpp (+1-1)
  • (modified) clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp (+1-9)
  • (modified) clang/lib/Interpreter/Value.cpp (+6-9)
  • (modified) clang/lib/Sema/Sema.cpp (+15-18)
  • (modified) clang/lib/Sema/SemaAccess.cpp (+2-4)
  • (modified) clang/lib/Sema/SemaCUDA.cpp (+5-12)
  • (modified) clang/lib/Sema/SemaCast.cpp (+9-11)
  • (modified) clang/lib/Sema/SemaChecking.cpp (+5-12)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+69-91)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+24-30)
  • (modified) clang/lib/Sema/SemaDeclCXX.cpp (+21-38)
  • (modified) clang/lib/Sema/SemaDeclObjC.cpp (+9-18)
  • (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+2-3)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+18-28)
  • (modified) clang/lib/Sema/SemaExprCXX.cpp (+4-9)
  • (modified) clang/lib/Sema/SemaHLSL.cpp (+5-10)
  • (modified) clang/lib/Sema/SemaInit.cpp (+63-75)
  • (modified) clang/lib/Sema/SemaLookup.cpp (+4-7)
  • (modified) clang/lib/Sema/SemaObjCProperty.cpp (+2-4)
  • (modified) clang/lib/Sema/SemaOverload.cpp (+11-12)
  • (modified) clang/lib/Sema/SemaStmtAsm.cpp (+3-4)
  • (modified) clang/lib/Sema/SemaSwift.cpp (+7-9)
  • (modified) clang/lib/Sema/SemaTemplate.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+2-2)
  • (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+5-9)
  • (modified) clang/lib/Sema/SemaType.cpp (+3-8)
  • (modified) clang/lib/Sema/SemaTypeTraits.cpp (+5-7)
  • (modified) clang/lib/Sema/TreeTransform.h (+11-20)
  • (modified) clang/lib/Sema/UsedDeclVisitor.h (+4-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp (+2-3)
  • (modified) clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp (+5-11)
  • (modified) clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp (+3-3)
  • (modified) clang/lib/StaticAnalyzer/Core/ExprEngine.cpp (+1-1)
  • (modified) clang/tools/libclang/CIndex.cpp (+1-1)
  • (modified) clang/unittests/AST/ASTImporterTest.cpp (+1-3)
  • (modified) clang/unittests/AST/RandstructTest.cpp (+1-2)
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index bcab4f1b8a729..506cc0a3b0e8f 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -901,9 +901,8 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
   if (!D->isThisDeclarationADefinition())
     return;
   for (const CXXBaseSpecifier &B : D->bases()) {
-    if (const RecordType *Ty = B.getType()->getAs<RecordType>()) {
-      if (const CXXRecordDecl *Base = cast_or_null<CXXRecordDecl>(
-              Ty->getOriginalDecl()->getDefinition())) {
+    if (const auto *Base = B.getType()->getAsCXXRecordDecl()) {
+      if (Base->isCompleteDefinition()) {
         // 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/cert/DefaultOperatorNewAlignmentCheck.cpp b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
index 2a0d0ada42b28..2c2248afb69e7 100644
--- a/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
@@ -31,7 +31,7 @@ void DefaultOperatorNewAlignmentCheck::check(
     return;
   const TagDecl *D = T->getAsTagDecl();
   // Alignment can not be obtained for undefined type.
-  if (!D || !D->getDefinition() || !D->isCompleteDefinition())
+  if (!D || !D->isCompleteDefinition())
     return;
 
   ASTContext &Context = D->getASTContext();
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
index 40fd15c08f0a1..6508bfd5ca808 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
@@ -90,9 +90,8 @@ void SlicingCheck::diagnoseSlicedOverriddenMethods(
   }
   // Recursively process bases.
   for (const auto &Base : DerivedDecl.bases()) {
-    if (const auto *BaseRecordType = Base.getType()->getAs<RecordType>()) {
-      if (const auto *BaseRecord = cast_or_null<CXXRecordDecl>(
-              BaseRecordType->getOriginalDecl()->getDefinition()))
+    if (const auto *BaseRecord = Base.getType()->getAsCXXRecordDecl()) {
+      if (BaseRecord->isCompleteDefinition())
         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 0302a5ad4957c..36b6007b58a51 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
@@ -71,13 +71,10 @@ bool MultipleInheritanceCheck::isInterface(const CXXRecordDecl *Node) {
   for (const auto &I : Node->bases()) {
     if (I.isVirtual())
       continue;
-    const auto *Ty = I.getType()->getAs<RecordType>();
-    if (!Ty)
+    const auto *Base = I.getType()->getAsCXXRecordDecl();
+    if (!Base)
       continue;
-    const RecordDecl *D = Ty->getOriginalDecl()->getDefinition();
-    if (!D)
-      continue;
-    const auto *Base = cast<CXXRecordDecl>(D);
+    assert(Base->isCompleteDefinition());
     if (!isInterface(Base)) {
       addNodeToInterfaceMap(Node, false);
       return false;
@@ -103,11 +100,10 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
     for (const auto &I : D->bases()) {
       if (I.isVirtual())
         continue;
-      const auto *Ty = I.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = I.getType()->getAsCXXRecordDecl();
+      if (!Base)
         continue;
-      const auto *Base =
-          cast<CXXRecordDecl>(Ty->getOriginalDecl()->getDefinition());
+      assert(Base->isCompleteDefinition());
       if (!isInterface(Base))
         NumConcrete++;
     }
@@ -115,11 +111,10 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
     // Check virtual bases to see if there is more than one concrete
     // non-virtual base.
     for (const auto &V : D->vbases()) {
-      const auto *Ty = V.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = V.getType()->getAsCXXRecordDecl();
+      if (!Base)
         continue;
-      const auto *Base =
-          cast<CXXRecordDecl>(Ty->getOriginalDecl()->getDefinition());
+      assert(Base->isCompleteDefinition());
       if (!isInterface(Base))
         NumConcrete++;
     }
diff --git a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
index 5518afd32e7f0..f944306171135 100644
--- a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
+++ b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
@@ -119,9 +119,8 @@ bool isTriviallyDefaultConstructible(QualType Type, const ASTContext &Context) {
   if (CanonicalType->isScalarType() || CanonicalType->isVectorType())
     return true;
 
-  if (const auto *RT = CanonicalType->getAs<RecordType>()) {
-    return recordIsTriviallyDefaultConstructible(
-        *RT->getOriginalDecl()->getDefinitionOrSelf(), Context);
+  if (const auto *RD = CanonicalType->getAsRecordDecl()) {
+    return recordIsTriviallyDefaultConstructible(*RD, Context);
   }
 
   // No other types can match.
diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h
index 26052b8086cf7..0d187eb49d6ca 100644
--- a/clang/include/clang/AST/AbstractBasicReader.h
+++ b/clang/include/clang/AST/AbstractBasicReader.h
@@ -193,7 +193,7 @@ class DataStreamBasicReader : public BasicReaderBase<Impl> {
     auto elemTy = origTy;
     unsigned pathLength = asImpl().readUInt32();
     for (unsigned i = 0; i < pathLength; ++i) {
-      if (elemTy->template getAs<RecordType>()) {
+      if (elemTy->isRecordType()) {
         unsigned int_ = asImpl().readUInt32();
         Decl *decl = asImpl().template readDeclAs<Decl>();
         if (auto *recordDecl = dyn_cast<CXXRecordDecl>(decl))
diff --git a/clang/include/clang/AST/AbstractBasicWriter.h b/clang/include/clang/AST/AbstractBasicWriter.h
index d41e655986ef9..8ea0c29cf5070 100644
--- a/clang/include/clang/AST/AbstractBasicWriter.h
+++ b/clang/include/clang/AST/AbstractBasicWriter.h
@@ -176,7 +176,7 @@ class DataStreamBasicWriter : public BasicWriterBase<Impl> {
     asImpl().writeUInt32(path.size());
     auto &ctx = ((BasicWriterBase<Impl> *)this)->getASTContext();
     for (auto elem : path) {
-      if (elemTy->getAs<RecordType>()) {
+      if (elemTy->isRecordType()) {
         asImpl().writeUInt32(elem.getAsBaseOrMember().getInt());
         const Decl *baseOrMember = elem.getAsBaseOrMember().getPointer();
         if (const auto *recordDecl = dyn_cast<CXXRecordDecl>(baseOrMember)) {
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 1d2ef0f4f2319..3ee03122f50cf 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -3825,7 +3825,9 @@ class UsingEnumDecl : public BaseUsingDecl, public Mergeable<UsingEnumDecl> {
   void setEnumType(TypeSourceInfo *TSI) { EnumType = TSI; }
 
 public:
-  EnumDecl *getEnumDecl() const { return cast<EnumDecl>(EnumType->getType()->getAsTagDecl()); }
+  EnumDecl *getEnumDecl() const {
+    return cast<clang::EnumType>(EnumType->getType())->getOriginalDecl();
+  }
 
   static UsingEnumDecl *Create(ASTContext &C, DeclContext *DC,
                                SourceLocation UsingL, SourceLocation EnumL,
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a78f5635f44da..c3fb57774c8dc 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5404,7 +5404,7 @@ class Sema final : public SemaBase {
 
   /// FinalizeVarWithDestructor - Prepare for calling destructor on the
   /// constructed variable.
-  void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType);
+  void FinalizeVarWithDestructor(VarDecl *VD, CXXRecordDecl *DeclInit);
 
   /// Helper class that collects exception specifications for
   /// implicitly-declared special member functions.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index bbb957067c4c8..036df53063568 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -654,9 +654,9 @@ comments::FullComment *ASTContext::getCommentForDecl(
       // does not have one of its own.
       QualType QT = TD->getUnderlyingType();
       if (const auto *TT = QT->getAs<TagType>())
-        if (const Decl *TD = TT->getOriginalDecl())
-          if (comments::FullComment *FC = getCommentForDecl(TD, PP))
-            return cloneFullComment(FC, D);
+        if (comments::FullComment *FC =
+                getCommentForDecl(TT->getOriginalDecl(), PP))
+          return cloneFullComment(FC, D);
     }
     else if (const auto *IC = dyn_cast<ObjCInterfaceDecl>(D)) {
       while (IC->getSuperClass()) {
@@ -1933,12 +1933,9 @@ 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<RecordType>()) {
-      const auto *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (!RD->isInvalidDecl()) {
-        const ASTRecordLayout &layout = getASTRecordLayout(RD);
-        Info.Width = layout.getDataSize();
-      }
+    if (const auto *RD = T->getAsCXXRecordDecl(); RD && !RD->isInvalidDecl()) {
+      const ASTRecordLayout &layout = getASTRecordLayout(RD);
+      Info.Width = layout.getDataSize();
     }
   }
 
@@ -2694,9 +2691,7 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
   if (!Target->allowsLargerPreferedTypeAlignment())
     return ABIAlign;
 
-  if (const auto *RT = T->getAs<RecordType>()) {
-    const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-
+  if (const auto *RD = T->getAsRecordDecl()) {
     // 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
     // 'packed' case is already taken into consideration when computing the
@@ -2887,12 +2882,10 @@ structHasUniqueObjectRepresentations(const ASTContext &Context,
 static std::optional<int64_t>
 getSubobjectSizeInBits(const FieldDecl *Field, const ASTContext &Context,
                        bool CheckIfTriviallyCopyable) {
-  if (Field->getType()->isRecordType()) {
-    const RecordDecl *RD = Field->getType()->getAsRecordDecl();
-    if (!RD->isUnion())
-      return structHasUniqueObjectRepresentations(Context, RD,
-                                                  CheckIfTriviallyCopyable);
-  }
+  if (const auto *RD = Field->getType()->getAsRecordDecl();
+      RD && !RD->isUnion())
+    return structHasUniqueObjectRepresentations(Context, RD,
+                                                CheckIfTriviallyCopyable);
 
   // A _BitInt type may not be unique if it has padding bits
   // but if it is a bitfield the padding bits are not used.
@@ -3047,10 +3040,7 @@ bool ASTContext::hasUniqueObjectRepresentations(
   if (const auto *MPT = Ty->getAs<MemberPointerType>())
     return !ABI->getMemberPointerInfo(MPT).HasPadding;
 
-  if (Ty->isRecordType()) {
-    const RecordDecl *Record =
-        Ty->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
-
+  if (const auto *Record = Ty->getAsRecordDecl()) {
     if (Record->isInvalidDecl())
       return false;
 
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 6d83de384ee10..1292c30d47589 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -878,10 +878,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
       // Treat the enumeration as its underlying type and use the builtin type
       // class comparison.
       if (T1->getTypeClass() == Type::Enum) {
-        T1 = T1->getAs<EnumType>()->getOriginalDecl()->getIntegerType();
+        T1 = cast<EnumType>(T1)->getOriginalDecl()->getIntegerType();
         assert(T2->isBuiltinType() && !T1.isNull()); // Sanity check
       } else if (T2->getTypeClass() == Type::Enum) {
-        T2 = T2->getAs<EnumType>()->getOriginalDecl()->getIntegerType();
+        T2 = cast<EnumType>(T2)->getOriginalDecl()->getIntegerType();
         assert(T1->isBuiltinType() && !T2.isNull()); // Sanity check
       }
       TC = Type::Builtin;
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 2e28814abfddb..e245f24e614e5 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -3303,11 +3303,8 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
     switch (Node.getKind()) {
     case OffsetOfNode::Field: {
       const FieldDecl *MemberDecl = Node.getField();
-      const RecordType *RT = CurrentType->getAs<RecordType>();
-      if (!RT)
-        return false;
-      const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (RD->isInvalidDecl())
+      const auto *RD = CurrentType->getAsRecordDecl();
+      if (!RD || RD->isInvalidDecl())
         return false;
       const ASTRecordLayout &RL = S.getASTContext().getASTRecordLayout(RD);
       unsigned FieldIndex = MemberDecl->getFieldIndex();
@@ -3336,23 +3333,19 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
         return false;
 
       // Find the layout of the class whose base we are looking into.
-      const RecordType *RT = CurrentType->getAs<RecordType>();
-      if (!RT)
-        return false;
-      const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (RD->isInvalidDecl())
+      const auto *RD = CurrentType->getAsCXXRecordDecl();
+      if (!RD || RD->isInvalidDecl())
         return false;
       const ASTRecordLayout &RL = S.getASTContext().getASTRecordLayout(RD);
 
       // Find the base class itself.
       CurrentType = BaseSpec->getType();
-      const RecordType *BaseRT = CurrentType->getAs<RecordType>();
-      if (!BaseRT)
+      const auto *BaseRD = CurrentType->getAsCXXRecordDecl();
+      if (!BaseRD)
         return false;
 
       // Add the offset to the base.
-      Result += RL.getBaseClassOffset(cast<CXXRecordDecl>(
-          BaseRT->getOriginalDecl()->getDefinitionOrSelf()));
+      Result += RL.getBaseClassOffset(BaseRD);
       break;
     }
     case OffsetOfNode::Identifier:
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index 5d72044af969e..139cae7afc87e 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -332,10 +332,9 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
         continue;
 
       // In error cases, the base might not be a RecordType.
-      const auto *RT = Spec.getType()->getAs<RecordType>();
-      if (!RT)
+      const auto *BD = Spec.getType()->getAsCXXRecordDecl();
+      if (!BD)
         return nullptr;
-      const RecordDecl *BD = RT->getOriginalDecl()->getDefinitionOrSelf();
       const Record *BR = getOrCreateRecord(BD);
 
       const Descriptor *Desc = GetBaseDesc(BD, BR);
@@ -408,9 +407,8 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
                                       const Expr *Init) {
 
   // Classes and structures.
-  if (const auto *RT = Ty->getAs<RecordType>()) {
-    if (const auto *Record =
-            getOrCreateRecord(RT->getOriginalDecl()->getDefinitionOrSelf()))
+  if (const auto *RD = Ty->getAsRecordDecl()) {
+    if (const auto *Record = getOrCreateRecord(RD))
       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 a7934ccb4e55e..c20ec184f34f4 100644
--- a/clang/lib/AST/ByteCode/Record.cpp
+++ b/clang/lib/AST/ByteCode/Record.cpp
@@ -50,10 +50,8 @@ const Record::Base *Record::getBase(const RecordDecl *FD) const {
 }
 
 const Record::Base *Record::getBase(QualType T) const {
-  if (auto *RT = T->getAs<RecordType>()) {
-    const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+  if (auto *RD = T->getAsCXXRecordDecl())
     return BaseMap.lookup(RD);
-  }
   return nullptr;
 }
 
diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp
index e4b77edc063dc..0ced210900b1a 100644
--- a/clang/lib/AST/CXXInheritance.cpp
+++ b/clang/lib/AST/CXXInheritance.cpp
@@ -128,17 +128,11 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches) const {
   const CXXRecordDecl *Record = this;
   while (true) {
     for (const auto &I : Record->bases()) {
-      const RecordType *Ty = I.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = I.getType()->getAsCXXRecordDecl();
+      if (!Base || !(Base->isBeingDefined() || Base->isCompleteDefinition()))
         return false;
-
-      CXXRecordDecl *Base = cast_if_present<CXXRecordDecl>(
-          Ty->getOriginalDecl()->getDefinition());
-      if (!Base ||
-          (Base->isDependentContext() &&
-           !Base->isCurrentInstantiation(Record))) {
+      if (Base->isDependentContext() && !Base->isCurrentInstantiation(Record))
         return false;
-      }
 
       Queue.push_back(Base);
       if (!BaseMatches(Base))
@@ -255,9 +249,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
         const TemplateSpecializationType *TST =
             BaseSpec.getType()->getAs<TemplateSpecializationType>();
         if (!TST) {
-          if (auto *RT = BaseSpec.getType()->getAs<RecordType>())
-            BaseRecord = cast<CXXRecordDecl>(RT->getOriginalDecl())
-                             ->getDefinitionOrSelf();
+          BaseRecord = BaseSpec.getType()->getAsCXXRecordDecl();
         } else {
           TemplateName TN = TST->getTemplateName();
           if (auto *TD =
@@ -347,11 +339,8 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches,
       // base is a subobject of any other path; if so, then the
       // declaration in this path are hidden by that patch.
       for (const CXXBasePath &HidingP : Paths) {
-        CXXRecordDecl *HidingClass = nullptr;
-        if (const RecordType *Record =
-                HidingP.back().Base->getType()->getAs<RecordType>())
-          HidingClass = cast<CXXRecordDecl>(Record->getOriginalDecl())
-                            ->getDefinitionOrSelf();
+        auto *HidingClass =
+            HidingP.back().Base->getType()->getAsCXXRecordDecl();
         if (!HidingClass)
           break;
 
@@ -470,9 +459,7 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
       = ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())];
 
   for (const auto &Base : RD->bases()) {
-    if (const RecordType *RT = Base.getType()->getAs<RecordType>()) {
-      const CXXRecordDecl *BaseDecl =
-          cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
+    if (const auto *BaseDecl = Base.getType()->getAsCXXRecordDecl()) {
       if (!BaseDecl->isPolymorphic())
         continue;
 
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 4507f415ce606..c44bf739dca2d 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2861,9 +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<RecordType>();
-  if (!Ty ||
-      !Ty->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
+  auto *D = getType()->getAsRecordDecl();
+  if (!D || !D->hasFlexibleArrayMember())
     return false;
   auto *List = dyn_cast<InitListExpr>(getInit()->IgnoreParens());
   if (!List)
@@ -2877,11 +2876,8 @@ bool VarDecl::hasFlexibleArrayInit(const ASTContext &Ctx) const {
 
 CharUnits VarDecl::getFlexibleArrayInitChars(const ASTContext &Ctx) const {
   assert(hasInit() && "Expect initializer to check for flexible a...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Aug 25, 2025

@llvm/pr-subscribers-hlsl

Author: Matheus Izvekov (mizvekov)

Changes

This changes a bunch of places which use getAs<TagType>, including derived types, just to obtain the tag definition.

This is preparation for #155028, offloading all the changes that PR used to introduce which don't depend on any new helpers.


Patch is 172.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/155313.diff

100 Files Affected:

  • (modified) clang-tools-extra/clang-doc/Serialize.cpp (+2-3)
  • (modified) clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp (+2-3)
  • (modified) clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp (+9-14)
  • (modified) clang-tools-extra/clang-tidy/utils/TypeTraits.cpp (+2-3)
  • (modified) clang/include/clang/AST/AbstractBasicReader.h (+1-1)
  • (modified) clang/include/clang/AST/AbstractBasicWriter.h (+1-1)
  • (modified) clang/include/clang/AST/DeclCXX.h (+3-1)
  • (modified) clang/include/clang/Sema/Sema.h (+1-1)
  • (modified) clang/lib/AST/ASTContext.cpp (+12-22)
  • (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+2-2)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+7-14)
  • (modified) clang/lib/AST/ByteCode/Program.cpp (+4-6)
  • (modified) clang/lib/AST/ByteCode/Record.cpp (+1-3)
  • (modified) clang/lib/AST/CXXInheritance.cpp (+7-20)
  • (modified) clang/lib/AST/Decl.cpp (+7-13)
  • (modified) clang/lib/AST/DeclCXX.cpp (+13-18)
  • (modified) clang/lib/AST/DeclTemplate.cpp (+3-3)
  • (modified) clang/lib/AST/ExprConstant.cpp (+7-10)
  • (modified) clang/lib/AST/FormatString.cpp (+1-1)
  • (modified) clang/lib/AST/ItaniumMangle.cpp (+4-4)
  • (modified) clang/lib/AST/RecordLayoutBuilder.cpp (+11-15)
  • (modified) clang/lib/AST/Type.cpp (+41-56)
  • (modified) clang/lib/Analysis/ExprMutationAnalyzer.cpp (+2-1)
  • (modified) clang/lib/Analysis/ThreadSafetyCommon.cpp (+5-7)
  • (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+4-10)
  • (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+1-1)
  • (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+5-14)
  • (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+1-2)
  • (modified) clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp (+3-2)
  • (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+3-6)
  • (modified) clang/lib/CIR/CodeGen/TargetInfo.cpp (+2-4)
  • (modified) clang/lib/CodeGen/ABIInfo.cpp (+1-2)
  • (modified) clang/lib/CodeGen/ABIInfoImpl.cpp (+13-20)
  • (modified) clang/lib/CodeGen/CGBlocks.cpp (+3-6)
  • (modified) clang/lib/CodeGen/CGBuiltin.cpp (+4-5)
  • (modified) clang/lib/CodeGen/CGCXXABI.cpp (+1-4)
  • (modified) clang/lib/CodeGen/CGCall.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CGClass.cpp (+4-10)
  • (modified) clang/lib/CodeGen/CGDecl.cpp (+3-4)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+5-8)
  • (modified) clang/lib/CodeGen/CGExprAgg.cpp (+7-12)
  • (modified) clang/lib/CodeGen/CGExprCXX.cpp (+1-3)
  • (modified) clang/lib/CodeGen/CGExprConstant.cpp (+5-8)
  • (modified) clang/lib/CodeGen/CGObjC.cpp (+2-4)
  • (modified) clang/lib/CodeGen/CGObjCMac.cpp (+2-3)
  • (modified) clang/lib/CodeGen/CGObjCRuntime.cpp (+2-4)
  • (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+3-8)
  • (modified) clang/lib/CodeGen/CodeGenFunction.h (+1-3)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+2-3)
  • (modified) clang/lib/CodeGen/CodeGenTypes.cpp (+5-7)
  • (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+12-15)
  • (modified) clang/lib/CodeGen/Targets/AArch64.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/AMDGPU.cpp (+7-12)
  • (modified) clang/lib/CodeGen/Targets/ARM.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/CSKY.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/NVPTX.cpp (+2-3)
  • (modified) clang/lib/CodeGen/Targets/PPC.cpp (+1-4)
  • (modified) clang/lib/CodeGen/Targets/SPIR.cpp (+7-12)
  • (modified) clang/lib/CodeGen/Targets/SystemZ.cpp (+2-4)
  • (modified) clang/lib/CodeGen/Targets/X86.cpp (+10-15)
  • (modified) clang/lib/Edit/RewriteObjCFoundationAPI.cpp (+1-1)
  • (modified) clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp (+1-9)
  • (modified) clang/lib/Interpreter/Value.cpp (+6-9)
  • (modified) clang/lib/Sema/Sema.cpp (+15-18)
  • (modified) clang/lib/Sema/SemaAccess.cpp (+2-4)
  • (modified) clang/lib/Sema/SemaCUDA.cpp (+5-12)
  • (modified) clang/lib/Sema/SemaCast.cpp (+9-11)
  • (modified) clang/lib/Sema/SemaChecking.cpp (+5-12)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+69-91)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+24-30)
  • (modified) clang/lib/Sema/SemaDeclCXX.cpp (+21-38)
  • (modified) clang/lib/Sema/SemaDeclObjC.cpp (+9-18)
  • (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+2-3)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+18-28)
  • (modified) clang/lib/Sema/SemaExprCXX.cpp (+4-9)
  • (modified) clang/lib/Sema/SemaHLSL.cpp (+5-10)
  • (modified) clang/lib/Sema/SemaInit.cpp (+63-75)
  • (modified) clang/lib/Sema/SemaLookup.cpp (+4-7)
  • (modified) clang/lib/Sema/SemaObjCProperty.cpp (+2-4)
  • (modified) clang/lib/Sema/SemaOverload.cpp (+11-12)
  • (modified) clang/lib/Sema/SemaStmtAsm.cpp (+3-4)
  • (modified) clang/lib/Sema/SemaSwift.cpp (+7-9)
  • (modified) clang/lib/Sema/SemaTemplate.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+2-2)
  • (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+5-9)
  • (modified) clang/lib/Sema/SemaType.cpp (+3-8)
  • (modified) clang/lib/Sema/SemaTypeTraits.cpp (+5-7)
  • (modified) clang/lib/Sema/TreeTransform.h (+11-20)
  • (modified) clang/lib/Sema/UsedDeclVisitor.h (+4-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp (+2-3)
  • (modified) clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp (+5-11)
  • (modified) clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp (+3-3)
  • (modified) clang/lib/StaticAnalyzer/Core/ExprEngine.cpp (+1-1)
  • (modified) clang/tools/libclang/CIndex.cpp (+1-1)
  • (modified) clang/unittests/AST/ASTImporterTest.cpp (+1-3)
  • (modified) clang/unittests/AST/RandstructTest.cpp (+1-2)
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index bcab4f1b8a729..506cc0a3b0e8f 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -901,9 +901,8 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
   if (!D->isThisDeclarationADefinition())
     return;
   for (const CXXBaseSpecifier &B : D->bases()) {
-    if (const RecordType *Ty = B.getType()->getAs<RecordType>()) {
-      if (const CXXRecordDecl *Base = cast_or_null<CXXRecordDecl>(
-              Ty->getOriginalDecl()->getDefinition())) {
+    if (const auto *Base = B.getType()->getAsCXXRecordDecl()) {
+      if (Base->isCompleteDefinition()) {
         // 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/cert/DefaultOperatorNewAlignmentCheck.cpp b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
index 2a0d0ada42b28..2c2248afb69e7 100644
--- a/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
@@ -31,7 +31,7 @@ void DefaultOperatorNewAlignmentCheck::check(
     return;
   const TagDecl *D = T->getAsTagDecl();
   // Alignment can not be obtained for undefined type.
-  if (!D || !D->getDefinition() || !D->isCompleteDefinition())
+  if (!D || !D->isCompleteDefinition())
     return;
 
   ASTContext &Context = D->getASTContext();
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
index 40fd15c08f0a1..6508bfd5ca808 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
@@ -90,9 +90,8 @@ void SlicingCheck::diagnoseSlicedOverriddenMethods(
   }
   // Recursively process bases.
   for (const auto &Base : DerivedDecl.bases()) {
-    if (const auto *BaseRecordType = Base.getType()->getAs<RecordType>()) {
-      if (const auto *BaseRecord = cast_or_null<CXXRecordDecl>(
-              BaseRecordType->getOriginalDecl()->getDefinition()))
+    if (const auto *BaseRecord = Base.getType()->getAsCXXRecordDecl()) {
+      if (BaseRecord->isCompleteDefinition())
         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 0302a5ad4957c..36b6007b58a51 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
@@ -71,13 +71,10 @@ bool MultipleInheritanceCheck::isInterface(const CXXRecordDecl *Node) {
   for (const auto &I : Node->bases()) {
     if (I.isVirtual())
       continue;
-    const auto *Ty = I.getType()->getAs<RecordType>();
-    if (!Ty)
+    const auto *Base = I.getType()->getAsCXXRecordDecl();
+    if (!Base)
       continue;
-    const RecordDecl *D = Ty->getOriginalDecl()->getDefinition();
-    if (!D)
-      continue;
-    const auto *Base = cast<CXXRecordDecl>(D);
+    assert(Base->isCompleteDefinition());
     if (!isInterface(Base)) {
       addNodeToInterfaceMap(Node, false);
       return false;
@@ -103,11 +100,10 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
     for (const auto &I : D->bases()) {
       if (I.isVirtual())
         continue;
-      const auto *Ty = I.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = I.getType()->getAsCXXRecordDecl();
+      if (!Base)
         continue;
-      const auto *Base =
-          cast<CXXRecordDecl>(Ty->getOriginalDecl()->getDefinition());
+      assert(Base->isCompleteDefinition());
       if (!isInterface(Base))
         NumConcrete++;
     }
@@ -115,11 +111,10 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
     // Check virtual bases to see if there is more than one concrete
     // non-virtual base.
     for (const auto &V : D->vbases()) {
-      const auto *Ty = V.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = V.getType()->getAsCXXRecordDecl();
+      if (!Base)
         continue;
-      const auto *Base =
-          cast<CXXRecordDecl>(Ty->getOriginalDecl()->getDefinition());
+      assert(Base->isCompleteDefinition());
       if (!isInterface(Base))
         NumConcrete++;
     }
diff --git a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
index 5518afd32e7f0..f944306171135 100644
--- a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
+++ b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
@@ -119,9 +119,8 @@ bool isTriviallyDefaultConstructible(QualType Type, const ASTContext &Context) {
   if (CanonicalType->isScalarType() || CanonicalType->isVectorType())
     return true;
 
-  if (const auto *RT = CanonicalType->getAs<RecordType>()) {
-    return recordIsTriviallyDefaultConstructible(
-        *RT->getOriginalDecl()->getDefinitionOrSelf(), Context);
+  if (const auto *RD = CanonicalType->getAsRecordDecl()) {
+    return recordIsTriviallyDefaultConstructible(*RD, Context);
   }
 
   // No other types can match.
diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h
index 26052b8086cf7..0d187eb49d6ca 100644
--- a/clang/include/clang/AST/AbstractBasicReader.h
+++ b/clang/include/clang/AST/AbstractBasicReader.h
@@ -193,7 +193,7 @@ class DataStreamBasicReader : public BasicReaderBase<Impl> {
     auto elemTy = origTy;
     unsigned pathLength = asImpl().readUInt32();
     for (unsigned i = 0; i < pathLength; ++i) {
-      if (elemTy->template getAs<RecordType>()) {
+      if (elemTy->isRecordType()) {
         unsigned int_ = asImpl().readUInt32();
         Decl *decl = asImpl().template readDeclAs<Decl>();
         if (auto *recordDecl = dyn_cast<CXXRecordDecl>(decl))
diff --git a/clang/include/clang/AST/AbstractBasicWriter.h b/clang/include/clang/AST/AbstractBasicWriter.h
index d41e655986ef9..8ea0c29cf5070 100644
--- a/clang/include/clang/AST/AbstractBasicWriter.h
+++ b/clang/include/clang/AST/AbstractBasicWriter.h
@@ -176,7 +176,7 @@ class DataStreamBasicWriter : public BasicWriterBase<Impl> {
     asImpl().writeUInt32(path.size());
     auto &ctx = ((BasicWriterBase<Impl> *)this)->getASTContext();
     for (auto elem : path) {
-      if (elemTy->getAs<RecordType>()) {
+      if (elemTy->isRecordType()) {
         asImpl().writeUInt32(elem.getAsBaseOrMember().getInt());
         const Decl *baseOrMember = elem.getAsBaseOrMember().getPointer();
         if (const auto *recordDecl = dyn_cast<CXXRecordDecl>(baseOrMember)) {
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 1d2ef0f4f2319..3ee03122f50cf 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -3825,7 +3825,9 @@ class UsingEnumDecl : public BaseUsingDecl, public Mergeable<UsingEnumDecl> {
   void setEnumType(TypeSourceInfo *TSI) { EnumType = TSI; }
 
 public:
-  EnumDecl *getEnumDecl() const { return cast<EnumDecl>(EnumType->getType()->getAsTagDecl()); }
+  EnumDecl *getEnumDecl() const {
+    return cast<clang::EnumType>(EnumType->getType())->getOriginalDecl();
+  }
 
   static UsingEnumDecl *Create(ASTContext &C, DeclContext *DC,
                                SourceLocation UsingL, SourceLocation EnumL,
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a78f5635f44da..c3fb57774c8dc 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5404,7 +5404,7 @@ class Sema final : public SemaBase {
 
   /// FinalizeVarWithDestructor - Prepare for calling destructor on the
   /// constructed variable.
-  void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType);
+  void FinalizeVarWithDestructor(VarDecl *VD, CXXRecordDecl *DeclInit);
 
   /// Helper class that collects exception specifications for
   /// implicitly-declared special member functions.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index bbb957067c4c8..036df53063568 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -654,9 +654,9 @@ comments::FullComment *ASTContext::getCommentForDecl(
       // does not have one of its own.
       QualType QT = TD->getUnderlyingType();
       if (const auto *TT = QT->getAs<TagType>())
-        if (const Decl *TD = TT->getOriginalDecl())
-          if (comments::FullComment *FC = getCommentForDecl(TD, PP))
-            return cloneFullComment(FC, D);
+        if (comments::FullComment *FC =
+                getCommentForDecl(TT->getOriginalDecl(), PP))
+          return cloneFullComment(FC, D);
     }
     else if (const auto *IC = dyn_cast<ObjCInterfaceDecl>(D)) {
       while (IC->getSuperClass()) {
@@ -1933,12 +1933,9 @@ 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<RecordType>()) {
-      const auto *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (!RD->isInvalidDecl()) {
-        const ASTRecordLayout &layout = getASTRecordLayout(RD);
-        Info.Width = layout.getDataSize();
-      }
+    if (const auto *RD = T->getAsCXXRecordDecl(); RD && !RD->isInvalidDecl()) {
+      const ASTRecordLayout &layout = getASTRecordLayout(RD);
+      Info.Width = layout.getDataSize();
     }
   }
 
@@ -2694,9 +2691,7 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
   if (!Target->allowsLargerPreferedTypeAlignment())
     return ABIAlign;
 
-  if (const auto *RT = T->getAs<RecordType>()) {
-    const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-
+  if (const auto *RD = T->getAsRecordDecl()) {
     // 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
     // 'packed' case is already taken into consideration when computing the
@@ -2887,12 +2882,10 @@ structHasUniqueObjectRepresentations(const ASTContext &Context,
 static std::optional<int64_t>
 getSubobjectSizeInBits(const FieldDecl *Field, const ASTContext &Context,
                        bool CheckIfTriviallyCopyable) {
-  if (Field->getType()->isRecordType()) {
-    const RecordDecl *RD = Field->getType()->getAsRecordDecl();
-    if (!RD->isUnion())
-      return structHasUniqueObjectRepresentations(Context, RD,
-                                                  CheckIfTriviallyCopyable);
-  }
+  if (const auto *RD = Field->getType()->getAsRecordDecl();
+      RD && !RD->isUnion())
+    return structHasUniqueObjectRepresentations(Context, RD,
+                                                CheckIfTriviallyCopyable);
 
   // A _BitInt type may not be unique if it has padding bits
   // but if it is a bitfield the padding bits are not used.
@@ -3047,10 +3040,7 @@ bool ASTContext::hasUniqueObjectRepresentations(
   if (const auto *MPT = Ty->getAs<MemberPointerType>())
     return !ABI->getMemberPointerInfo(MPT).HasPadding;
 
-  if (Ty->isRecordType()) {
-    const RecordDecl *Record =
-        Ty->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
-
+  if (const auto *Record = Ty->getAsRecordDecl()) {
     if (Record->isInvalidDecl())
       return false;
 
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 6d83de384ee10..1292c30d47589 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -878,10 +878,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
       // Treat the enumeration as its underlying type and use the builtin type
       // class comparison.
       if (T1->getTypeClass() == Type::Enum) {
-        T1 = T1->getAs<EnumType>()->getOriginalDecl()->getIntegerType();
+        T1 = cast<EnumType>(T1)->getOriginalDecl()->getIntegerType();
         assert(T2->isBuiltinType() && !T1.isNull()); // Sanity check
       } else if (T2->getTypeClass() == Type::Enum) {
-        T2 = T2->getAs<EnumType>()->getOriginalDecl()->getIntegerType();
+        T2 = cast<EnumType>(T2)->getOriginalDecl()->getIntegerType();
         assert(T1->isBuiltinType() && !T2.isNull()); // Sanity check
       }
       TC = Type::Builtin;
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 2e28814abfddb..e245f24e614e5 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -3303,11 +3303,8 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
     switch (Node.getKind()) {
     case OffsetOfNode::Field: {
       const FieldDecl *MemberDecl = Node.getField();
-      const RecordType *RT = CurrentType->getAs<RecordType>();
-      if (!RT)
-        return false;
-      const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (RD->isInvalidDecl())
+      const auto *RD = CurrentType->getAsRecordDecl();
+      if (!RD || RD->isInvalidDecl())
         return false;
       const ASTRecordLayout &RL = S.getASTContext().getASTRecordLayout(RD);
       unsigned FieldIndex = MemberDecl->getFieldIndex();
@@ -3336,23 +3333,19 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
         return false;
 
       // Find the layout of the class whose base we are looking into.
-      const RecordType *RT = CurrentType->getAs<RecordType>();
-      if (!RT)
-        return false;
-      const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
-      if (RD->isInvalidDecl())
+      const auto *RD = CurrentType->getAsCXXRecordDecl();
+      if (!RD || RD->isInvalidDecl())
         return false;
       const ASTRecordLayout &RL = S.getASTContext().getASTRecordLayout(RD);
 
       // Find the base class itself.
       CurrentType = BaseSpec->getType();
-      const RecordType *BaseRT = CurrentType->getAs<RecordType>();
-      if (!BaseRT)
+      const auto *BaseRD = CurrentType->getAsCXXRecordDecl();
+      if (!BaseRD)
         return false;
 
       // Add the offset to the base.
-      Result += RL.getBaseClassOffset(cast<CXXRecordDecl>(
-          BaseRT->getOriginalDecl()->getDefinitionOrSelf()));
+      Result += RL.getBaseClassOffset(BaseRD);
       break;
     }
     case OffsetOfNode::Identifier:
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index 5d72044af969e..139cae7afc87e 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -332,10 +332,9 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
         continue;
 
       // In error cases, the base might not be a RecordType.
-      const auto *RT = Spec.getType()->getAs<RecordType>();
-      if (!RT)
+      const auto *BD = Spec.getType()->getAsCXXRecordDecl();
+      if (!BD)
         return nullptr;
-      const RecordDecl *BD = RT->getOriginalDecl()->getDefinitionOrSelf();
       const Record *BR = getOrCreateRecord(BD);
 
       const Descriptor *Desc = GetBaseDesc(BD, BR);
@@ -408,9 +407,8 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
                                       const Expr *Init) {
 
   // Classes and structures.
-  if (const auto *RT = Ty->getAs<RecordType>()) {
-    if (const auto *Record =
-            getOrCreateRecord(RT->getOriginalDecl()->getDefinitionOrSelf()))
+  if (const auto *RD = Ty->getAsRecordDecl()) {
+    if (const auto *Record = getOrCreateRecord(RD))
       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 a7934ccb4e55e..c20ec184f34f4 100644
--- a/clang/lib/AST/ByteCode/Record.cpp
+++ b/clang/lib/AST/ByteCode/Record.cpp
@@ -50,10 +50,8 @@ const Record::Base *Record::getBase(const RecordDecl *FD) const {
 }
 
 const Record::Base *Record::getBase(QualType T) const {
-  if (auto *RT = T->getAs<RecordType>()) {
-    const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+  if (auto *RD = T->getAsCXXRecordDecl())
     return BaseMap.lookup(RD);
-  }
   return nullptr;
 }
 
diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp
index e4b77edc063dc..0ced210900b1a 100644
--- a/clang/lib/AST/CXXInheritance.cpp
+++ b/clang/lib/AST/CXXInheritance.cpp
@@ -128,17 +128,11 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches) const {
   const CXXRecordDecl *Record = this;
   while (true) {
     for (const auto &I : Record->bases()) {
-      const RecordType *Ty = I.getType()->getAs<RecordType>();
-      if (!Ty)
+      const auto *Base = I.getType()->getAsCXXRecordDecl();
+      if (!Base || !(Base->isBeingDefined() || Base->isCompleteDefinition()))
         return false;
-
-      CXXRecordDecl *Base = cast_if_present<CXXRecordDecl>(
-          Ty->getOriginalDecl()->getDefinition());
-      if (!Base ||
-          (Base->isDependentContext() &&
-           !Base->isCurrentInstantiation(Record))) {
+      if (Base->isDependentContext() && !Base->isCurrentInstantiation(Record))
         return false;
-      }
 
       Queue.push_back(Base);
       if (!BaseMatches(Base))
@@ -255,9 +249,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
         const TemplateSpecializationType *TST =
             BaseSpec.getType()->getAs<TemplateSpecializationType>();
         if (!TST) {
-          if (auto *RT = BaseSpec.getType()->getAs<RecordType>())
-            BaseRecord = cast<CXXRecordDecl>(RT->getOriginalDecl())
-                             ->getDefinitionOrSelf();
+          BaseRecord = BaseSpec.getType()->getAsCXXRecordDecl();
         } else {
           TemplateName TN = TST->getTemplateName();
           if (auto *TD =
@@ -347,11 +339,8 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches,
       // base is a subobject of any other path; if so, then the
       // declaration in this path are hidden by that patch.
       for (const CXXBasePath &HidingP : Paths) {
-        CXXRecordDecl *HidingClass = nullptr;
-        if (const RecordType *Record =
-                HidingP.back().Base->getType()->getAs<RecordType>())
-          HidingClass = cast<CXXRecordDecl>(Record->getOriginalDecl())
-                            ->getDefinitionOrSelf();
+        auto *HidingClass =
+            HidingP.back().Base->getType()->getAsCXXRecordDecl();
         if (!HidingClass)
           break;
 
@@ -470,9 +459,7 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
       = ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())];
 
   for (const auto &Base : RD->bases()) {
-    if (const RecordType *RT = Base.getType()->getAs<RecordType>()) {
-      const CXXRecordDecl *BaseDecl =
-          cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
+    if (const auto *BaseDecl = Base.getType()->getAsCXXRecordDecl()) {
       if (!BaseDecl->isPolymorphic())
         continue;
 
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 4507f415ce606..c44bf739dca2d 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2861,9 +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<RecordType>();
-  if (!Ty ||
-      !Ty->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
+  auto *D = getType()->getAsRecordDecl();
+  if (!D || !D->hasFlexibleArrayMember())
     return false;
   auto *List = dyn_cast<InitListExpr>(getInit()->IgnoreParens());
   if (!List)
@@ -2877,11 +2876,8 @@ bool VarDecl::hasFlexibleArrayInit(const ASTContext &Ctx) const {
 
 CharUnits VarDecl::getFlexibleArrayInitChars(const ASTContext &Ctx) const {
   assert(hasInit() && "Expect initializer to check for flexible a...
[truncated]

@mizvekov mizvekov merged commit dc8596d into main Aug 25, 2025
31 of 32 checks passed
@mizvekov mizvekov deleted the users/mizvekov/GH155028-prep1 branch August 25, 2025 23:18
@llvm-ci
Copy link
Collaborator

llvm-ci commented Aug 26, 2025

LLVM Buildbot has detected a new failure on builder clang-m68k-linux-cross running on suse-gary-m68k-cross while building clang-tools-extra,clang at step 4 "build stage 1".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/27/builds/15121

Here is the relevant piece of the build log for the reference
Step 4 (build stage 1) failure: 'ninja' (failure)
...
      |                                  ~~~~~~~~~~~~~~~~~~~~~
 6820 |                                    ? Scope::FunctionDeclarationScope : 0));
      |                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/lib/Parse/ParseDecl.cpp: In member function ‘void clang::Parser::ParseParenDeclarator(clang::Declarator&)’:
/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/lib/Parse/ParseDecl.cpp:7102:32: warning: enumerated and non-enumerated type in conditional expression [-Wextra]
 7101 |                             (D.isFunctionDeclaratorAFunctionDeclaration()
      |                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 7102 |                                ? Scope::FunctionDeclarationScope : 0));
      |                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[204/1393] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaExpr.cpp.o
FAILED: tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaExpr.cpp.o 
/usr/bin/c++ -DCLANG_EXPORTS -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/stage1/tools/clang/lib/Sema -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/lib/Sema -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/include -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/stage1/tools/clang/include -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/stage1/include -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual -O3 -DNDEBUG -std=c++17  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -MD -MT tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaExpr.cpp.o -MF tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaExpr.cpp.o.d -o tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaExpr.cpp.o -c /var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/lib/Sema/SemaExpr.cpp
In file included from /var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/include/clang/Sema/Sema.h:86,
                 from /var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/lib/Sema/CheckExprLifetime.h:17,
                 from /var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/lib/Sema/SemaExpr.cpp:13:
/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/llvm/include/llvm/ADT/SmallSet.h:280:43: warning: ‘template<class PointerType, unsigned int N> class llvm::DeprecatedSmallSet’ is deprecated: Use SmallPtrSet instead [-Wdeprecated-declarations]
  280 | class SmallSet<PointeeType *, N> : public DeprecatedSmallSet<PointeeType *, N> {
      |                                           ^~~~~~~~~~~~~~~~~~
/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/llvm/include/llvm/ADT/SmallSet.h:277:5: note: declared here
  277 |     DeprecatedSmallSet : public SmallPtrSet<PointerType, N> {};
      |     ^~~~~~~~~~~~~~~~~~
/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/include/clang/Sema/Sema.h:850:7: warning: ‘clang::Sema’ declared with greater visibility than the type of its field ‘clang::Sema::UnusedFileScopedDecls’ [-Wattributes]
  850 | class Sema final : public SemaBase {
      |       ^~~~
/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/include/clang/Sema/Sema.h:850:7: warning: ‘clang::Sema’ declared with greater visibility than the type of its field ‘clang::Sema::TentativeDefinitions’ [-Wattributes]
/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/include/clang/Sema/Sema.h:850:7: warning: ‘clang::Sema’ declared with greater visibility than the type of its field ‘clang::Sema::ExtVectorDecls’ [-Wattributes]
/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/include/clang/Sema/Sema.h:850:7: warning: ‘clang::Sema’ declared with greater visibility than the type of its field ‘clang::Sema::DelegatingCtorDecls’ [-Wattributes]
c++: fatal error: Killed signal terminated program cc1plus
compilation terminated.
[205/1393] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaOpenMP.cpp.o
FAILED: tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaOpenMP.cpp.o 
/usr/bin/c++ -DCLANG_EXPORTS -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/stage1/tools/clang/lib/Sema -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/lib/Sema -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/include -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/stage1/tools/clang/include -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/stage1/include -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual -O3 -DNDEBUG -std=c++17  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -MD -MT tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaOpenMP.cpp.o -MF tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaOpenMP.cpp.o.d -o tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaOpenMP.cpp.o -c /var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/lib/Sema/SemaOpenMP.cpp
In file included from /var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/include/clang/Sema/Sema.h:86,
                 from /var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/include/clang/Sema/Lookup.h:27,
                 from /var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/include/clang/Sema/SemaInternal.h:19,
                 from /var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/lib/Sema/CoroutineStmtBuilder.h:20,
                 from /var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/lib/Sema/TreeTransform.h:16,
                 from /var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/lib/Sema/SemaOpenMP.cpp:16:
/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/llvm/include/llvm/ADT/SmallSet.h:280:43: warning: ‘template<class PointerType, unsigned int N> class llvm::DeprecatedSmallSet’ is deprecated: Use SmallPtrSet instead [-Wdeprecated-declarations]
  280 | class SmallSet<PointeeType *, N> : public DeprecatedSmallSet<PointeeType *, N> {
      |                                           ^~~~~~~~~~~~~~~~~~
/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/llvm/include/llvm/ADT/SmallSet.h:277:5: note: declared here
  277 |     DeprecatedSmallSet : public SmallPtrSet<PointerType, N> {};
      |     ^~~~~~~~~~~~~~~~~~
/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/include/clang/Sema/Sema.h:850:7: warning: ‘clang::Sema’ declared with greater visibility than the type of its field ‘clang::Sema::UnusedFileScopedDecls’ [-Wattributes]
  850 | class Sema final : public SemaBase {
      |       ^~~~
/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/include/clang/Sema/Sema.h:850:7: warning: ‘clang::Sema’ declared with greater visibility than the type of its field ‘clang::Sema::TentativeDefinitions’ [-Wattributes]
/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/include/clang/Sema/Sema.h:850:7: warning: ‘clang::Sema’ declared with greater visibility than the type of its field ‘clang::Sema::ExtVectorDecls’ [-Wattributes]

@zwuis zwuis added the skip-precommit-approval PR for CI feedback, not intended for review label Aug 26, 2025
@shafik
Copy link
Collaborator

shafik commented Aug 28, 2025

I am not sure it makes sense to label such larger changes NFC, anything this large should have at least one review if not more.

This is linked to this regression: #155794

@mizvekov
Copy link
Contributor Author

It was split off from another PR, which had reviewers.

mizvekov added a commit that referenced this pull request Aug 28, 2025
The regression was introduced in #155313

Since this regression was never released, there are no release notes.

Fixes #155794
mizvekov added a commit that referenced this pull request Aug 28, 2025
…155904)

The regression was introduced in #155313

Since this regression was never released, there are no release notes.

Fixes #155794
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:AArch64 backend:AMDGPU backend:ARM backend:CSKY backend:PowerPC backend:SystemZ backend:X86 clang:analysis clang:as-a-library libclang and C++ API clang:bytecode Issues for the clang bytecode constexpr interpreter clang:codegen IR generation bugs: mangling, exceptions, etc. clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules clang:static analyzer clang Clang issues not falling into any other category clang-tidy clang-tools-extra ClangIR Anything related to the ClangIR project HLSL HLSL Language Support skip-precommit-approval PR for CI feedback, not intended for review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants