Skip to content

Commit fffe2ce

Browse files
Merge pull request #76591 from cachemeifyoucan/eng/PR-swift-macro-dep-tracking
[Macro][Dependencies] Properly model macro dependencies in the scanner
2 parents 74b93c5 + e0541b0 commit fffe2ce

20 files changed

+327
-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;
@@ -513,6 +517,9 @@ class SerializedASTFile final : public LoadedFile {
513517
getImportedModules(SmallVectorImpl<ImportedModule> &imports,
514518
ModuleDecl::ImportFilter filter) const override;
515519

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

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(

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,19 @@ static llvm::Error resolveExplicitModuleInputs(
265265

266266
std::vector<std::string> commandLine = resolvingDepInfo.getCommandline();
267267
auto dependencyInfoCopy = resolvingDepInfo;
268+
auto &directDeps = resolvingDepInfo.getDirectModuleDependencies();
269+
270+
// Helper to the macro dependencies from direct module dependencies.
271+
auto addMacroDependencies = [&](ModuleDependencyID moduleID,
272+
const ModuleDependencyInfo &dep) {
273+
if (llvm::find(directDeps, moduleID) == directDeps.end())
274+
return;
275+
276+
for (auto &entry: dep.getMacroDependencies())
277+
dependencyInfoCopy.addMacroDependency(
278+
entry.first, entry.second.LibraryPath, entry.second.ExecutablePath);
279+
};
280+
268281
for (const auto &depModuleID : dependencies) {
269282
const auto &depInfo = cache.findKnownDependency(depModuleID);
270283
switch (depModuleID.Kind) {
@@ -276,6 +289,7 @@ static llvm::Error resolveExplicitModuleInputs(
276289
: interfaceDepDetails->moduleCacheKey;
277290
commandLine.push_back("-swift-module-file=" + depModuleID.ModuleName + "=" +
278291
path);
292+
addMacroDependencies(depModuleID, depInfo);
279293
} break;
280294
case swift::ModuleDependencyKind::SwiftBinary: {
281295
auto binaryDepDetails = depInfo.getAsSwiftBinaryModule();
@@ -299,6 +313,7 @@ static llvm::Error resolveExplicitModuleInputs(
299313
"-fmodule-map-file=" +
300314
remapPath(bridgingHeaderDepModuleDetails->moduleMapFile));
301315
}
316+
addMacroDependencies(depModuleID, depInfo);
302317
} break;
303318
case swift::ModuleDependencyKind::SwiftPlaceholder: {
304319
auto placeholderDetails = depInfo.getAsPlaceholderDependencyModule();
@@ -364,7 +379,7 @@ static llvm::Error resolveExplicitModuleInputs(
364379
llvm::for_each(
365380
sourceDep->auxiliaryFiles,
366381
[&tracker](const std::string &file) { tracker->trackFile(file); });
367-
llvm::for_each(sourceDep->textualModuleDetails.macroDependencies,
382+
llvm::for_each(sourceDep->macroDependencies,
368383
[&tracker](const auto &entry) {
369384
tracker->trackFile(entry.second.LibraryPath);
370385
});
@@ -382,7 +397,7 @@ static llvm::Error resolveExplicitModuleInputs(
382397
llvm::for_each(
383398
textualDep->auxiliaryFiles,
384399
[&tracker](const std::string &file) { tracker->trackFile(file); });
385-
llvm::for_each(textualDep->textualModuleDetails.macroDependencies,
400+
llvm::for_each(textualDep->macroDependencies,
386401
[&tracker](const auto &entry) {
387402
tracker->trackFile(entry.second.LibraryPath);
388403
});
@@ -402,7 +417,7 @@ static llvm::Error resolveExplicitModuleInputs(
402417

403418
// If there are no external macro dependencies, drop all plugin search
404419
// paths.
405-
if (!resolvingDepInfo.hasMacroDependencies())
420+
if (dependencyInfoCopy.getMacroDependencies().empty())
406421
removeMacroSearchPaths(newCommandLine);
407422

408423
// Update with casfs option.
@@ -629,6 +644,7 @@ static swiftscan_macro_dependency_set_t *createMacroDependencySet(
629644
create_clone(entry.second.LibraryPath.c_str());
630645
set->macro_dependencies[SI]->executablePath =
631646
create_clone(entry.second.ExecutablePath.c_str());
647+
++ SI;
632648
}
633649
return set;
634650
}
@@ -725,7 +741,7 @@ generateFullDependencyGraph(const CompilerInstance &instance,
725741
.CASBridgingHeaderIncludeTreeRootID.c_str()),
726742
create_clone(swiftTextualDeps->moduleCacheKey.c_str()),
727743
createMacroDependencySet(
728-
swiftTextualDeps->textualModuleDetails.macroDependencies),
744+
swiftTextualDeps->macroDependencies),
729745
create_clone(swiftTextualDeps->userModuleVersion.c_str())};
730746
} else if (swiftSourceDeps) {
731747
swiftscan_string_ref_t moduleInterfacePath = create_null();
@@ -763,7 +779,7 @@ generateFullDependencyGraph(const CompilerInstance &instance,
763779
.CASBridgingHeaderIncludeTreeRootID.c_str()),
764780
/*CacheKey*/ create_clone(""),
765781
createMacroDependencySet(
766-
swiftSourceDeps->textualModuleDetails.macroDependencies),
782+
swiftSourceDeps->macroDependencies),
767783
/*userModuleVersion*/ create_clone("")};
768784
} else if (swiftPlaceholderDeps) {
769785
details->kind = SWIFTSCAN_DEPENDENCY_INFO_SWIFT_PLACEHOLDER;
@@ -787,6 +803,7 @@ generateFullDependencyGraph(const CompilerInstance &instance,
787803
create_set(swiftBinaryDeps->headerSourceFiles),
788804
swiftBinaryDeps->isFramework,
789805
swiftBinaryDeps->isStatic,
806+
createMacroDependencySet(swiftBinaryDeps->macroDependencies),
790807
create_clone(swiftBinaryDeps->moduleCacheKey.c_str()),
791808
create_clone(swiftBinaryDeps->userModuleVersion.c_str())};
792809
} else {

0 commit comments

Comments
 (0)