diff options
author | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2025-06-23 14:31:21 +0800 |
---|---|---|
committer | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2025-06-23 14:39:08 +0800 |
commit | fccc6ee7021811a27ab1303d19407f703853ab92 (patch) | |
tree | 85cb47f3ecc00413787da78a14c6bdbcebd537a7 /clang/lib/Serialization/ASTWriter.cpp | |
parent | 4be4b82e74f1b06f18efd1c6be3582daba2e6739 (diff) | |
download | llvm-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.cpp | 32 |
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 |