Skip to content

[C++20] [Modules] Support module level lookup (#122887) #123281

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

Merged
merged 1 commit into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,8 @@ C++23 Feature Support
C++20 Feature Support
^^^^^^^^^^^^^^^^^^^^^

- Implemented module level lookup for C++20 modules. (#GH90154)


Resolutions to C++ Defect Reports
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/AST/DeclBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,10 @@ class alignas(8) Decl {
return isFromASTFile() ? getImportedOwningModule() : getLocalOwningModule();
}

/// Get the top level owning named module that owns this declaration if any.
/// \returns nullptr if the declaration is not owned by a named module.
Module *getTopLevelOwningNamedModule() const;

/// Get the module that owns this declaration for linkage purposes.
/// There only ever is such a standard C++ module.
Module *getOwningModuleForLinkage() const;
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,8 @@ enum ASTRecordTypes {
CXX_ADDED_TEMPLATE_SPECIALIZATION = 74,

CXX_ADDED_TEMPLATE_PARTIAL_SPECIALIZATION = 75,

UPDATE_MODULE_LOCAL_VISIBLE = 76,
};

/// Record types used within a source manager block.
Expand Down Expand Up @@ -1334,6 +1336,10 @@ enum DeclCode {
/// into a DeclContext via DeclContext::lookup.
DECL_CONTEXT_VISIBLE,

/// A record containing the set of declarations that are
/// only visible from DeclContext in the same module.
DECL_CONTEXT_MODULE_LOCAL_VISIBLE,

/// A LabelDecl record.
DECL_LABEL,

Expand Down
29 changes: 26 additions & 3 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ class ASTIdentifierLookupTrait;

/// The on-disk hash table(s) used for DeclContext name lookup.
struct DeclContextLookupTable;
struct ModuleLocalLookupTable;

/// The on-disk hash table(s) used for specialization decls.
struct LazySpecializationInfoLookupTable;
Expand Down Expand Up @@ -523,9 +524,14 @@ class ASTReader
/// in the chain.
DeclUpdateOffsetsMap DeclUpdateOffsets;

struct LookupBlockOffsets {
uint64_t LexicalOffset;
uint64_t VisibleOffset;
uint64_t ModuleLocalOffset;
};

using DelayedNamespaceOffsetMapTy =
llvm::DenseMap<GlobalDeclID, std::pair</*LexicalOffset*/ uint64_t,
/*VisibleOffset*/ uint64_t>>;
llvm::DenseMap<GlobalDeclID, LookupBlockOffsets>;

/// Mapping from global declaration IDs to the lexical and visible block
/// offset for delayed namespace in reduced BMI.
Expand Down Expand Up @@ -631,6 +637,9 @@ class ASTReader
/// Map from a DeclContext to its lookup tables.
llvm::DenseMap<const DeclContext *,
serialization::reader::DeclContextLookupTable> Lookups;
llvm::DenseMap<const DeclContext *,
serialization::reader::ModuleLocalLookupTable>
ModuleLocalLookups;

using SpecLookupTableTy =
llvm::DenseMap<const Decl *,
Expand Down Expand Up @@ -659,6 +668,8 @@ class ASTReader
/// Updates to the visible declarations of declaration contexts that
/// haven't been loaded yet.
llvm::DenseMap<GlobalDeclID, DeclContextVisibleUpdates> PendingVisibleUpdates;
llvm::DenseMap<GlobalDeclID, DeclContextVisibleUpdates>
PendingModuleLocalVisibleUpdates;

using SpecializationsUpdate = SmallVector<UpdateData, 1>;
using SpecializationsUpdateMap =
Expand Down Expand Up @@ -696,7 +707,8 @@ class ASTReader
/// Read the record that describes the visible contents of a DC.
bool ReadVisibleDeclContextStorage(ModuleFile &M,
llvm::BitstreamCursor &Cursor,
uint64_t Offset, GlobalDeclID ID);
uint64_t Offset, GlobalDeclID ID,
bool IsModuleLocal);

bool ReadSpecializations(ModuleFile &M, llvm::BitstreamCursor &Cursor,
uint64_t Offset, Decl *D, bool IsPartial);
Expand Down Expand Up @@ -1132,6 +1144,10 @@ class ASTReader
/// Number of visible decl contexts read/total.
unsigned NumVisibleDeclContextsRead = 0, TotalVisibleDeclContexts = 0;

/// Number of module local visible decl contexts read/total.
unsigned NumModuleLocalVisibleDeclContexts = 0,
TotalModuleLocalVisibleDeclContexts = 0;

/// Total size of modules, in bits, currently loaded
uint64_t TotalModulesSizeInBits = 0;

Expand Down Expand Up @@ -1444,6 +1460,9 @@ class ASTReader
const serialization::reader::DeclContextLookupTable *
getLoadedLookupTables(DeclContext *Primary) const;

const serialization::reader::ModuleLocalLookupTable *
getModuleLocalLookupTables(DeclContext *Primary) const;

/// Get the loaded specializations lookup tables for \p D,
/// if any.
serialization::reader::LazySpecializationInfoLookupTable *
Expand Down Expand Up @@ -2608,6 +2627,10 @@ inline bool shouldSkipCheckingODR(const Decl *D) {
(D->isFromGlobalModule() || D->isFromHeaderUnit());
}

/// Calculate a hash value for the primary module name of the given module.
/// \returns std::nullopt if M is not a C++ standard module.
std::optional<unsigned> getPrimaryModuleHash(const Module *M);

} // namespace clang

#endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H
16 changes: 13 additions & 3 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,10 @@ class ASTWriter : public ASTDeserializationListener,
/// file.
unsigned NumVisibleDeclContexts = 0;

/// The number of module local visible declcontexts written to the AST
/// file.
unsigned NumModuleLocalDeclContexts = 0;

/// A mapping from each known submodule to its ID number, which will
/// be a positive integer.
llvm::DenseMap<const Module *, unsigned> SubmoduleIDs;
Expand Down Expand Up @@ -587,11 +591,15 @@ class ASTWriter : public ASTDeserializationListener,
uint64_t WriteSpecializationInfoLookupTable(
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
bool IsPartial);
void GenerateNameLookupTable(ASTContext &Context, const DeclContext *DC,
llvm::SmallVectorImpl<char> &LookupTable);
void
GenerateNameLookupTable(ASTContext &Context, const DeclContext *DC,
llvm::SmallVectorImpl<char> &LookupTable,
llvm::SmallVectorImpl<char> &ModuleLocalLookupTable);
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context,
const DeclContext *DC);
uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
void WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC,
uint64_t &VisibleBlockOffset,
uint64_t &ModuleLocalBlockOffset);
void WriteTypeDeclOffsets();
void WriteFileDeclIDsMap();
void WriteComments(ASTContext &Context);
Expand Down Expand Up @@ -624,7 +632,9 @@ class ASTWriter : public ASTDeserializationListener,
unsigned DeclParmVarAbbrev = 0;
unsigned DeclContextLexicalAbbrev = 0;
unsigned DeclContextVisibleLookupAbbrev = 0;
unsigned DeclModuleLocalVisibleLookupAbbrev = 0;
unsigned UpdateVisibleAbbrev = 0;
unsigned ModuleLocalUpdateVisibleAbbrev = 0;
unsigned DeclRecordAbbrev = 0;
unsigned DeclTypedefAbbrev = 0;
unsigned DeclVarAbbrev = 0;
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/AST/DeclBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ void Decl::setOwningModuleID(unsigned ID) {
*IDAddress |= (uint64_t)ID << 48;
}

Module *Decl::getTopLevelOwningNamedModule() const {
if (getOwningModule() &&
getOwningModule()->getTopLevelModule()->isNamedModule())
return getOwningModule()->getTopLevelModule();

return nullptr;
}

Module *Decl::getOwningModuleSlow() const {
assert(isFromASTFile() && "Not from AST file?");
return getASTContext().getExternalSource()->getModule(getOwningModuleID());
Expand Down
Loading
Loading