Skip to content

Commit 1328dca

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 21c390f commit 1328dca

File tree

2 files changed

+65
-42
lines changed

2 files changed

+65
-42
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 &typecheckOpts,
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 &typecheckOpts,
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: 44 additions & 32 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,14 @@ 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 &typecheckOpts,
584+
SILOptions &silOpts, SearchPathOptions &SearchPathOpts,
585+
ClangImporterOptions &ClangImporterOpts,
586+
symbolgraphgen::SymbolGraphOptions &SymbolGraphOpts,
587+
SourceManager &SourceMgr, DiagnosticEngine &Diags,
588+
std::function<bool(llvm::StringRef, bool)> PreModuleImportCallback) {
589+
// If more than two data structures are concatentated, then the aggregate
588590
// size math needs to become more complicated due to per-struct alignment
589591
// constraints.
590592
auto align = std::max(alignof(ASTContext), alignof(Implementation));
@@ -594,19 +596,22 @@ ASTContext *ASTContext::get(LangOptions &langOpts,
594596
impl = reinterpret_cast<void *>(
595597
llvm::alignAddr(impl, llvm::Align(alignof(Implementation))));
596598
new (impl) Implementation();
597-
return new (mem)
598-
ASTContext(langOpts, typecheckOpts, silOpts, SearchPathOpts,
599-
ClangImporterOpts, SymbolGraphOpts, SourceMgr, Diags);
600-
}
601-
602-
ASTContext::ASTContext(LangOptions &langOpts, TypeCheckerOptions &typecheckOpts,
603-
SILOptions &silOpts, SearchPathOptions &SearchPathOpts,
604-
ClangImporterOptions &ClangImporterOpts,
605-
symbolgraphgen::SymbolGraphOptions &SymbolGraphOpts,
606-
SourceManager &SourceMgr, DiagnosticEngine &Diags)
599+
return new (mem) ASTContext(langOpts, typecheckOpts, silOpts, SearchPathOpts,
600+
ClangImporterOpts, SymbolGraphOpts, SourceMgr,
601+
Diags, PreModuleImportCallback);
602+
}
603+
604+
ASTContext::ASTContext(
605+
LangOptions &langOpts, TypeCheckerOptions &typecheckOpts,
606+
SILOptions &silOpts, SearchPathOptions &SearchPathOpts,
607+
ClangImporterOptions &ClangImporterOpts,
608+
symbolgraphgen::SymbolGraphOptions &SymbolGraphOpts,
609+
SourceManager &SourceMgr, DiagnosticEngine &Diags,
610+
std::function<bool(llvm::StringRef, bool)> PreModuleImportCallback)
607611
: LangOpts(langOpts), TypeCheckerOpts(typecheckOpts), SILOpts(silOpts),
608612
SearchPathOpts(SearchPathOpts), ClangImporterOpts(ClangImporterOpts),
609613
SymbolGraphOpts(SymbolGraphOpts), SourceMgr(SourceMgr), Diags(Diags),
614+
PreModuleImportCallback(PreModuleImportCallback),
610615
evaluator(Diags, langOpts), TheBuiltinModule(createBuiltinModule(*this)),
611616
StdlibModuleName(getIdentifier(STDLIB_NAME)),
612617
SwiftShimsModuleName(getIdentifier(SWIFT_SHIMS_NAME)),
@@ -622,18 +627,18 @@ ASTContext::ASTContext(LangOptions &langOpts, TypeCheckerOptions &typecheckOpts,
622627
The##SHORT_ID##Type(new (*this, AllocationArena::Permanent) \
623628
ID##Type(*this)),
624629
#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)) {
630+
TheIEEE32Type(new (*this, AllocationArena::Permanent)
631+
BuiltinFloatType(BuiltinFloatType::IEEE32, *this)),
632+
TheIEEE64Type(new (*this, AllocationArena::Permanent)
633+
BuiltinFloatType(BuiltinFloatType::IEEE64, *this)),
634+
TheIEEE16Type(new (*this, AllocationArena::Permanent)
635+
BuiltinFloatType(BuiltinFloatType::IEEE16, *this)),
636+
TheIEEE80Type(new (*this, AllocationArena::Permanent)
637+
BuiltinFloatType(BuiltinFloatType::IEEE80, *this)),
638+
TheIEEE128Type(new (*this, AllocationArena::Permanent)
639+
BuiltinFloatType(BuiltinFloatType::IEEE128, *this)),
640+
ThePPC128Type(new (*this, AllocationArena::Permanent)
641+
BuiltinFloatType(BuiltinFloatType::PPC128, *this)) {
637642

638643
// Initialize all of the known identifiers.
639644
#define IDENTIFIER_WITH_NAME(Name, IdStr) Id_##Name = getIdentifier(IdStr);
@@ -2211,6 +2216,8 @@ ASTContext::getModule(ImportPath::Module ModulePath) {
22112216
return M;
22122217

22132218
auto moduleID = ModulePath[0];
2219+
if (PreModuleImportCallback)
2220+
PreModuleImportCallback(moduleID.Item.str(), false /*=IsOverlay*/);
22142221
for (auto &importer : getImpl().ModuleLoaders) {
22152222
if (ModuleDecl *M = importer->loadModule(moduleID.Loc, ModulePath)) {
22162223
if (LangOpts.EnableModuleLoadingRemarks) {
@@ -2235,12 +2242,17 @@ ModuleDecl *ASTContext::getOverlayModule(const FileUnit *FU) {
22352242
return Existing;
22362243
}
22372244

2245+
if (PreModuleImportCallback) {
2246+
SmallString<16> path;
2247+
ModPath.getString(path);
2248+
if (!path.empty())
2249+
PreModuleImportCallback(path.str(), /*IsOverlay=*/true);
2250+
}
22382251
for (auto &importer : getImpl().ModuleLoaders) {
22392252
if (importer.get() == getClangModuleLoader())
22402253
continue;
2241-
if (ModuleDecl *M = importer->loadModule(SourceLoc(), ModPath)) {
2254+
if (ModuleDecl *M = importer->loadModule(SourceLoc(), ModPath))
22422255
return M;
2243-
}
22442256
}
22452257

22462258
return nullptr;

0 commit comments

Comments
 (0)