Skip to content

Commit 1c08aba

Browse files
authored
Merge pull request #82169 from artemcm/DepScanImportAccessControl
[Dependency Scanning] Keep track of each imported module's access control
2 parents e42b564 + c3ce91e commit 1c08aba

20 files changed

+400
-90
lines changed

include/swift-c/DependencyScan/DependencyScan.h

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
/// SWIFTSCAN_VERSION_MINOR should increase when there are API additions.
2626
/// SWIFTSCAN_VERSION_MAJOR is intended for "major" source/ABI breaking changes.
2727
#define SWIFTSCAN_VERSION_MAJOR 2
28-
#define SWIFTSCAN_VERSION_MINOR 1
28+
#define SWIFTSCAN_VERSION_MINOR 2
2929

3030
SWIFTSCAN_BEGIN_DECLS
3131

@@ -49,6 +49,9 @@ typedef struct swiftscan_dependency_info_s *swiftscan_dependency_info_t;
4949
/// Opaque container to a link library info.
5050
typedef struct swiftscan_link_library_info_s *swiftscan_link_library_info_t;
5151

52+
/// Opaque container to an import info.
53+
typedef struct swiftscan_import_info_s *swiftscan_import_info_t;
54+
5255
/// Opaque container to a macro dependency.
5356
typedef struct swiftscan_macro_dependency_s *swiftscan_macro_dependency_t;
5457

@@ -76,6 +79,18 @@ typedef struct {
7679
size_t count;
7780
} swiftscan_link_library_set_t;
7881

