aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Serialization/ASTWriter.cpp
diff options
context:
space:
mode:
authorChuanqi Xu <yedeng.yd@linux.alibaba.com>2025-06-23 14:31:21 +0800
committerChuanqi Xu <yedeng.yd@linux.alibaba.com>2025-06-23 14:39:08 +0800
commitfccc6ee7021811a27ab1303d19407f703853ab92 (patch)
tree85cb47f3ecc00413787da78a14c6bdbcebd537a7 /clang/lib/Serialization/ASTWriter.cpp
parent4be4b82e74f1b06f18efd1c6be3582daba2e6739 (diff)
downloadllvm-fccc6ee7021811a27ab1303d19407f703853ab92.zip
llvm-fccc6ee7021811a27ab1303d19407f703853ab92.tar.gz
llvm-fccc6ee7021811a27ab1303d19407f703853ab92.tar.bz2
[C++20] [Modules] Don't make enum constant members always visible
Close https://github.com/llvm/llvm-project/issues/131058 See the comments in ASTWriter.cpp:ASTDeclContextNameLookupTrait::getLookupVisibility and SemaLookup.cpp:Sema::makeMergedDefinitionVisible for details.
Diffstat (limited to 'clang/lib/Serialization/ASTWriter.cpp')
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp32
1 files changed, 31 insertions, 1 deletions
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index af7229d..c6487c5 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -4331,9 +4331,36 @@ private:
return LookupVisibility::ModuleLocalVisible;
if (isTULocalInNamedModules(D))
return LookupVisibility::TULocal;
+
+ // A trick to handle enum constants. The enum constants is special since
+ // they can be found directly without their parent context. This makes it
+ // tricky to decide if an EnumConstantDecl is visible or not by their own
+ // visibilities. E.g., for a class member, we can assume it is visible if
+ // the user get its parent somehow. But for an enum constant, the users may
+ // access if without its parent context. Although we can fix the problem in
+ // Sema lookup process, it might be too complex, we just make a trick here.
+ // Note that we only removes enum constant from the lookup table from its
+ // parent of parent. We DON'T remove the enum constant from its parent. So
+ // we don't need to care about merging problems here.
+ if (auto *ECD = dyn_cast<EnumConstantDecl>(D);
+ ECD && DC.isFileContext() && ECD->getOwningModule() &&
+ ECD->getTopLevelOwningNamedModule()->isNamedModule()) {
+ if (llvm::all_of(
+ DC.noload_lookup(
+ cast<EnumDecl>(ECD->getDeclContext())->getDeclName()),
+ [](auto *Found) {
+ return Found->isInvisibleOutsideTheOwningModule();
+ }))
+ return ECD->isFromExplicitGlobalModule() ||
+ ECD->isInAnonymousNamespace()
+ ? LookupVisibility::TULocal
+ : LookupVisibility::ModuleLocalVisible;
+ }
+
return LookupVisibility::GenerallyVisibile;
}
+ DeclContext &DC;
ModuleLevelDeclsMapTy ModuleLocalDeclsMap;
TULocalDeclsMapTy TULocalDeclsMap;
@@ -4341,6 +4368,9 @@ public:
using ASTDeclContextNameTrivialLookupTrait::
ASTDeclContextNameTrivialLookupTrait;
+ ASTDeclContextNameLookupTrait(ASTWriter &Writer, DeclContext &DC)
+ : ASTDeclContextNameTrivialLookupTrait(Writer), DC(DC) {}
+
template <typename Coll> data_type getData(const Coll &Decls) {
unsigned Start = DeclIDs.size();
for (NamedDecl *D : Decls) {
@@ -4612,7 +4642,7 @@ void ASTWriter::GenerateNameLookupTable(
MultiOnDiskHashTableGenerator<reader::ASTDeclContextNameLookupTrait,
ASTDeclContextNameLookupTrait>
Generator;
- ASTDeclContextNameLookupTrait Trait(*this);
+ ASTDeclContextNameLookupTrait Trait(*this, *DC);
// The first step is to collect the declaration names which we need to
// serialize into the name lookup table, and to collect them in a stable