Skip to content

Commit 80b1f4c

Browse files
committed
TBDGen: Improve correctness of API symbol visibility and availability.
By plumbing the currently visited Decl through to APIRecorder we can improve the correctness of API symbol visibility and availability in swift-api-extract output.
1 parent 6f1f0b0 commit 80b1f4c

File tree

7 files changed

+53
-54
lines changed

7 files changed

+53
-54
lines changed

include/swift/AST/TBDGenRequests.h

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -222,26 +222,6 @@ class SymbolSource {
222222
return irEntity;
223223
}
224224

225-
/// Returns the associated decl.
226-
const ValueDecl *getDecl() const {
227-
switch (kind) {
228-
case Kind::SIL: {
229-
if (silDeclRef.hasDecl())
230-
return silDeclRef.getDecl();
231-
return nullptr;
232-
}
233-
case Kind::Global:
234-
return Global;
235-
case Kind::IR:
236-
if (irEntity.hasDecl())
237-
return irEntity.getDecl();
238-
return nullptr;
239-
case Kind::LinkerDirective:
240-
case Kind::Unknown:
241-
return nullptr;
242-
}
243-
}
244-
245225
/// Typecheck the entity wrapped by this `SymbolSource`
246226
void typecheck() const {
247227
switch (kind) {

lib/IRGen/TBDGen.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ void TBDGenVisitor::addSymbolInternal(StringRef name, SymbolKind kind,
8181
}
8282
}
8383
#endif
84-
recorder.addSymbol(name, kind, source);
84+
recorder.addSymbol(name, kind, source,
85+
DeclStack.empty() ? nullptr : DeclStack.back());
8586
}
8687

8788
static std::vector<OriginallyDefinedInAttr::ActiveVersion>
@@ -613,9 +614,8 @@ TBDFile GenerateTBDRequest::evaluate(Evaluator &evaluator,
613614
targets.push_back(targetVar);
614615
}
615616

