Skip to content

Commit 586e586

Browse files
committed
Add top-level request for TBDGen
Introduce `GenerateTBDRequest` which outputs the interface file along with a set of public symbols.
1 parent 12d14bb commit 586e586

File tree

11 files changed

+288
-15
lines changed

11 files changed

+288
-15
lines changed

include/swift/AST/TBDGenRequests.h

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
//===--- TBDGenRequests.h - TBDGen Requests ---------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 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 file defines TBDGen requests.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_TBDGEN_REQUESTS_H
18+
#define SWIFT_TBDGEN_REQUESTS_H
19+
20+
#include "swift/AST/ASTTypeIDs.h"
21+
#include "swift/AST/SimpleRequest.h"
22+
23+
namespace llvm {
24+
namespace MachO {
25+
class InterfaceFile;
26+
} // end namespace MachO
27+
28+
template <class AllocatorTy>
29+
class StringSet;
30+
} // end namespace llvm
31+
32+
namespace swift {
33+
34+
class FileUnit;
35+
class ModuleDecl;
36+
struct TBDGenOptions;
37+
38+
class TBDGenDescriptor final {
39+
using FileOrModule = llvm::PointerUnion<FileUnit *, ModuleDecl *>;
40+
FileOrModule Input;
41+
const TBDGenOptions &Opts;
42+
43+
TBDGenDescriptor(FileOrModule input, const TBDGenOptions &opts)
44+
: Input(input), Opts(opts) {
45+
assert(input);
46+
}
47+
48+
public:
49+
/// Returns the file or module we're emitting TBD for.
50+
FileOrModule getFileOrModule() const { return Input; }
51+
52+
/// If the input is a single file, returns that file. Otherwise returns
53+
/// \c nullptr.
54+
FileUnit *getSingleFile() const;
55+
56+
/// Returns the parent module for TBD emission.
57+
ModuleDecl *getParentModule() const;
58+
59+
/// Returns the TBDGen options.
60+
const TBDGenOptions &getOptions() const { return Opts; }
61+
62+
bool operator==(const TBDGenDescriptor &other) const;
63+
bool operator!=(const TBDGenDescriptor &other) const {
64+
return !(*this == other);
65+
}
66+
67+
static TBDGenDescriptor forFile(FileUnit *file, const TBDGenOptions &opts) {
68+
return TBDGenDescriptor(file, opts);
69+
}
70+
71+
static TBDGenDescriptor forModule(ModuleDecl *M, const TBDGenOptions &opts) {
72+
return TBDGenDescriptor(M, opts);
73+
}
74+
};
75+
76+
llvm::hash_code hash_value(const TBDGenDescriptor &desc);
77+
void simple_display(llvm::raw_ostream &out, const TBDGenDescriptor &desc);
78+
SourceLoc extractNearestSourceLoc(const TBDGenDescriptor &desc);
79+
80+
using TBDFileAndSymbols =
81+
std::pair<llvm::MachO::InterfaceFile, llvm::StringSet<>>;
82+
83+
/// Computes the TBD file and public symbols for a given module or file.
84+
class GenerateTBDRequest
85+
: public SimpleRequest<GenerateTBDRequest,
86+
TBDFileAndSymbols(TBDGenDescriptor),
87+
CacheKind::Uncached> {
88+
public:
89+
using SimpleRequest::SimpleRequest;
90+
91+
private:
92+
friend SimpleRequest;
93+
94+
// Evaluation.
95+
llvm::Expected<TBDFileAndSymbols> evaluate(Evaluator &evaluator,
96+
TBDGenDescriptor desc) const;
97+
};
98+
99+
/// Report that a request of the given kind is being evaluated, so it
100+
/// can be recorded by the stats reporter.
101+
template <typename Request>
102+
void reportEvaluatedRequest(UnifiedStatsReporter &stats,
103+
const Request &request);
104+
105+
/// The zone number for TBDGen.
106+
#define SWIFT_TYPEID_ZONE TBDGen
107+
#define SWIFT_TYPEID_HEADER "swift/AST/TBDGenTypeIDZone.def"
108+
#include "swift/Basic/DefineTypeIDZone.h"
109+
#undef SWIFT_TYPEID_ZONE
110+
#undef SWIFT_TYPEID_HEADER
111+
112+
// Set up reporting of evaluated requests.
113+
#define SWIFT_REQUEST(Zone, RequestType, Sig, Caching, LocOptions) \
114+
template<> \
115+
inline void reportEvaluatedRequest(UnifiedStatsReporter &stats, \
116+
const RequestType &request) { \
117+
++stats.getFrontendCounters().RequestType; \
118+
}
119+
#include "swift/AST/TBDGenTypeIDZone.def"
120+
#undef SWIFT_REQUEST
121+
122+
} // end namespace swift
123+
124+
#endif // SWIFT_TBDGEN_REQUESTS_H
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===--- TBDGenTypeIDZone.def -----------------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 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 definition file describes the requests in TBDGen's zone.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
SWIFT_REQUEST(TBDGen, GenerateTBDRequest, TBDFileAndSymbols(TBDGenDescriptor),
18+
Uncached, NoLocationInfo)

