Skip to content

Commit e0541b0

Browse files
[Macro][Dependencies] Properly model macro dependencies in the scanner
Add function to handle all macro dependencies kinds in the scanner, including taking care of the macro definitions in the module interface for its client to use. The change involves: * Encode the macro definition inside the binary module * Resolve macro modules in the dependencies scanners, including those declared inside the dependency modules. * Propagate the macro defined from the direct dependencies to track all the potentially available modules inside a module compilation.
1 parent b9dc764 commit e0541b0

20 files changed

+326
-56
lines changed

include/swift/AST/FileUnit.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ class FileUnit : public DeclContext, public ASTAllocated<FileUnit> {
272272
getImportedModules(SmallVectorImpl<ImportedModule> &imports,
273273
ModuleDecl::ImportFilter filter) const {}
274274

275+
/// Looks up which external macros are defined by this file.
276+
virtual void
277+
getExternalMacros(SmallVectorImpl<ExternalMacroPlugin> &macros) const {}
278+
275279
/// Lists modules that are not imported from this file and used in API.
276280
virtual void getImplicitImportsForModuleInterface(
277281
SmallVectorImpl<ImportedModule> &imports) const {}

include/swift/AST/Module.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,19 @@ struct SourceFilePathInfo {
145145
}
146146
};
147147

