Skip to content

Commit 75a8cfa

Browse files
committed
[Dependency Scanning] Add a C API layer for dependency scanning tool, scanning actions, and scan results.
Adds a C API layer consisting of: - Data structures used to represent in-memory result of dependency scanning - Opaque dependency scanner tool (C wrapper for `DependencyScanningTool`) Refactors `ScanDependencies.cpp` to produce dependency scanning result in the form of the above binary format.
1 parent 082fc48 commit 75a8cfa

18 files changed

+861
-353
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//===-- swift-c/DSString.h - Managed C String --------------------*- C -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_C_DSSTRING_H
14+
#define SWIFT_C_DSSTRING_H
15+
16+
#include "DependencyScanMacros.h"
17+
18+
DEPSCAN_BEGIN_DECLS
19+
20+
/**
21+
* A character string used to pass around dependency scan result metadata.
22+
* A slightly-reduced variation of clang's CXString
23+
* Use \c depscan_get_C_string() to retrieve the string data and, once finished
24+
* with the string data, call \c depscan_dispose_string() to free the string.
25+
*/
26+
typedef struct {
27+
const void *data;
28+
unsigned private_flags;
29+
} ds_string_t;
30+
31+
typedef struct {
32+
ds_string_t *strings;
33+
unsigned count;
34+
} ds_string_set_t;
35+
36+
//=== Public API ----------------------------------------------------------===//
37+
/// Retrieve the character data associated with the given string.
38+
DEPSCAN_PUBLIC const char *depscan_get_C_string(ds_string_t string);
39+
40+
41+
/// Free the given string.
42+
DEPSCAN_PUBLIC void depscan_string_dispose(ds_string_t string);
43+
44+
45+
/// Free the given string set.
46+
DEPSCAN_PUBLIC void depscan_string_set_dispose(ds_string_set_t *set);
47+
48+
DEPSCAN_END_DECLS
49+
50+
#endif // SWIFT_C_DSSTRING_H
51+
52+
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
//===--- DependencyScan.h - C API for Swift Dependency Scanning ---*- C -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This C API is primarily intended to serve as the Swift Driver's
14+
// dependency scanning facility (https://github.com/apple/swift-driver).
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_C_DEPENDENCY_SCAN_H
19+
#define SWIFT_C_DEPENDENCY_SCAN_H
20+
21+
#include "DependencyScanMacros.h"
22+
#include "DSString.h"
23+
#include <stdbool.h>
24+
#include <stddef.h>
25+
#include <stdint.h>
26+
27+
/// The version constants for the SwiftDependencyScan C API.
28+
/// DEPSCAN_VERSION_MINOR should increase when there are API additions.
29+
/// DEPSCAN_VERSION_MAJOR is intended for "major" source/ABI breaking changes.
30+
#define DEPSCAN_VERSION_MAJOR 0
31+
#define DEPSCAN_VERSION_MINOR 1
32+
33+
DEPSCAN_BEGIN_DECLS
34+
35+
//=== Scanner Data Types --------------------------------------------------===//
36+
37+
typedef enum {
38+
DEPSCAN_DEPENDENCY_INFO_SWIFT_TEXTUAL = 0,
39+
DEPSCAN_DEPENDENCY_INFO_SWIFT_BINARY = 1,
40+
DEPSCAN_DEPENDENCY_INFO_SWIFT_PLACEHOLDER = 2,
41+
DEPSCAN_DEPENDENCY_INFO_CLANG = 3
42+
} depscan_dependency_info_kind_t;
43+
44+
/// Swift modules to be built from a module interface, may have a bridging
45+
/// header.
46+
typedef struct {
47+
/// The module interface from which this module was built, if any.
48+
ds_string_t module_interface_path;
49+
50+
/// The paths of potentially ready-to-use compiled modules for the interface.
51+
ds_string_set_t* compiled_module_candidates;
52+
53+
/// The bridging header, if any.
54+
ds_string_t bridging_header_path;
55+
56+
/// The source files referenced by the bridging header.
57+
ds_string_set_t* bridging_source_files;
58+
59+
/// (Clang) modules on which the bridging header depends.
60+
ds_string_set_t* bridging_module_dependencies;
61+
62+
/// Options to the compile command required to build this module interface
63+
ds_string_set_t* command_line;
64+
65+
/// To build a PCM to be used by this Swift module, we need to append these
66+
/// arguments to the generic PCM build arguments reported from the dependency
67+
/// graph.
68+
ds_string_set_t* extra_pcm_args;
69+
70+
/// The hash value that will be used for the generated module
71+
ds_string_t context_hash;
72+
73+
/// A flag to indicate whether or not this module is a framework.
74+
bool is_framework;
75+
} depscan_swift_textual_details_t;
76+
77+
/// Swift modules with only a binary module file.
78+
typedef struct {
79+
/// The path to the pre-compiled binary module
80+
ds_string_t compiled_module_path;
81+
82+
/// The path to the .swiftModuleDoc file.
83+
ds_string_t module_doc_path;
84+
85+
/// The path to the .swiftSourceInfo file.
86+
ds_string_t module_source_info_path;
87+
} depscan_swift_binary_details_t;
88+
89+
/// Swift placeholder modules carry additional details that specify their
90+
/// module doc path and source info paths.
91+
typedef struct {
92+
/// The path to the pre-compiled binary module
93+
ds_string_t compiled_module_path;
94+
95+
/// The path to the .swiftModuleDoc file.
96+
ds_string_t module_doc_path;
97+
98+
/// The path to the .swiftSourceInfo file.
99+
ds_string_t module_source_info_path;
100+
} depscan_swift_placeholder_details_t;
101+
102+
/// Clang modules are built from a module map file.
103+
typedef struct {
104+
/// The path to the module map used to build this module.
105+
ds_string_t module_map_path;
106+
107+
/// clang-generated context hash
108+
ds_string_t context_hash;
109+
110+
/// Options to the compile command required to build this clang modulemap
111+
ds_string_set_t* command_line;
112+
} depscan_clang_details_t;
113+
114+
typedef struct {
115+
depscan_dependency_info_kind_t kind;
116+
union {
117+
depscan_swift_textual_details_t swift_textual_details;
118+
depscan_swift_binary_details_t swift_binary_details;
119+
depscan_swift_placeholder_details_t swift_placeholder_details;
120+
depscan_clang_details_t clang_details;
121+
};
122+
} depscan_module_details_t;
123+
124+
typedef struct {
125+
/// The module's name
126+
/// The format is:
127+
/// `<module-kind>:<module-name>`
128+
/// where `module-kind` is one of:
129+
/// "swiftTextual"
130+
/// "swiftBinary"
131+
/// "swiftPlaceholder"
132+
/// "clang""
133+
ds_string_t module_name;
134+
135+
/// The path for the module.
136+
ds_string_t module_path;
137+
138+
/// The source files used to build this module.
139+
ds_string_set_t* source_files;
140+
141+
/**
142+
* The list of modules which this module direct depends on.
143+
* The format is:
144+
* `<module-kind>:<module-name>`
145+
*/
146+
ds_string_set_t* direct_dependencies;
147+
148+
/// Specific details of a particular kind of module.
149+
depscan_module_details_t* details;
150+
} depscan_dependency_info_t;
151+
152+
/// Full Dependency Graph (Result)
153+
154+
typedef struct {
155+
int count;
156+
depscan_dependency_info_t *modules;
157+
} depscan_dependency_set_t;
158+
159+
typedef struct {
160+
/// The name of the main module for this dependency graph (root node)
161+
ds_string_t main_module_name;
162+
163+
/// The complete list of modules discovered
164+
depscan_dependency_set_t* module_set;
165+
} depscan_dependency_result_t;
166+
167+
//=== Dependency Result Functions -----------------------------------------===//
168+
169+
DEPSCAN_PUBLIC void
170+
depscan_dependency_info_details_dispose(depscan_module_details_t *details);
171+
172+
DEPSCAN_PUBLIC void
173+
depscan_dependency_info_dispose(depscan_dependency_info_t *info);
174+
175+
DEPSCAN_PUBLIC void
176+
depscan_dependency_set_dispose(depscan_dependency_set_t *set);
177+
178+
DEPSCAN_PUBLIC void
179+
depscan_dependency_result_dispose(depscan_dependency_result_t *result);
180+
181+
//=== Scanner Functions ---------------------------------------------------===//
182+
183+
/// Container of the configuration state and shared cache for dependency scanning.
184+
typedef void *depscan_scanner_t;
185+
186+
DEPSCAN_PUBLIC depscan_scanner_t
187+
depscan_scanner_create(void);
188+
189+
DEPSCAN_PUBLIC void
190+
depscan_scanner_dispose(depscan_scanner_t);
191+
192+
DEPSCAN_PUBLIC depscan_dependency_result_t*
193+
depscan_scan_dependencies(depscan_scanner_t* scanner,
194+
const char *working_directory,
195+
int argc,
196+
const char *const *argv);
197+
198+
DEPSCAN_END_DECLS
199+
200+
#endif // SWIFT_C_DEPENDENCY_SCAN_H
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//===-- DependencyScanMacros.h - Swift Dependency Scanning Macros -*- C -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifdef __cplusplus
14+
# define DEPSCAN_BEGIN_DECLS extern "C" {
15+
# define DEPSCAN_END_DECLS }
16+
#else
17+
# define DEPSCAN_BEGIN_DECLS
18+
# define DEPSCAN_END_DECLS
19+
#endif
20+
21+
#ifndef DEPSCAN_PUBLIC
22+
# ifdef _WIN32
23+
# ifdef libSwiftScan_EXPORTS
24+
# define DEPSCAN_PUBLIC __declspec(dllexport)
25+
# else
26+
# define DEPSCAN_PUBLIC __declspec(dllimport)
27+
# endif
28+
# else
29+
# define DEPSCAN_PUBLIC
30+
# endif
31+
#endif
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module _InternalDependencyScan {
2+
header "DependencyScan.h"
3+
link "_InternalDependencyScan"
4+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===-- swift-c/SCString.h - Managed C String Utility Functions ---*- C -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "swift-c/DependencyScan/DSString.h"
14+
#include "llvm/ADT/StringRef.h"
15+
#include "llvm/ADT/StringSet.h"
16+
#include <string>
17+
#include <vector>
18+
19+
//=== Private Utility Functions--------------------------------------------===//
20+
namespace swift {
21+
namespace dependencies {
22+
/// Create an empty "" string
23+
ds_string_t create_empty();
24+
25+
/// Create null string
26+
ds_string_t create_null();
27+
28+
/// Create a c_string_t object from a nul-terminated C string. New
29+
/// c_string_t may contain a pointer to \p String.
30+
///
31+
/// \p String should not be changed by the caller afterwards.
32+
ds_string_t create_ref(const char *string);
33+
34+
/// Create a c_string_t object from a nul-terminated C string. New
35+
/// c_string_t will contain a copy of \p String.
36+
ds_string_t create_dup(const char *string);
37+
38+
// std::string is already intended to be used as backing storage for CXString.
39+
// Instead, call \c create_ref(string.c_str()).
40+
ds_string_t create_ref(std::string string) = delete;
41+
42+
ds_string_set_t *create_set(const std::vector<std::string> &strings);
43+
}
44+
}

include/swift/DependencyScan/DependencyScanningTool.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef SWIFT_DEPENDENCY_SCANNING_TOOL_H
1414
#define SWIFT_DEPENDENCY_SCANNING_TOOL_H
1515

16+
#include "swift-c/DependencyScan/DependencyScan.h"
1617
#include "swift/AST/ModuleDependencies.h"
1718
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
1819
#include "swift/DependencyScan/ScanDependencies.h"
@@ -35,7 +36,7 @@ class DependencyScanningTool {
3536
///
3637
/// \returns a \c StringError with the diagnostic output if errors
3738
/// occurred, \c FullDependencies otherwise.
38-
llvm::ErrorOr<FullDependencies>
39+
llvm::ErrorOr<depscan_dependency_result_t*>
3940
getDependencies(ArrayRef<const char *> Command,
4041
const llvm::StringSet<> &PlaceholderModules);
4142

@@ -44,9 +45,10 @@ class DependencyScanningTool {
4445
/// BatchScanInput-specified output locations.
4546
///
4647
/// \returns a \c std::error_code if errors occured during scan.
47-
std::error_code getDependencies(ArrayRef<const char *> Command,
48-
const std::vector<BatchScanInput> &BatchInput,
49-
const llvm::StringSet<> &PlaceholderModules);
48+
std::vector<llvm::ErrorOr<depscan_dependency_result_t*>>
49+
getDependencies(ArrayRef<const char *> Command,
50+
const std::vector<BatchScanInput> &BatchInput,
51+
const llvm::StringSet<> &PlaceholderModules);
5052

5153
private:
5254
/// Using the specified invocation command, instantiate a CompilerInstance

0 commit comments

Comments
 (0)