include/swift/Basic/Statistics.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,4 +300,8 @@ FRONTEND_STATISTIC(IRModule, NumGOTEntries)
300300
/// the .o file you find on disk after the frontend exits.
301301
FRONTEND_STATISTIC(LLVM, NumLLVMBytesOutput)
302302

303+
#define SWIFT_REQUEST(ZONE, NAME, Sig, Caching, LocOptions) FRONTEND_STATISTIC(TBDGen, NAME)
304+
#include "swift/AST/TBDGenTypeIDZone.def"
305+
#undef SWIFT_REQUEST
306+
303307
#endif

include/swift/Basic/TypeID.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ enum class Zone : uint8_t {
3838
Parse = 8,
3939
TypeChecker = 10,
4040
SILGen = 12,
41+
TBDGen = 14,
4142
// N.B. This is not a formal zone and exists solely to support the unit tests.
4243
ArithmeticEvaluator = 255,
4344
};

include/swift/Subsystems.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,12 @@ namespace swift {
375375
/// should call this functions after forming the ASTContext.
376376
void registerSILGenRequestFunctions(Evaluator &evaluator);
377377

378+
/// Register TBDGen-level request functions with the evaluator.
379+
///
380+
/// Clients that form an ASTContext and will perform any TBD generation
381+
/// should call this functions after forming the ASTContext.
382+
void registerTBDGenRequestFunctions(Evaluator &evaluator);
383+
378384
/// Register IDE-level request functions with the evaluator.
379385
///
380386
/// The ASTContext will automatically call these upon construction.

include/swift/TBDGen/TBDGen.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,32 @@ struct TBDGenOptions {
5959
/// Typically, these modules are static linked libraries. Thus their symbols
6060
/// are embeded in the current dylib.
6161
std::vector<std::string> embedSymbolsFromModules;
62+
63+
friend bool operator==(const TBDGenOptions &lhs, const TBDGenOptions &rhs) {
64+
return lhs.HasMultipleIGMs == rhs.HasMultipleIGMs &&
65+
lhs.IsInstallAPI == rhs.IsInstallAPI &&
66+
lhs.LinkerDirectivesOnly == rhs.LinkerDirectivesOnly &&
67+
lhs.InstallName == rhs.InstallName &&
68+
lhs.ModuleLinkName == rhs.ModuleLinkName &&
69+
lhs.CurrentVersion == rhs.CurrentVersion &&
70+
lhs.CompatibilityVersion == rhs.CompatibilityVersion &&
71+
lhs.ModuleInstallNameMapPath == rhs.ModuleInstallNameMapPath &&
72+
lhs.embedSymbolsFromModules == rhs.embedSymbolsFromModules;
73+
}
74+
75+
friend bool operator!=(const TBDGenOptions &lhs, const TBDGenOptions &rhs) {
76+
return !(lhs == rhs);
77+
}
78+
79+
friend llvm::hash_code hash_value(const TBDGenOptions &opts) {
80+
using namespace llvm;
81+
return hash_combine(
82+
opts.HasMultipleIGMs, opts.IsInstallAPI, opts.LinkerDirectivesOnly,
83+
opts.InstallName, opts.ModuleLinkName, opts.CurrentVersion,
84+
opts.CompatibilityVersion, opts.ModuleInstallNameMapPath,
85+
hash_combine_range(opts.embedSymbolsFromModules.begin(),
86+
opts.embedSymbolsFromModules.end()));
87+
}
6288
};
6389

6490
void enumeratePublicSymbols(FileUnit *module, llvm::StringSet<> &symbols,

lib/Frontend/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ target_link_libraries(swiftFrontend PRIVATE
2222
swiftSILGen
2323
swiftSILOptimizer
2424
swiftSema
25-
swiftSerialization)
25+
swiftSerialization
26+
swiftTBDGen)
2627

lib/Frontend/Frontend.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ bool CompilerInstance::setUpASTContextIfNeeded() {
211211
registerParseRequestFunctions(Context->evaluator);
212212
registerTypeCheckerRequestFunctions(Context->evaluator);
213213
registerSILGenRequestFunctions(Context->evaluator);
214+
registerTBDGenRequestFunctions(Context->evaluator);
214215

215216
// Migrator, indexing and typo correction need some IDE requests.
216217
// The integrated REPL needs IDE requests for completion.

lib/TBDGen/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
add_swift_host_library(swiftTBDGen STATIC
22
TBDGen.cpp
3+
TBDGenRequests.cpp
34
LLVM_LINK_COMPONENTS
45
demangle
56
TextAPI
67
)
78
target_link_libraries(swiftTBDGen PRIVATE
89
swiftAST
10+
swiftIRGen
911
swiftSIL)

lib/TBDGen/TBDGen.cpp

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/AST/Module.h"
2424
#include "swift/AST/ParameterList.h"
2525
#include "swift/AST/PropertyWrappers.h"
26+
#include "swift/AST/TBDGenRequests.h"
2627
#include "swift/Basic/LLVM.h"
2728
#include "swift/ClangImporter/ClangImporter.h"
2829
#include "swift/IRGen/IRGenPublic.h"
@@ -945,10 +946,12 @@ static bool hasLinkerDirective(Decl *D) {
945946
return !getAllMovedPlatformVersions(D).empty();
946947
}
947948

948-
static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
949-
StringSet *symbols,
950-
llvm::raw_ostream *os,
951-
const TBDGenOptions &opts) {
949+
llvm::Expected<TBDFileAndSymbols>
950+
GenerateTBDRequest::evaluate(Evaluator &evaluator,
951+
TBDGenDescriptor desc) const {
952+
auto *M = desc.getParentModule();
953+
auto &opts = desc.getOptions();
954+
952955
auto &ctx = M->getASTContext();
953956
const auto &triple = ctx.LangOpts.Target;
954957
UniversalLinkageInfo linkInfo(triple, opts.HasMultipleIGMs,
@@ -976,8 +979,9 @@ static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
976979
llvm::MachO::Target target(triple);
977980
file.addTarget(target);
978981

982+
StringSet symbols;
979983
auto *clang = static_cast<ClangImporter *>(ctx.getClangModuleLoader());
980-
TBDGenVisitor visitor(file, {target}, symbols,
984+
TBDGenVisitor visitor(file, {target}, &symbols,
981985
clang->getTargetInfo().getDataLayout(),
982986
linkInfo, M, opts);
983987

@@ -1000,7 +1004,7 @@ static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
10001004
}
10011005
};
10021006

1003-
if (singleFile) {
1007+
if (auto *singleFile = desc.getSingleFile()) {
10041008
assert(M == singleFile->getParentModule() && "mismatched file and module");
10051009
visitFile(singleFile);
10061010
} else {
@@ -1025,22 +1029,28 @@ static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
10251029
});
10261030
}
10271031

1028-
if (os) {
1029-
llvm::cantFail(llvm::MachO::TextAPIWriter::writeToStream(*os, file),
1030-
"YAML writing should be error-free");
1031-
}
1032+
return std::make_pair(std::move(file), std::move(symbols));
10321033
}
10331034

10341035
void swift::enumeratePublicSymbols(FileUnit *file, StringSet &symbols,
10351036
const TBDGenOptions &opts) {
1036-
enumeratePublicSymbolsAndWrite(file->getParentModule(), file, &symbols,
1037-
nullptr, opts);
1037+
assert(symbols.empty() && "Additive symbol enumeration not supported");
1038+
auto &evaluator = file->getASTContext().evaluator;
1039+
auto desc = TBDGenDescriptor::forFile(file, opts);
1040+
symbols = llvm::cantFail(evaluator(GenerateTBDRequest{desc})).second;
10381041
}
10391042
void swift::enumeratePublicSymbols(ModuleDecl *M, StringSet &symbols,
10401043
const TBDGenOptions &opts) {
1041-
enumeratePublicSymbolsAndWrite(M, nullptr, &symbols, nullptr, opts);
1044+
assert(symbols.empty() && "Additive symbol enumeration not supported");
1045+
auto &evaluator = M->getASTContext().evaluator;
1046+
auto desc = TBDGenDescriptor::forModule(M, opts);
1047+
symbols = llvm::cantFail(evaluator(GenerateTBDRequest{desc})).second;
10421048
}
10431049
void swift::writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os,
10441050
const TBDGenOptions &opts) {
1045-
enumeratePublicSymbolsAndWrite(M, nullptr, nullptr, &os, opts);
1051+
auto &evaluator = M->getASTContext().evaluator;
1052+
auto desc = TBDGenDescriptor::forModule(M, opts);
1053+
auto file = llvm::cantFail(evaluator(GenerateTBDRequest{desc})).first;
1054+
llvm::cantFail(llvm::MachO::TextAPIWriter::writeToStream(os, file),
1055+
"YAML writing should be error-free");
10461056
}

0 commit comments

Comments
 (0)