Author: Yanzuo Liu Date: 2025-07-12T21:13:30+08:00 New Revision: c4cc3573d144831d2815433646ffcab62cc9ea40
URL: https://github.com/llvm/llvm-project/commit/c4cc3573d144831d2815433646ffcab62cc9ea40 DIFF: https://github.com/llvm/llvm-project/commit/c4cc3573d144831d2815433646ffcab62cc9ea40.diff LOG: [Clang][AST][NFC] (`RecordDecl` -> `CXXRecordDecl`)`::isInjectedClassName` (#148195) Move `RecordDecl::isInjectedClassName` to `CXXRecordDecl::isInjectedClassName`. C language doesn't have the term "injected class name". Co-authored-by: Matheus Izvekov <mizve...@gmail.com> Added: Modified: clang-tools-extra/clangd/CodeComplete.cpp clang-tools-extra/clangd/Quality.cpp clang-tools-extra/clangd/SemanticHighlighting.cpp clang/include/clang/AST/Decl.h clang/include/clang/AST/DeclCXX.h clang/lib/AST/Decl.cpp clang/lib/AST/DeclCXX.cpp clang/lib/Sema/SemaAccess.cpp lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp index 14679fea6ac8a..d5907e3143bf6 100644 --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -870,7 +870,7 @@ bool contextAllowsIndex(enum CodeCompletionContext::Kind K) { } static bool isInjectedClass(const NamedDecl &D) { - if (auto *R = dyn_cast_or_null<RecordDecl>(&D)) + if (auto *R = dyn_cast_or_null<CXXRecordDecl>(&D)) if (R->isInjectedClassName()) return true; return false; diff --git a/clang-tools-extra/clangd/Quality.cpp b/clang-tools-extra/clangd/Quality.cpp index c1ab63fb22f61..3f630b05c654b 100644 --- a/clang-tools-extra/clangd/Quality.cpp +++ b/clang-tools-extra/clangd/Quality.cpp @@ -258,7 +258,7 @@ static SymbolRelevanceSignals::AccessibleScope computeScope(const NamedDecl *D) { // Injected "Foo" within the class "Foo" has file scope, not class scope. const DeclContext *DC = D->getDeclContext(); - if (auto *R = dyn_cast_or_null<RecordDecl>(D)) + if (auto *R = dyn_cast_or_null<CXXRecordDecl>(D)) if (R->isInjectedClassName()) DC = DC->getParent(); // Class constructor should have the same scope as the class. diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp index dc574dcd11703..e6d5cf7053694 100644 --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -597,7 +597,7 @@ class HighlightingsBuilder { std::optional<HighlightingModifier> scopeModifier(const NamedDecl *D) { const DeclContext *DC = D->getDeclContext(); // Injected "Foo" within the class "Foo" has file scope, not class scope. - if (auto *R = dyn_cast_or_null<RecordDecl>(D)) + if (auto *R = dyn_cast_or_null<CXXRecordDecl>(D)) if (R->isInjectedClassName()) DC = DC->getParent(); // Lambda captures are considered function scope, not class scope. diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index de79a9df29a5b..3d7969cca83fd 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -4420,21 +4420,6 @@ class RecordDecl : public TagDecl { void reorderDecls(const SmallVectorImpl<Decl *> &Decls); - /// Determines whether this declaration represents the - /// injected class name. - /// - /// The injected class name in C++ is the name of the class that - /// appears inside the class itself. For example: - /// - /// \code - /// struct C { - /// // C is implicitly declared here as a synonym for the class name. - /// }; - /// - /// C::C c; // same as "C c;" - /// \endcode - bool isInjectedClassName() const; - /// Determine whether this record is a class describing a lambda /// function object. bool isLambda() const; diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 05cddd024d7cf..77bc3cad72ed9 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -546,8 +546,7 @@ class CXXRecordDecl : public RecordDecl { } CXXRecordDecl *getMostRecentNonInjectedDecl() { - CXXRecordDecl *Recent = - static_cast<CXXRecordDecl *>(this)->getMostRecentDecl(); + CXXRecordDecl *Recent = getMostRecentDecl(); while (Recent->isInjectedClassName()) { // FIXME: Does injected class name need to be in the redeclarations chain? assert(Recent->getPreviousDecl()); @@ -1889,6 +1888,21 @@ class CXXRecordDecl : public RecordDecl { DL.IsGenericLambda = IsGeneric; } + /// Determines whether this declaration represents the + /// injected class name. + /// + /// The injected class name in C++ is the name of the class that + /// appears inside the class itself. For example: + /// + /// \code + /// struct C { + /// // C is implicitly declared here as a synonym for the class name. + /// }; + /// + /// C::C c; // same as "C c;" + /// \endcode + bool isInjectedClassName() const; + // Determine whether this type is an Interface Like type for // __interface inheritance purposes. bool isInterfaceLike() const; diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 8855d0107daca..bd1b5950d30a6 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -5136,11 +5136,6 @@ RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, return R; } -bool RecordDecl::isInjectedClassName() const { - return isImplicit() && getDeclName() && getDeclContext()->isRecord() && - cast<RecordDecl>(getDeclContext())->getDeclName() == getDeclName(); -} - bool RecordDecl::isLambda() const { if (auto RD = dyn_cast<CXXRecordDecl>(this)) return RD->isLambda(); diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index ccb308e103253..4514965009793 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -2149,6 +2149,16 @@ bool CXXRecordDecl::hasDeletedDestructor() const { return false; } +bool CXXRecordDecl::isInjectedClassName() const { + if (!isImplicit() || !getDeclName()) + return false; + + if (const auto *RD = dyn_cast<CXXRecordDecl>(getDeclContext())) + return RD->getDeclName() == getDeclName(); + + return false; +} + static bool isDeclContextInNamespace(const DeclContext *DC) { while (!DC->isTranslationUnit()) { if (DC->isNamespace()) diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index 39328b76a10c4..83a07a23f3414 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/lib/Sema/SemaAccess.cpp @@ -1129,7 +1129,8 @@ static void diagnoseBadDirectAccess(Sema &S, else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D)) PrevDecl = TND->getPreviousDecl(); else if (TagDecl *TD = dyn_cast<TagDecl>(D)) { - if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName()) + if (auto *RD = dyn_cast<CXXRecordDecl>(D); + RD && RD->isInjectedClassName()) break; PrevDecl = TD->getPreviousDecl(); } diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp index c8c8ba53e3bae..2529e78f78bca 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp @@ -288,7 +288,7 @@ class CompleteTagDeclsScope : public ClangASTImporter::NewDeclListener { // Filter out decls that we can't complete later. if (!isa<TagDecl>(to) && !isa<ObjCInterfaceDecl>(to)) return; - RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from); + auto *from_record_decl = dyn_cast<CXXRecordDecl>(from); // We don't need to complete injected class name decls. if (from_record_decl && from_record_decl->isInjectedClassName()) return; diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 82e07bb8e0ffb..bafe9d56a93bf 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -2420,9 +2420,12 @@ void TypeSystemClang::DumpDeclHiearchy(clang::Decl *decl) { clang::RecordDecl *record_decl = llvm::dyn_cast<clang::RecordDecl>(decl); if (record_decl) { + bool is_injected_class_name = + llvm::isa<clang::CXXRecordDecl>(record_decl) && + llvm::cast<CXXRecordDecl>(record_decl)->isInjectedClassName(); printf("%20s: %s%s\n", decl->getDeclKindName(), record_decl->getDeclName().getAsString().c_str(), - record_decl->isInjectedClassName() ? " (injected class name)" : ""); + is_injected_class_name ? " (injected class name)" : ""); } else { clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits