[clang] [clang-tools-extra] [lldb] [Clang][AST][NFC] (`RecordDecl` -> `CXXRecordDecl`)`::isInjectedClassName` (PR #148195)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 11 03:34:10 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-tools-extra
@llvm/pr-subscribers-clangd
Author: Yanzuo Liu (zwuis)
<details>
<summary>Changes</summary>
Co-authored-by: Matheus Izvekov <mizvekov@<!-- -->gmail.com>
---
Full diff: https://github.com/llvm/llvm-project/pull/148195.diff
10 Files Affected:
- (modified) clang-tools-extra/clangd/CodeComplete.cpp (+1-1)
- (modified) clang-tools-extra/clangd/Quality.cpp (+1-1)
- (modified) clang-tools-extra/clangd/SemanticHighlighting.cpp (+1-1)
- (modified) clang/include/clang/AST/Decl.h (-15)
- (modified) clang/include/clang/AST/DeclCXX.h (+16-2)
- (modified) clang/lib/AST/Decl.cpp (-5)
- (modified) clang/lib/AST/DeclCXX.cpp (+10)
- (modified) clang/lib/Sema/SemaAccess.cpp (+2-1)
- (modified) lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp (+1-1)
- (modified) lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp (+4-1)
``````````diff
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);
``````````
</details>
https://github.com/llvm/llvm-project/pull/148195
More information about the cfe-commits
mailing list