Skip to content

Commit 38146fc

Browse files
committed
[AST] Add mechanism to notify module loading to other clients
This patch adds an optional callback function member to the AST Context. The callback gets invoked when a new module (or overlay module) gets loaded. This can be used for instance by other clients, such as lldb, to perform actions when a module gets loaded, like showing progress to the end-user. rdar://94165195 Signed-off-by: Med Ismail Bennani <[email protected]>
1 parent 53f5767 commit 38146fc

File tree

2 files changed

+61
-40
lines changed

2 files changed

+61
-40
lines changed

include/swift/AST/ASTContext.h

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,13 @@ class ASTContext final {
223223
ASTContext(const ASTContext&) = delete;
224224
void operator=(const ASTContext&) = delete;
225225

226-
ASTContext(LangOptions &langOpts, TypeCheckerOptions &typecheckOpts,
227-
SILOptions &silOpts, SearchPathOptions &SearchPathOpts,
228-
ClangImporterOptions &ClangImporterOpts,
229-
symbolgraphgen::SymbolGraphOptions &SymbolGraphOpts,
230-
SourceManager &SourceMgr, DiagnosticEngine &Diags);
226+
ASTContext(
227+
LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
228+
SILOptions &silOpts, SearchPathOptions &SearchPathOpts,
229+
ClangImporterOptions &ClangImporterOpts,
230+
symbolgraphgen::SymbolGraphOptions &SymbolGraphOpts,
231+
SourceManager &SourceMgr, DiagnosticEngine &Diags,
232+
std::function<bool(llvm::StringRef, bool)> PreModuleImportCallback = {});
231233

232234
public:
233235
// Members that should only be used by ASTContext.cpp.
@@ -238,11 +240,13 @@ class ASTContext final {
238240

239241
void operator delete(void *Data) throw();
240242

241-
static ASTContext *get(LangOptions &langOpts, TypeCheckerOptions &typecheckOpts,
242-
SILOptions &silOpts, SearchPathOptions &SearchPathOpts,
243-
ClangImporterOptions &ClangImporterOpts,
244-
symbolgraphgen::SymbolGraphOptions &SymbolGraphOpts,
245-
SourceManager &SourceMgr, DiagnosticEngine &Diags);
243+
static ASTContext *
244+
get(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
245+
SILOptions &silOpts, SearchPathOptions &SearchPathOpts,
246+
ClangImporterOptions &ClangImporterOpts,
247+
symbolgraphgen::SymbolGraphOptions &SymbolGraphOpts,
248+
SourceManager &SourceMgr, DiagnosticEngine &Diags,
249+
std::function<bool(llvm::StringRef, bool)> PreModuleImportCallback = {});
246250
~ASTContext();
247251

248252
/// Optional table of counters to report, nullptr when not collecting.
@@ -374,6 +378,10 @@ class ASTContext final {
374378
llvm::BumpPtrAllocator &
375379
getAllocator(AllocationArena arena = AllocationArena::Permanent) const;
376380

381+
/// An optional generic callback function invoked prior to importing a module.
382+
mutable std::function<bool(llvm::StringRef ModuleName, bool IsOverlay)>
383+
PreModuleImportCallback;
384+
377385
public:
378386
/// Allocate - Allocate memory from the ASTContext bump pointer.
379387
void *Allocate(unsigned long bytes, unsigned alignment,
@@ -1107,6 +1115,9 @@ class ASTContext final {
11071115
/// If a module by this name has already been loaded, the existing module will
11081116
/// be returned.
11091117
///
1118+
/// \param ModulePath The module's \c ImportPath which describes
1119+
/// the name of the module being loaded, possibly including submodules.
1120+
11101121
/// \returns The requested module, or NULL if the module cannot be found.
11111122
ModuleDecl *getModule(ImportPath::Module ModulePath);
11121123

lib/AST/ASTContext.cpp

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@
4242
#include "swift/AST/PropertyWrappers.h"
4343
#include "swift/AST/ProtocolConformance.h"
4444
#include "swift/AST/RawComment.h"
45-
#include "swift/AST/SearchPathOptions.h"
4645
#include "swift/AST/SILLayout.h"
46+
#include "swift/AST/SearchPathOptions.h"
4747
#include "swift/AST/SemanticAttrs.h"
4848
#include "swift/AST/SourceFile.h"
4949
#include "swift/AST/SubstitutionMap.h"
@@ -65,6 +65,7 @@
6565
#include "llvm/IR/LLVMContext.h"
6666
#include "llvm/Support/Allocator.h"
6767
#include "llvm/Support/Compiler.h"
68+
#include "llvm/Support/FormatVariadic.h"
6869
#include <algorithm>
6970
#include <memory>
7071

@@ -578,13 +579,13 @@ void ASTContext::operator delete(void *Data) throw() {
578579
AlignedFree(Data);
579580
}
580581

581-
ASTContext *ASTContext::get(LangOptions &langOpts,
582-
TypeCheckerOptions &typecheckOpts, SILOptions &silOpts,
583-
SearchPathOptions &SearchPathOpts,
584-
ClangImporterOptions &ClangImporterOpts,
585-
symbolgraphgen::SymbolGraphOptions &SymbolGraphOpts,
586-
SourceManager &SourceMgr, DiagnosticEngine &Diags) {
587-
// If more than two data structures are concatenated, then the aggregate
582+
ASTContext *ASTContext::get(
583+
LangOptions &langOpts, TypeCheckerOptions &typeckOpts, SILOptions &silOpts,
584+
SearchPathOptions &SearchPathOpts, ClangImporterOptions &ClangImporterOpts,
585+
symbolgraphgen::SymbolGraphOptions &SymbolGraphOpts,
586+
SourceManager &SourceMgr, DiagnosticEngine &Diags,
587+
std::function<bool(llvm::StringRef, bool)> PreModuleImportCallback) {
588+
// If more than two data structures are concatentated, then the aggregate
588589
// size math needs to become more complicated due to per-struct alignment
589590
// constraints.
590591
auto align = std::max(alignof(ASTContext), alignof(Implementation));
@@ -594,19 +595,21 @@ ASTContext *ASTContext::get(LangOptions &langOpts,
594595
impl = reinterpret_cast<void *>(
595596
llvm::alignAddr(impl, llvm::Align(alignof(Implementation))));
596597
new (impl) Implementation();
597-
return new (mem)
598-
ASTContext(langOpts, typecheckOpts, silOpts, SearchPathOpts,
599-
ClangImporterOpts, SymbolGraphOpts, SourceMgr, Diags);
598+
return new (mem) ASTContext(langOpts, typeckOpts, silOpts, SearchPathOpts,
599+
ClangImporterOpts, SymbolGraphOpts, SourceMgr,
600+
Diags, PreModuleImportCallback);
600601
}
601602

602-
ASTContext::ASTContext(LangOptions &langOpts, TypeCheckerOptions &typecheckOpts,
603-
SILOptions &silOpts, SearchPathOptions &SearchPathOpts,
604-
ClangImporterOptions &ClangImporterOpts,
605-
symbolgraphgen::SymbolGraphOptions &SymbolGraphOpts,
606-
SourceManager &SourceMgr, DiagnosticEngine &Diags)
603+
ASTContext::ASTContext(
604+
LangOptions &langOpts, TypeCheckerOptions &typeckOpts, SILOptions &silOpts,
605+
SearchPathOptions &SearchPathOpts, ClangImporterOptions &ClangImporterOpts,
606+
symbolgraphgen::SymbolGraphOptions &SymbolGraphOpts,
607+
SourceManager &SourceMgr, DiagnosticEngine &Diags,
608+
std::function<bool(llvm::StringRef, bool)> PreModuleImportCallback)
607609
: LangOpts(langOpts), TypeCheckerOpts(typecheckOpts), SILOpts(silOpts),
608610
SearchPathOpts(SearchPathOpts), ClangImporterOpts(ClangImporterOpts),
609611
SymbolGraphOpts(SymbolGraphOpts), SourceMgr(SourceMgr), Diags(Diags),
612+
PreModuleImportCallback(PreModuleImportCallback),
610613
evaluator(Diags, langOpts), TheBuiltinModule(createBuiltinModule(*this)),
611614
StdlibModuleName(getIdentifier(STDLIB_NAME)),
612615
SwiftShimsModuleName(getIdentifier(SWIFT_SHIMS_NAME)),
@@ -622,18 +625,18 @@ ASTContext::ASTContext(LangOptions &langOpts, TypeCheckerOptions &typecheckOpts,
622625
The##SHORT_ID##Type(new (*this, AllocationArena::Permanent) \
623626
ID##Type(*this)),
624627
#include "swift/AST/TypeNodes.def"
625-
TheIEEE32Type(new (*this, AllocationArena::Permanent)
626-
BuiltinFloatType(BuiltinFloatType::IEEE32,*this)),
627-
TheIEEE64Type(new (*this, AllocationArena::Permanent)
628-
BuiltinFloatType(BuiltinFloatType::IEEE64,*this)),
629-
TheIEEE16Type(new (*this, AllocationArena::Permanent)
630-
BuiltinFloatType(BuiltinFloatType::IEEE16,*this)),
631-
TheIEEE80Type(new (*this, AllocationArena::Permanent)
632-
BuiltinFloatType(BuiltinFloatType::IEEE80,*this)),
633-
TheIEEE128Type(new (*this, AllocationArena::Permanent)
634-
BuiltinFloatType(BuiltinFloatType::IEEE128, *this)),
635-
ThePPC128Type(new (*this, AllocationArena::Permanent)
636-
BuiltinFloatType(BuiltinFloatType::PPC128, *this)) {
628+
TheIEEE32Type(new (*this, AllocationArena::Permanent)
629+
BuiltinFloatType(BuiltinFloatType::IEEE32, *this)),
630+
TheIEEE64Type(new (*this, AllocationArena::Permanent)
631+
BuiltinFloatType(BuiltinFloatType::IEEE64, *this)),
632+
TheIEEE16Type(new (*this, AllocationArena::Permanent)
633+
BuiltinFloatType(BuiltinFloatType::IEEE16, *this)),
634+
TheIEEE80Type(new (*this, AllocationArena::Permanent)
635+
BuiltinFloatType(BuiltinFloatType::IEEE80, *this)),
636+
TheIEEE128Type(new (*this, AllocationArena::Permanent)
637+
BuiltinFloatType(BuiltinFloatType::IEEE128, *this)),
638+
ThePPC128Type(new (*this, AllocationArena::Permanent)
639+
BuiltinFloatType(BuiltinFloatType::PPC128, *this)) {
637640

638641
// Initialize all of the known identifiers.
639642
#define IDENTIFIER_WITH_NAME(Name, IdStr) Id_##Name = getIdentifier(IdStr);
@@ -2211,6 +2214,8 @@ ASTContext::getModule(ImportPath::Module ModulePath) {
22112214
return M;
22122215

22132216
auto moduleID = ModulePath[0];
2217+
if (PreModuleImportCallback)
2218+
PreModuleImportCallback(moduleID.Item.str(), false /*=IsOverlay*/);
22142219
for (auto &importer : getImpl().ModuleLoaders) {
22152220
if (ModuleDecl *M = importer->loadModule(moduleID.Loc, ModulePath)) {
22162221
if (LangOpts.EnableModuleLoadingRemarks) {
@@ -2235,12 +2240,17 @@ ModuleDecl *ASTContext::getOverlayModule(const FileUnit *FU) {
22352240
return Existing;
22362241
}
22372242

2243+
if (PreModuleImportCallback) {
2244+
SmallString<16> path;
2245+
ModPath.getString(path);
2246+
if (!path.empty())
2247+
PreModuleImportCallback(path.str(), /*IsOverlay=*/true);
2248+
}
22382249
for (auto &importer : getImpl().ModuleLoaders) {
22392250
if (importer.get() == getClangModuleLoader())
22402251
continue;
2241-
if (ModuleDecl *M = importer->loadModule(SourceLoc(), ModPath)) {
2252+
if (ModuleDecl *M = importer->loadModule(SourceLoc(), ModPath))
22422253
return M;
2243-
}
22442254
}
22452255

22462256
return nullptr;

0 commit comments

Comments
 (0)