82+
/// Set of details about source imports
83+
typedef struct {
84+
swiftscan_import_info_t *imports;
85+
size_t count;
86+
} swiftscan_import_info_set_t;
87+
88+
/// Set of source location infos
89+
typedef struct {
90+
swiftscan_source_location_t *source_locations;
91+
size_t count;
92+
} swiftscan_source_location_set_t;
93+
7994
/// Set of macro dependency
8095
typedef struct {
8196
swiftscan_macro_dependency_t *macro_dependencies;
@@ -89,6 +104,15 @@ typedef enum {
89104
SWIFTSCAN_DIAGNOSTIC_SEVERITY_REMARK = 3
90105
} swiftscan_diagnostic_severity_t;
91106

107+
// Must maintain consistency with swift::AccessLevel
108+
typedef enum {
109+
SWIFTSCAN_ACCESS_LEVEL_PRIVATE = 0,
110+
SWIFTSCAN_ACCESS_LEVEL_FILEPRIVATE = 1,
111+
SWIFTSCAN_ACCESS_LEVEL_INTERNAL = 2,
112+
SWIFTSCAN_ACCESS_LEVEL_PACKAGE = 3,
113+
SWIFTSCAN_ACCESS_LEVEL_PUBLIC = 4
114+
} swiftscan_access_level_t;
115+
92116
typedef struct {
93117
swiftscan_diagnostic_info_t *diagnostics;
94118
size_t count;
@@ -148,10 +172,23 @@ swiftscan_module_info_get_direct_dependencies(swiftscan_dependency_info_t info);
148172
SWIFTSCAN_PUBLIC swiftscan_link_library_set_t *
149173
swiftscan_module_info_get_link_libraries(swiftscan_dependency_info_t info);
150174

175+
SWIFTSCAN_PUBLIC swiftscan_import_info_set_t *
176+
swiftscan_module_info_get_imports(swiftscan_dependency_info_t info);
177+
151178
SWIFTSCAN_PUBLIC swiftscan_module_details_t
152179
swiftscan_module_info_get_details(swiftscan_dependency_info_t info);
153180

154-
//=== Link Library Info Functions ------------------------------------===//
181+
//=== Import Details Functions -------------------------------------------===//
182+
SWIFTSCAN_PUBLIC swiftscan_source_location_set_t *
183+
swiftscan_import_info_get_source_locations(swiftscan_import_info_t info);
184+
185+
SWIFTSCAN_PUBLIC swiftscan_string_ref_t
186+
swiftscan_import_info_get_identifier(swiftscan_import_info_t info);
187+
188+
SWIFTSCAN_PUBLIC swiftscan_access_level_t
189+
swiftscan_import_info_get_access_level(swiftscan_import_info_t info);
190+
191+
//=== Link Library Info Functions ----------------------------------------===//
155192
SWIFTSCAN_PUBLIC swiftscan_string_ref_t
156193
swiftscan_link_library_info_get_link_name(
157194
swiftscan_link_library_info_t info);

include/swift/AST/ModuleDependencies.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -156,30 +156,35 @@ struct ScannerImportStatementInfo {
156156
uint32_t columnNumber;
157157
};
158158

159-
ScannerImportStatementInfo(std::string importIdentifier, bool isExported)
160-
: importLocations(), importIdentifier(importIdentifier),
161-
isExported(isExported) {}
159+
ScannerImportStatementInfo(std::string importIdentifier, bool isExported,
160+
AccessLevel accessLevel)
161+
: importIdentifier(importIdentifier), importLocations(),
162+
isExported(isExported), accessLevel(accessLevel) {}
162163

163164
ScannerImportStatementInfo(std::string importIdentifier, bool isExported,
165+
AccessLevel accessLevel,
164166
ImportDiagnosticLocationInfo location)
165-
: importLocations({location}), importIdentifier(importIdentifier),
166-
isExported(isExported) {}
167+
: importIdentifier(importIdentifier), importLocations({location}),
168+
isExported(isExported), accessLevel(accessLevel) {}
167169

168170
ScannerImportStatementInfo(std::string importIdentifier, bool isExported,
171+
AccessLevel accessLevel,
169172
SmallVector<ImportDiagnosticLocationInfo, 4> locations)
170-
: importLocations(locations), importIdentifier(importIdentifier),
171-
isExported(isExported) {}
173+
: importIdentifier(importIdentifier), importLocations(locations),
174+
isExported(isExported), accessLevel(accessLevel) {}
172175

173176
void addImportLocation(ImportDiagnosticLocationInfo location) {
174177
importLocations.push_back(location);
175178
}
176179

177-
/// Buffer, line & column number of the import statement
178-
SmallVector<ImportDiagnosticLocationInfo, 4> importLocations;
179180
/// Imported module string. e.g. "Foo.Bar" in 'import Foo.Bar'
180181
std::string importIdentifier;
182+
/// Buffer, line & column number of the import statement
183+
SmallVector<ImportDiagnosticLocationInfo, 4> importLocations;
181184
/// Is this an @_exported import
182185
bool isExported;
186+
/// Access level of this dependency
187+
AccessLevel accessLevel;
183188
};
184189

185190
/// Base class for the variant storage of ModuleDependencyInfo.
@@ -942,6 +947,7 @@ class ModuleDependencyInfo {
942947
/// Add a dependency on the given module, if it was not already in the set.
943948
void
944949
addOptionalModuleImport(StringRef module, bool isExported,
950+
AccessLevel accessLevel,
945951
llvm::StringSet<> *alreadyAddedModules = nullptr);
946952

947953
/// Add all of the module imports in the given source
@@ -952,12 +958,14 @@ class ModuleDependencyInfo {
952958

953959
/// Add a dependency on the given module, if it was not already in the set.
954960
void addModuleImport(ImportPath::Module module, bool isExported,
961+
AccessLevel accessLevel,
955962
llvm::StringSet<> *alreadyAddedModules = nullptr,
956963
const SourceManager *sourceManager = nullptr,
957964
SourceLoc sourceLocation = SourceLoc());
958965

959966
/// Add a dependency on the given module, if it was not already in the set.
960967
void addModuleImport(StringRef module, bool isExported,
968+
AccessLevel accessLevel,
961969
llvm::StringSet<> *alreadyAddedModules = nullptr,
962970
const SourceManager *sourceManager = nullptr,
963971
SourceLoc sourceLocation = SourceLoc());

include/swift/DependencyScan/DependencyScanImpl.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ struct swiftscan_dependency_info_s {
6363
/// The list of link libraries for this module.
6464
swiftscan_link_library_set_t *link_libraries;
6565

66+
/// The list of source import infos.
67+
swiftscan_import_info_set_t *imports;
68+
6669
/// Specific details of a particular kind of module.
6770
swiftscan_module_details_t details;
6871
};
@@ -74,10 +77,16 @@ struct swiftscan_link_library_info_s {
7477
bool forceLoad;
7578
};
7679

80+
struct swiftscan_import_info_s {
81+
swiftscan_string_ref_t import_identifier;
82+
swiftscan_source_location_set_t *source_locations;
83+
swiftscan_access_level_t access_level;
84+
};
85+
7786
struct swiftscan_macro_dependency_s {
78-
swiftscan_string_ref_t moduleName;
79-
swiftscan_string_ref_t libraryPath;
80-
swiftscan_string_ref_t executablePath;
87+
swiftscan_string_ref_t module_name;
88+
swiftscan_string_ref_t library_path;
89+
swiftscan_string_ref_t executable_path;
8190
};
8291

8392
/// Swift modules to be built from a module interface, may have a bridging

include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ using IsExportedImport = BCFixed<1>;
6767
using LineNumberField = BCFixed<32>;
6868
using ColumnNumberField = BCFixed<32>;
6969

70+
/// Access level of an import
71+
using AccessLevelField = BCFixed<8>;
72+
7073
/// Arrays of various identifiers, distinguished for readability
7174
using IdentifierIDArryField = llvm::BCArray<IdentifierIDField>;
7275
using ModuleIDArryField = llvm::BCArray<IdentifierIDField>;
@@ -192,7 +195,8 @@ using ImportStatementLayout =
192195
LineNumberField, // lineNumber
193196
ColumnNumberField, // columnNumber
194197
IsOptionalImport, // isOptional
195-
IsExportedImport // isExported
198+
IsExportedImport, // isExported
199+
AccessLevelField // accessLevel
196200
>;
197201
using ImportStatementArrayLayout =
198202
BCRecordLayout<IMPORT_STATEMENT_ARRAY_NODE, IdentifierIDArryField>;

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,7 @@ class SerializedModuleLoaderBase : public ModuleLoader {
170170
bool isTestableImport, bool isCandidateForTextualModule);
171171

172172
struct BinaryModuleImports {
173-
llvm::StringSet<> moduleImports;
174-
llvm::StringSet<> exportedModules;
173+
std::vector<ScannerImportStatementInfo> moduleImports;
175174
std::string headerImport;
176175
};
177176

lib/AST/ModuleDependencies.cpp

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,34 @@ bool ModuleDependencyInfo::isTestableImport(StringRef moduleName) const {
116116
}
117117

118118
void ModuleDependencyInfo::addOptionalModuleImport(
119-
StringRef module, bool isExported, llvm::StringSet<> *alreadyAddedModules) {
120-
if (!alreadyAddedModules || alreadyAddedModules->insert(module).second)
121-
storage->optionalModuleImports.push_back({module.str(), isExported});
119+
StringRef module, bool isExported, AccessLevel accessLevel,
120+
llvm::StringSet<> *alreadyAddedModules) {
121+
122+
if (alreadyAddedModules && alreadyAddedModules->contains(module)) {
123+
// Find a prior import of this module and add import location
124+
// and adjust whether or not this module is ever imported as exported
125+
// as well as the access level
126+
for (auto &existingImport : storage->optionalModuleImports) {
127+
if (existingImport.importIdentifier == module) {
128+
existingImport.isExported |= isExported;
129+
existingImport.accessLevel = std::max(existingImport.accessLevel,
130+
accessLevel);
131+
break;
132+
}
133+
}
134+
} else {
135+
if (alreadyAddedModules)
136+
alreadyAddedModules->insert(module);
137+
138+
storage->optionalModuleImports.push_back(
139+
{module.str(), isExported, accessLevel});
140+
}
122141
}
123142

124143
void ModuleDependencyInfo::addModuleImport(
125-
StringRef module, bool isExported, llvm::StringSet<> *alreadyAddedModules,
126-
const SourceManager *sourceManager, SourceLoc sourceLocation) {
144+
StringRef module, bool isExported, AccessLevel accessLevel,
145+
llvm::StringSet<> *alreadyAddedModules, const SourceManager *sourceManager,
146+
SourceLoc sourceLocation) {
127147
auto scannerImportLocToDiagnosticLocInfo =
128148
[&sourceManager](SourceLoc sourceLocation) {
129149
auto lineAndColumnNumbers =
@@ -138,13 +158,16 @@ void ModuleDependencyInfo::addModuleImport(
138158
if (alreadyAddedModules && alreadyAddedModules->contains(module)) {
139159
// Find a prior import of this module and add import location
140160
// and adjust whether or not this module is ever imported as exported
161+
// as well as the access level
141162
for (auto &existingImport : storage->moduleImports) {
142163
if (existingImport.importIdentifier == module) {
143164
if (validSourceLocation) {
144165
existingImport.addImportLocation(
145-
scannerImportLocToDiagnosticLocInfo(sourceLocation));
166+
scannerImportLocToDiagnosticLocInfo(sourceLocation));
146167
}
147168
existingImport.isExported |= isExported;
169+
existingImport.accessLevel = std::max(existingImport.accessLevel,
170+
accessLevel);
148171
break;
149172
}
150173
}
@@ -154,16 +177,18 @@ void ModuleDependencyInfo::addModuleImport(
154177

155178
if (validSourceLocation)
156179
storage->moduleImports.push_back(ScannerImportStatementInfo(
157-
module.str(), isExported, scannerImportLocToDiagnosticLocInfo(sourceLocation)));
180+
module.str(), isExported, accessLevel,
181+
scannerImportLocToDiagnosticLocInfo(sourceLocation)));
158182
else
159183
storage->moduleImports.push_back(
160-
ScannerImportStatementInfo(module.str(), isExported));
184+
ScannerImportStatementInfo(module.str(), isExported, accessLevel));
161185
}
162186
}
163187

164188
void ModuleDependencyInfo::addModuleImport(
165-
ImportPath::Module module, bool isExported, llvm::StringSet<> *alreadyAddedModules,
166-
const SourceManager *sourceManager, SourceLoc sourceLocation) {
189+
ImportPath::Module module, bool isExported, AccessLevel accessLevel,
190+
llvm::StringSet<> *alreadyAddedModules, const SourceManager *sourceManager,
191+
SourceLoc sourceLocation) {
167192
std::string ImportedModuleName = module.front().Item.str().str();
168193
auto submodulePath = module.getSubmodulePath();
169194
if (submodulePath.size() > 0 && !submodulePath[0].Item.empty()) {
@@ -172,11 +197,12 @@ void ModuleDependencyInfo::addModuleImport(
172197
// module named "Foo_Private". ClangImporter has special support for this.
173198
if (submoduleComponent.Item.str() == "Private")
174199
addOptionalModuleImport(ImportedModuleName + "_Private",
200+
isExported, accessLevel,
175201
alreadyAddedModules);
176202
}
177203

178-
addModuleImport(ImportedModuleName, isExported, alreadyAddedModules,
179-
sourceManager, sourceLocation);
204+
addModuleImport(ImportedModuleName, isExported, accessLevel,
205+
alreadyAddedModules, sourceManager, sourceLocation);
180206
}
181207

182208
void ModuleDependencyInfo::addModuleImports(
@@ -205,6 +231,7 @@ void ModuleDependencyInfo::addModuleImports(
205231
continue;
206232

207233
addModuleImport(realPath, importDecl->isExported(),
234+
importDecl->getAccessLevel(),
208235
&alreadyAddedModules, sourceManager,
209236
importDecl->getLoc());
210237

lib/ClangImporter/ClangModuleDependencyScanner.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ ModuleDependencyVector ClangImporter::bridgeClangModuleDependencies(
191191
// FIXME: This assumes, conservatively, that all Clang module imports
192192
// are exported. We need to fix this once the clang scanner gains the appropriate
193193
// API to query this.
194-
dependencies.addModuleImport(moduleName.ModuleName, /* isExported */ true, &alreadyAddedModules);
194+
dependencies.addModuleImport(moduleName.ModuleName, /* isExported */ true,
195+
AccessLevel::Public, &alreadyAddedModules);
195196
// It is safe to assume that all dependencies of a Clang module are Clang modules.
196197
directDependencyIDs.push_back({moduleName.ModuleName, ModuleDependencyKind::Clang});
197198
}

0 commit comments

Comments
 (0)