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
@apolloww
Copy link
Contributor

This pr caused an assertion failure in our internal codebase. A minimal repro: https://godbolt.org/z/vTWWfE3no

mizvekov added a commit that referenced this pull request Aug 30, 2025
Use the castAs acessor for the type for a UsingEnumDecl,
as it can be sugar for an EnumType.

Fixes a regression reported here: #155313 (comment)

Since this regression was never released, there are no release notes.
mizvekov added a commit that referenced this pull request Aug 30, 2025
Use the castAs acessor for the type for a UsingEnumDecl, as it can be
sugar for an EnumType.

Fixes a regression reported here:
#155313 (comment)

Since this regression was never released, there are no release notes.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Aug 30, 2025
Use the castAs acessor for the type for a UsingEnumDecl, as it can be
sugar for an EnumType.

Fixes a regression reported here:
llvm/llvm-project#155313 (comment)

Since this regression was never released, there are no release notes.
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.

6 participants