-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[Clang][AST][NFC] (RecordDecl
-> CXXRecordDecl
)::isInjectedClassName
#148195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clangd Author: Yanzuo Liu (zwuis) ChangesCo-authored-by: Matheus Izvekov <[email protected]> Full diff: https://github.com/llvm/llvm-project/pull/148195.diff 10 Files Affected:
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);
|
@llvm/pr-subscribers-lldb Author: Yanzuo Liu (zwuis) ChangesCo-authored-by: Matheus Izvekov <[email protected]> Full diff: https://github.com/llvm/llvm-project/pull/148195.diff 10 Files Affected:
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);
|
I'm not sure if I should update |
Can you provide a more detailed description? Thanks! |
Why would you need to? There are no changes to mangling/demangling here AFAICT |
These files test demangling |
This file uses these symbols as test cases, but they are just examples and aren't coupled to the clang implementation at all, the tests are still valid, even if these were originally constructed from clang as an example. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
For reference, this takes this change out of #147835, which reduces the size of that PR a little bit.
@cor3ntin Updated. Are you happy with current PR description? |
Thanks for your review. |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/26685 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/18/builds/18898 Here is the relevant piece of the build log for the reference
|
Move
RecordDecl::isInjectedClassName
toCXXRecordDecl::isInjectedClassName
. C language doesn't have the term "injected class name".Co-authored-by: Matheus Izvekov [email protected]