148+
/// This is used to idenfity an external macro definition.
149+
struct ExternalMacroPlugin {
150+
std::string ModuleName;
151+
152+
enum Access {
153+
Internal = 0,
154+
Package,
155+
Public,
156+
};
157+
158+
Access MacroAccess;
159+
};
160+
148161
/// Discriminator for resilience strategy.
149162
enum class ResilienceStrategy : unsigned {
150163
/// Public nominal types: fragile
@@ -969,6 +982,9 @@ class ModuleDecl
969982
void getImportedModules(SmallVectorImpl<ImportedModule> &imports,
970983
ImportFilter filter = ImportFilterKind::Exported) const;
971984

985+
/// Looks up which external macros are defined by this file.
986+
void getExternalMacros(SmallVectorImpl<ExternalMacroPlugin> &macros) const;
987+
972988
/// Lists modules that are not imported from a file and used in API.
973989
void getImplicitImportsForModuleInterface(
974990
SmallVectorImpl<ImportedModule> &imports) const;

include/swift/AST/ModuleDependencies.h

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,9 @@ class ModuleDependencyInfoStorageBase {
224224
/// command-line), no need to be saved to reconstruct from cache.
225225
std::vector<std::string> auxiliaryFiles;
226226

227+
/// The macro dependencies.
228+
std::map<std::string, MacroPluginDependency> macroDependencies;
229+
227230
/// The direct dependency of the module is resolved by scanner.
228231
bool resolved;
229232
/// ModuleDependencyInfo is finalized (with all transitive dependencies
@@ -253,9 +256,6 @@ struct CommonSwiftTextualModuleDependencyDetails {
253256
/// (Clang) modules on which the bridging header depends.
254257
std::vector<std::string> bridgingModuleDependencies;
255258

256-
/// The macro dependencies.
257-
std::map<std::string, MacroPluginDependency> macroDependencies;
258-
259259
/// The Swift frontend invocation arguments to build the Swift module from the
260260
/// interface.
261261
std::vector<std::string> buildCommandLine;
@@ -326,12 +326,6 @@ class SwiftInterfaceModuleDependenciesStorage
326326
void updateCommandLine(const std::vector<std::string> &newCommandLine) {
327327
textualModuleDetails.buildCommandLine = newCommandLine;
328328
}
329-
330-
void addMacroDependency(StringRef macroModuleName, StringRef libraryPath,
331-
StringRef executablePath) {
332-
textualModuleDetails.macroDependencies.insert(
333-
{macroModuleName.str(), {libraryPath.str(), executablePath.str()}});
334-
}
335329
};
336330

337331
/// Describes the dependencies of a Swift module
@@ -382,12 +376,6 @@ class SwiftSourceModuleDependenciesStorage
382376
void addTestableImport(ImportPath::Module module) {
383377
testableImports.insert(module.front().Item.str());
384378
}
385-
386-
void addMacroDependency(StringRef macroModuleName, StringRef libraryPath,
387-
StringRef executablePath) {
388-
textualModuleDetails.macroDependencies.insert(
389-
{macroModuleName.str(), {libraryPath.str(), executablePath.str()}});
390-
}
391379
};
392380

393381
/// Describes the dependencies of a pre-built Swift module (with no
@@ -786,6 +774,16 @@ class ModuleDependencyInfo {
786774
storage->auxiliaryFiles.emplace_back(file);
787775
}
788776

777+
void addMacroDependency(StringRef macroModuleName, StringRef libraryPath,
778+
StringRef executablePath) {
779+
storage->macroDependencies.insert(
780+
{macroModuleName.str(), {libraryPath.str(), executablePath.str()}});
781+
}
782+
783+
std::map<std::string, MacroPluginDependency> &getMacroDependencies() const {
784+
return storage->macroDependencies;
785+
}
786+
789787
void updateCASFileSystemRootID(const std::string &rootID) {
790788
if (isSwiftInterfaceModule())
791789
cast<SwiftInterfaceModuleDependenciesStorage>(storage.get())
@@ -809,13 +807,6 @@ class ModuleDependencyInfo {
809807
/// For a Source dependency, register a `Testable` import
810808
void addTestableImport(ImportPath::Module module);
811809

812-
/// For a Source/Textual dependency, register a macro dependency.
813-
void addMacroDependency(StringRef macroModuleName, StringRef libraryPath,
814-
StringRef executablePath);
815-
816-
/// For a Source/Textual dependency, if it Has macro dependency.
817-
bool hasMacroDependencies() const;
818-
819810
/// Whether or not a queried module name is a `@Testable` import dependency
820811
/// of this module. Can only return `true` for Swift source modules.
821812
bool isTestableImport(StringRef moduleName) const;

include/swift/AST/SourceFile.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,9 @@ class SourceFile final : public FileUnit {
576576
getImportedModules(SmallVectorImpl<ImportedModule> &imports,
577577
ModuleDecl::ImportFilter filter) const override;
578578

579+
virtual void getExternalMacros(
580+
SmallVectorImpl<ExternalMacroPlugin> &macros) const override;
581+
579582
virtual void
580583
collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const override;
581584

include/swift/DependencyScan/DependencyScanImpl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,9 @@ typedef struct {
167167
/// A flag that indicates this dependency is associated with a static archive
168168
bool is_static;
169169

170+
/// Macro dependecies.
171+
swiftscan_macro_dependency_set_t *macro_dependencies;
172+
170173
/// ModuleCacheKey
171174
swiftscan_string_ref_t module_cache_key;
172175

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "swift/AST/FileUnit.h"
1717
#include "swift/AST/Module.h"
18+
#include "swift/AST/ModuleDependencies.h"
1819
#include "swift/AST/ModuleLoader.h"
1920
#include "swift/AST/SearchPathOptions.h"
2021
#include "llvm/Support/MemoryBuffer.h"
@@ -191,6 +192,9 @@ class SerializedModuleLoaderBase : public ModuleLoader {
191192
llvm::vfs::FileSystem *fileSystem,
192193
PathObfuscator &recoverer);
193194

195+
std::optional<MacroPluginDependency>
196+
resolveMacroPlugin(const ExternalMacroPlugin &macro, StringRef packageName);
197+
194198
public:
195199
virtual ~SerializedModuleLoaderBase();
196200
SerializedModuleLoaderBase(const SerializedModuleLoaderBase &) = delete;
@@ -514,6 +518,9 @@ class SerializedASTFile final : public LoadedFile {
514518
getImportedModules(SmallVectorImpl<ImportedModule> &imports,
515519
ModuleDecl::ImportFilter filter) const override;
516520

521+
virtual void getExternalMacros(
522+
SmallVectorImpl<ExternalMacroPlugin> &macros) const override;
523+
517524
virtual void
518525
collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const override;
519526

lib/AST/Module.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/AST/ASTPrinter.h"
2121
#include "swift/AST/ASTWalker.h"
2222
#include "swift/AST/AccessScope.h"
23+
#include "swift/AST/AttrKind.h"
2324
#include "swift/AST/Builtins.h"
2425
#include "swift/AST/ClangModuleLoader.h"
2526
#include "swift/AST/DiagnosticsSema.h"
@@ -30,6 +31,7 @@
3031
#include "swift/AST/ImportCache.h"
3132
#include "swift/AST/LazyResolver.h"
3233
#include "swift/AST/LinkLibrary.h"
34+
#include "swift/AST/MacroDefinition.h"
3335
#include "swift/AST/ModuleLoader.h"
3436
#include "swift/AST/NameLookup.h"
3537
#include "swift/AST/NameLookupRequests.h"
@@ -1614,6 +1616,11 @@ void ModuleDecl::getImportedModules(SmallVectorImpl<ImportedModule> &modules,
16141616
FORWARD(getImportedModules, (modules, filter));
16151617
}
16161618

1619+
void ModuleDecl::getExternalMacros(
1620+
SmallVectorImpl<ExternalMacroPlugin> &macros) const {
1621+
FORWARD(getExternalMacros, (macros));
1622+
}
1623+
16171624
void ModuleDecl::getImplicitImportsForModuleInterface(
16181625
SmallVectorImpl<ImportedModule> &imports) const {
16191626
FORWARD(getImplicitImportsForModuleInterface, (imports));
@@ -1705,6 +1712,29 @@ SourceFile::getImportedModules(SmallVectorImpl<ImportedModule> &modules,
17051712
}
17061713
}
17071714

1715+
void SourceFile::getExternalMacros(
1716+
SmallVectorImpl<ExternalMacroPlugin> &macros) const {
1717+
for (auto *D : getTopLevelDecls()) {
1718+
auto macroDecl = dyn_cast<MacroDecl>(D);
1719+
if (!macroDecl)
1720+
continue;
1721+
1722+
auto macroDef = macroDecl->getDefinition();
1723+
if (macroDef.kind != MacroDefinition::Kind::External)
1724+
continue;
1725+
1726+
auto formalAccess = macroDecl->getFormalAccess();
1727+
ExternalMacroPlugin::Access access = ExternalMacroPlugin::Access::Internal;
1728+
if (formalAccess >= AccessLevel::Public)
1729+
access = ExternalMacroPlugin::Access::Public;
1730+
else if (formalAccess >= AccessLevel::Package)
1731+
access = ExternalMacroPlugin::Access::Package;
1732+
1733+
auto external = macroDef.getExternalMacro();
1734+
macros.push_back({external.moduleName.str().str(), access});
1735+
}
1736+
}
1737+
17081738
void SourceFile::getImplicitImportsForModuleInterface(
17091739
SmallVectorImpl<ImportedModule> &modules) const {
17101740
for (auto module : ImplicitImportsForModuleInterface)

lib/AST/ModuleDependencies.cpp

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/AST/DiagnosticsFrontend.h"
1919
#include "swift/AST/DiagnosticsSema.h"
2020
#include "swift/AST/MacroDefinition.h"
21+
#include "swift/AST/Module.h"
2122
#include "swift/AST/PluginLoader.h"
2223
#include "swift/AST/SourceFile.h"
2324
#include "swift/Frontend/Frontend.h"
@@ -105,33 +106,6 @@ void ModuleDependencyInfo::addTestableImport(ImportPath::Module module) {
105106
dyn_cast<SwiftSourceModuleDependenciesStorage>(storage.get())->addTestableImport(module);
106107
}
107108

108-
void ModuleDependencyInfo::addMacroDependency(StringRef macroModuleName,
109-
StringRef libraryPath,
110-
StringRef executablePath) {
111-
if (auto swiftSourceStorage =
112-
dyn_cast<SwiftSourceModuleDependenciesStorage>(storage.get()))
113-
swiftSourceStorage->addMacroDependency(macroModuleName, libraryPath,
114-
executablePath);
115-
else if (auto swiftInterfaceStorage =
116-
dyn_cast<SwiftInterfaceModuleDependenciesStorage>(storage.get()))
117-
swiftInterfaceStorage->addMacroDependency(macroModuleName, libraryPath,
118-
executablePath);
119-
else
120-
llvm_unreachable("Unexpected dependency kind");
121-
}
122-
123-
bool ModuleDependencyInfo::hasMacroDependencies() const {
124-
if (auto sourceModule =
125-
dyn_cast<SwiftSourceModuleDependenciesStorage>(storage.get()))
126-
return !sourceModule->textualModuleDetails.macroDependencies.empty();
127-
128-
if (auto interfaceModule =
129-
dyn_cast<SwiftInterfaceModuleDependenciesStorage>(storage.get()))
130-
return !interfaceModule->textualModuleDetails.macroDependencies.empty();
131-
132-
llvm_unreachable("Unexpected dependency kind");
133-
}
134-
135109
bool ModuleDependencyInfo::isTestableImport(StringRef moduleName) const {
136110
if (auto swiftSourceDepStorage = getAsSwiftSourceModule())
137111
return swiftSourceDepStorage->testableImports.contains(moduleName);

lib/DependencyScan/DependencyScanJSON.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,8 @@ void writeJSON(llvm::raw_ostream &out,
601601
/*trailingComma=*/true);
602602
}
603603

604+
writeMacroDependencies(out, swiftBinaryDeps->macro_dependencies, 5,
605+
/*trailingComma=*/true);
604606
writeJSONSingleField(out, "isFramework", swiftBinaryDeps->is_framework,
605607
5, /*trailingComma=*/false);
606608
} else {

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/AST/DiagnosticsSema.h"
1818
#include "swift/AST/ModuleDependencies.h"
1919
#include "swift/AST/ModuleLoader.h"
20+
#include "swift/AST/PluginLoader.h"
2021
#include "swift/AST/SourceFile.h"
2122
#include "swift/AST/TypeCheckRequests.h"
2223
#include "swift/Basic/Assertions.h"
@@ -180,6 +181,10 @@ ModuleDependencyScanningWorker::ModuleDependencyScanningWorker(
180181
workerCompilerInvocation->getSymbolGraphOptions(),
181182
workerCompilerInvocation->getCASOptions(),
182183
ScanASTContext.SourceMgr, Diagnostics));
184+
auto loader = std::make_unique<PluginLoader>(
185+
*workerASTContext, /*DepTracker=*/nullptr,
186+
workerCompilerInvocation->getFrontendOptions().DisableSandbox);
187+
workerASTContext->setPluginLoader(std::move(loader));
183188

184189
// Configure the interface scanning AST delegate.
185190
auto ClangModuleCachePath = getModuleCachePathFromClang(

0 commit comments

Comments
 (0)