616-
auto addSymbol = [&](StringRef symbol, SymbolKind kind, SymbolSource source) {
617-
file.addSymbol(kind, symbol, targets);
618-
};
617+
auto addSymbol = [&](StringRef symbol, SymbolKind kind, SymbolSource source,
618+
Decl *decl) { file.addSymbol(kind, symbol, targets); };
619619
SimpleAPIRecorder recorder(addSymbol);
620620
TBDGenVisitor visitor(desc, recorder);
621621
visitor.visit(desc);
@@ -626,7 +626,8 @@ std::vector<std::string>
626626
PublicSymbolsRequest::evaluate(Evaluator &evaluator,
627627
TBDGenDescriptor desc) const {
628628
std::vector<std::string> symbols;
629-
auto addSymbol = [&](StringRef symbol, SymbolKind kind, SymbolSource source) {
629+
auto addSymbol = [&](StringRef symbol, SymbolKind kind, SymbolSource source,
630+
Decl *decl) {
630631
if (kind == SymbolKind::GlobalSymbol)
631632
symbols.push_back(symbol.str());
632633
// TextAPI ObjC Class Kinds represents two symbols.
@@ -668,14 +669,13 @@ class APIGenRecorder final : public APIRecorder {
668669
}
669670
~APIGenRecorder() {}
670671

671-
void addSymbol(StringRef symbol, SymbolKind kind,
672-
SymbolSource source) override {
672+
void addSymbol(StringRef symbol, SymbolKind kind, SymbolSource source,
673+
Decl *decl) override {
673674
if (kind != SymbolKind::GlobalSymbol)
674675
return;
675676

676677
apigen::APIAvailability availability;
677678
auto access = apigen::APIAccess::Public;
678-
auto decl = source.getDecl();
679679
if (decl) {
680680
availability = getAvailability(decl);
681681
if (isSPI(decl))
@@ -856,7 +856,8 @@ SymbolSourceMapRequest::evaluate(Evaluator &evaluator,
856856
auto &Ctx = desc.getParentModule()->getASTContext();
857857
auto *SymbolSources = Ctx.Allocate<SymbolSourceMap>();
858858

859-
auto addSymbol = [=](StringRef symbol, SymbolKind kind, SymbolSource source) {
859+
auto addSymbol = [=](StringRef symbol, SymbolKind kind, SymbolSource source,
860+
Decl *decl) {
860861
SymbolSources->insert({symbol, source});
861862
};
862863

lib/IRGen/TBDGenVisitor.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class APIRecorder {
6262
virtual ~APIRecorder() {}
6363

6464
virtual void addSymbol(StringRef name, llvm::MachO::SymbolKind kind,
65-
SymbolSource source) {}
65+
SymbolSource source, Decl *decl) {}
6666
virtual void addObjCInterface(const ClassDecl *decl) {}
6767
virtual void addObjCCategory(const ExtensionDecl *decl) {}
6868
virtual void addObjCMethod(const GenericContext *ctx, SILDeclRef method) {}
@@ -71,14 +71,15 @@ class APIRecorder {
7171
class SimpleAPIRecorder final : public APIRecorder {
7272
public:
7373
using SymbolCallbackFn = llvm::function_ref<void(
74-
StringRef, llvm::MachO::SymbolKind, SymbolSource)>;
74+
StringRef, llvm::MachO::SymbolKind, SymbolSource, Decl *)>;
7575

7676
SimpleAPIRecorder(SymbolCallbackFn func) : func(func) {}
7777

7878
void addSymbol(StringRef symbol, llvm::MachO::SymbolKind kind,
79-
SymbolSource source) override {
80-
func(symbol, kind, source);
79+
SymbolSource source, Decl *decl) override {
80+
func(symbol, kind, source, decl);
8181
}
82+
8283
private:
8384
SymbolCallbackFn func;
8485
};

lib/SIL/IR/SILSymbolVisitor.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -646,19 +646,24 @@ class SILSymbolVisitorImpl : public ASTVisitor<SILSymbolVisitorImpl> {
646646
void addMethod(SILDeclRef method) {
647647
assert(method.getDecl()->getDeclContext() == CD);
648648

649-
if (VirtualFunctionElimination || CD->hasResilientMetadata()) {
650-
if (FirstTime) {
651-
FirstTime = false;
652-
653-
// If the class is itself resilient and has at least one vtable
654-
// entry, it has a method lookup function.
649+
// If the class is itself resilient and has at least one vtable
650+
// entry, it has a method lookup function.
651+
bool hasLookupFunc =
652+
VirtualFunctionElimination || CD->hasResilientMetadata();
653+
if (FirstTime) {
654+
FirstTime = false;
655+
656+
if (hasLookupFunc)
655657
Visitor.addMethodLookupFunction(CD);
656-
}
658+
}
657659

660+
if (!Visitor.willVisitDecl(method.getDecl()))
661+
return;
662+
if (hasLookupFunc)
658663
Visitor.addDispatchThunk(method);
659-
}
660664

661665
Visitor.addMethodDescriptor(method);
666+
Visitor.didVisitDecl(method.getDecl());
662667
}
663668

664669
void addMethodOverride(SILDeclRef baseRef, SILDeclRef derivedRef) {}

test/APIJSON/apigen.swift

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Foundation
99
@available(macOS 10.13, *)
1010
public class Test : NSObject {
1111
@objc public func method1() {}
12+
@available(macOS 10.14, *)
1213
@objc public class func method2() {}
1314
public func nonObjc() {}
1415
}
@@ -80,13 +81,15 @@ public var myGlobalVar: Int = 42
8081
// CHECK-NEXT: "name": "_$s8MyModule11myGlobalVarSivg",
8182
// CHECK-NEXT: "access": "public",
8283
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
83-
// CHECK-NEXT: "linkage": "exported"
84+
// CHECK-NEXT: "linkage": "exported",
85+
// CHECK-NEXT: "introduced": "10.13"
8486
// CHECK-NEXT: },
8587
// CHECK-NEXT: {
8688
// CHECK-NEXT: "name": "_$s8MyModule11myGlobalVarSivs",
8789
// CHECK-NEXT: "access": "public",
8890
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
89-
// CHECK-NEXT: "linkage": "exported"
91+
// CHECK-NEXT: "linkage": "exported",
92+
// CHECK-NEXT: "introduced": "10.13"
9093
// CHECK-NEXT: },
9194
// CHECK-NEXT: {
9295
// CHECK-NEXT: "name": "_$s8MyModule4TestC7method1yyFTj",
@@ -104,13 +107,15 @@ public var myGlobalVar: Int = 42
104107
// CHECK-NEXT: "name": "_$s8MyModule4TestC7method2yyFZTj",
105108
// CHECK-NEXT: "access": "public",
106109
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
107-
// CHECK-NEXT: "linkage": "exported"
110+
// CHECK-NEXT: "linkage": "exported",
111+
// CHECK-NEXT: "introduced": "10.14"
108112
// CHECK-NEXT: },
109113
// CHECK-NEXT: {
110114
// CHECK-NEXT: "name": "_$s8MyModule4TestC7method2yyFZTq",
111115
// CHECK-NEXT: "access": "public",
112116
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
113-
// CHECK-NEXT: "linkage": "exported"
117+
// CHECK-NEXT: "linkage": "exported",
118+
// CHECK-NEXT: "introduced": "10.14"
114119
// CHECK-NEXT: },
115120
// CHECK-NEXT: {
116121
// CHECK-NEXT: "name": "_$s8MyModule4TestC7nonObjcyyFTj",
@@ -140,7 +145,8 @@ public var myGlobalVar: Int = 42
140145
// CHECK-NEXT: "name": "_$s8MyModule4TestCMa",
141146
// CHECK-NEXT: "access": "public",
142147
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
143-
// CHECK-NEXT: "linkage": "exported"
148+
// CHECK-NEXT: "linkage": "exported",
149+
// CHECK-NEXT: "introduced": "10.13"
144150
// CHECK-NEXT: },
145151
// CHECK-NEXT: {
146152
// CHECK-NEXT: "name": "_$s8MyModule4TestCMn",
@@ -167,7 +173,8 @@ public var myGlobalVar: Int = 42
167173
// CHECK-NEXT: "name": "_$s8MyModule4TestCN",
168174
// CHECK-NEXT: "access": "public",
169175
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
170-
// CHECK-NEXT: "linkage": "exported"
176+
// CHECK-NEXT: "linkage": "exported",
177+
// CHECK-NEXT: "introduced": "10.13"
171178
// CHECK-NEXT: },
172179
// CHECK-NEXT: {
173180
// CHECK-NEXT: "name": "_$s8MyModule4TestCfD",
@@ -317,7 +324,8 @@ public var myGlobalVar: Int = 42
317324
// CHECK-NEXT: "name": "_$s8MyModule7DerivedCMa",
318325
// CHECK-NEXT: "access": "public",
319326
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
320-
// CHECK-NEXT: "linkage": "exported"
327+
// CHECK-NEXT: "linkage": "exported",
328+
// CHECK-NEXT: "introduced": "10.13"
321329
// CHECK-NEXT: },
322330
// CHECK-NEXT: {
323331
// CHECK-NEXT: "name": "_$s8MyModule7DerivedCMn",
@@ -337,7 +345,8 @@ public var myGlobalVar: Int = 42
337345
// CHECK-NEXT: "name": "_$s8MyModule7DerivedCN",
338346
// CHECK-NEXT: "access": "public",
339347
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
340-
// CHECK-NEXT: "linkage": "exported"
348+
// CHECK-NEXT: "linkage": "exported",
349+
// CHECK-NEXT: "introduced": "10.13"
341350
// CHECK-NEXT: },
342351
// CHECK-NEXT: {
343352
// CHECK-NEXT: "name": "_$s8MyModule7DerivedCfD",
@@ -370,7 +379,8 @@ public var myGlobalVar: Int = 42
370379
// CHECK-NEXT: {
371380
// CHECK-NEXT: "name": "method2",
372381
// CHECK-NEXT: "access": "public",
373-
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface"
382+
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
383+
// CHECK-NEXT: "introduced": "10.14"
374384
// CHECK-NEXT: }
375385
// CHECK-NEXT: ]
376386
// CHECK-NEXT: },

test/APIJSON/spi.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ public func spiAvailableFunc() {}
155155
// CHECK-SPI-NEXT: },
156156
// CHECK-SPI-NEXT: {
157157
// CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCMa",
158-
// CHECK-SPI-NEXT: "access": "public",
158+
// CHECK-SPI-NEXT: "access": "private",
159159
// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule",
160160
// CHECK-SPI-NEXT: "linkage": "exported"
161161
// CHECK-SPI-NEXT: },
@@ -179,7 +179,7 @@ public func spiAvailableFunc() {}
179179
// CHECK-SPI-NEXT: },
180180
// CHECK-SPI-NEXT: {
181181
// CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCN",
182-
// CHECK-SPI-NEXT: "access": "public",
182+
// CHECK-SPI-NEXT: "access": "private",
183183
// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule",
184184
// CHECK-SPI-NEXT: "linkage": "exported"
185185
// CHECK-SPI-NEXT: },

test/APIJSON/struct.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ public struct TestStruct {
3333
// CHECK-NEXT: "name": "_$s8MyModule10TestStructVMa",
3434
// CHECK-NEXT: "access": "public",
3535
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
36-
// CHECK-NEXT: "linkage": "exported"
36+
// CHECK-NEXT: "linkage": "exported",
37+
// CHECK-NEXT: "introduced": "10.13"
3738
// CHECK-NEXT: },
3839
// CHECK-NEXT: {
3940
// CHECK-NEXT: "name": "_$s8MyModule10TestStructVMn",
@@ -46,7 +47,8 @@ public struct TestStruct {
4647
// CHECK-NEXT: "name": "_$s8MyModule10TestStructVN",
4748
// CHECK-NEXT: "access": "public",
4849
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
49-
// CHECK-NEXT: "linkage": "exported"
50+
// CHECK-NEXT: "linkage": "exported",
51+
// CHECK-NEXT: "introduced": "10.13"
5052
// CHECK-NEXT: }
5153
// CHECK-NEXT: ],
5254
// CHECK-NEXT: "interfaces": [],

0 commit comments

Comments
 (0)