mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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.
This commit is contained in:
@@ -222,26 +222,6 @@ public:
|
||||
return irEntity;
|
||||
}
|
||||
|
||||
/// Returns the associated decl.
|
||||
const ValueDecl *getDecl() const {
|
||||
switch (kind) {
|
||||
case Kind::SIL: {
|
||||
if (silDeclRef.hasDecl())
|
||||
return silDeclRef.getDecl();
|
||||
return nullptr;
|
||||
}
|
||||
case Kind::Global:
|
||||
return Global;
|
||||
case Kind::IR:
|
||||
if (irEntity.hasDecl())
|
||||
return irEntity.getDecl();
|
||||
return nullptr;
|
||||
case Kind::LinkerDirective:
|
||||
case Kind::Unknown:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/// Typecheck the entity wrapped by this `SymbolSource`
|
||||
void typecheck() const {
|
||||
switch (kind) {
|
||||
|
||||
@@ -81,7 +81,8 @@ void TBDGenVisitor::addSymbolInternal(StringRef name, SymbolKind kind,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
recorder.addSymbol(name, kind, source);
|
||||
recorder.addSymbol(name, kind, source,
|
||||
DeclStack.empty() ? nullptr : DeclStack.back());
|
||||
}
|
||||
|
||||
static std::vector<OriginallyDefinedInAttr::ActiveVersion>
|
||||
@@ -613,9 +614,8 @@ TBDFile GenerateTBDRequest::evaluate(Evaluator &evaluator,
|
||||
targets.push_back(targetVar);
|
||||
}
|
||||
|
||||
auto addSymbol = [&](StringRef symbol, SymbolKind kind, SymbolSource source) {
|
||||
file.addSymbol(kind, symbol, targets);
|
||||
};
|
||||
auto addSymbol = [&](StringRef symbol, SymbolKind kind, SymbolSource source,
|
||||
Decl *decl) { file.addSymbol(kind, symbol, targets); };
|
||||
SimpleAPIRecorder recorder(addSymbol);
|
||||
TBDGenVisitor visitor(desc, recorder);
|
||||
visitor.visit(desc);
|
||||
@@ -626,7 +626,8 @@ std::vector<std::string>
|
||||
PublicSymbolsRequest::evaluate(Evaluator &evaluator,
|
||||
TBDGenDescriptor desc) const {
|
||||
std::vector<std::string> symbols;
|
||||
auto addSymbol = [&](StringRef symbol, SymbolKind kind, SymbolSource source) {
|
||||
auto addSymbol = [&](StringRef symbol, SymbolKind kind, SymbolSource source,
|
||||
Decl *decl) {
|
||||
if (kind == SymbolKind::GlobalSymbol)
|
||||
symbols.push_back(symbol.str());
|
||||
// TextAPI ObjC Class Kinds represents two symbols.
|
||||
@@ -668,14 +669,13 @@ public:
|
||||
}
|
||||
~APIGenRecorder() {}
|
||||
|
||||
void addSymbol(StringRef symbol, SymbolKind kind,
|
||||
SymbolSource source) override {
|
||||
void addSymbol(StringRef symbol, SymbolKind kind, SymbolSource source,
|
||||
Decl *decl) override {
|
||||
if (kind != SymbolKind::GlobalSymbol)
|
||||
return;
|
||||
|
||||
apigen::APIAvailability availability;
|
||||
auto access = apigen::APIAccess::Public;
|
||||
auto decl = source.getDecl();
|
||||
if (decl) {
|
||||
availability = getAvailability(decl);
|
||||
if (isSPI(decl))
|
||||
@@ -856,7 +856,8 @@ SymbolSourceMapRequest::evaluate(Evaluator &evaluator,
|
||||
auto &Ctx = desc.getParentModule()->getASTContext();
|
||||
auto *SymbolSources = Ctx.Allocate<SymbolSourceMap>();
|
||||
|
||||
auto addSymbol = [=](StringRef symbol, SymbolKind kind, SymbolSource source) {
|
||||
auto addSymbol = [=](StringRef symbol, SymbolKind kind, SymbolSource source,
|
||||
Decl *decl) {
|
||||
SymbolSources->insert({symbol, source});
|
||||
};
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
virtual ~APIRecorder() {}
|
||||
|
||||
virtual void addSymbol(StringRef name, llvm::MachO::SymbolKind kind,
|
||||
SymbolSource source) {}
|
||||
SymbolSource source, Decl *decl) {}
|
||||
virtual void addObjCInterface(const ClassDecl *decl) {}
|
||||
virtual void addObjCCategory(const ExtensionDecl *decl) {}
|
||||
virtual void addObjCMethod(const GenericContext *ctx, SILDeclRef method) {}
|
||||
@@ -71,14 +71,15 @@ public:
|
||||
class SimpleAPIRecorder final : public APIRecorder {
|
||||
public:
|
||||
using SymbolCallbackFn = llvm::function_ref<void(
|
||||
StringRef, llvm::MachO::SymbolKind, SymbolSource)>;
|
||||
StringRef, llvm::MachO::SymbolKind, SymbolSource, Decl *)>;
|
||||
|
||||
SimpleAPIRecorder(SymbolCallbackFn func) : func(func) {}
|
||||
|
||||
void addSymbol(StringRef symbol, llvm::MachO::SymbolKind kind,
|
||||
SymbolSource source) override {
|
||||
func(symbol, kind, source);
|
||||
SymbolSource source, Decl *decl) override {
|
||||
func(symbol, kind, source, decl);
|
||||
}
|
||||
|
||||
private:
|
||||
SymbolCallbackFn func;
|
||||
};
|
||||
|
||||
@@ -646,19 +646,24 @@ public:
|
||||
void addMethod(SILDeclRef method) {
|
||||
assert(method.getDecl()->getDeclContext() == CD);
|
||||
|
||||
if (VirtualFunctionElimination || CD->hasResilientMetadata()) {
|
||||
// If the class is itself resilient and has at least one vtable
|
||||
// entry, it has a method lookup function.
|
||||
bool hasLookupFunc =
|
||||
VirtualFunctionElimination || CD->hasResilientMetadata();
|
||||
if (FirstTime) {
|
||||
FirstTime = false;
|
||||
|
||||
// If the class is itself resilient and has at least one vtable
|
||||
// entry, it has a method lookup function.
|
||||
if (hasLookupFunc)
|
||||
Visitor.addMethodLookupFunction(CD);
|
||||
}
|
||||
|
||||
if (!Visitor.willVisitDecl(method.getDecl()))
|
||||
return;
|
||||
if (hasLookupFunc)
|
||||
Visitor.addDispatchThunk(method);
|
||||
}
|
||||
|
||||
Visitor.addMethodDescriptor(method);
|
||||
Visitor.didVisitDecl(method.getDecl());
|
||||
}
|
||||
|
||||
void addMethodOverride(SILDeclRef baseRef, SILDeclRef derivedRef) {}
|
||||
|
||||
@@ -9,6 +9,7 @@ import Foundation
|
||||
@available(macOS 10.13, *)
|
||||
public class Test : NSObject {
|
||||
@objc public func method1() {}
|
||||
@available(macOS 10.14, *)
|
||||
@objc public class func method2() {}
|
||||
public func nonObjc() {}
|
||||
}
|
||||
@@ -80,13 +81,15 @@ public var myGlobalVar: Int = 42
|
||||
// CHECK-NEXT: "name": "_$s8MyModule11myGlobalVarSivg",
|
||||
// CHECK-NEXT: "access": "public",
|
||||
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
|
||||
// CHECK-NEXT: "linkage": "exported"
|
||||
// CHECK-NEXT: "linkage": "exported",
|
||||
// CHECK-NEXT: "introduced": "10.13"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "name": "_$s8MyModule11myGlobalVarSivs",
|
||||
// CHECK-NEXT: "access": "public",
|
||||
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
|
||||
// CHECK-NEXT: "linkage": "exported"
|
||||
// CHECK-NEXT: "linkage": "exported",
|
||||
// CHECK-NEXT: "introduced": "10.13"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "name": "_$s8MyModule4TestC7method1yyFTj",
|
||||
@@ -104,13 +107,15 @@ public var myGlobalVar: Int = 42
|
||||
// CHECK-NEXT: "name": "_$s8MyModule4TestC7method2yyFZTj",
|
||||
// CHECK-NEXT: "access": "public",
|
||||
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
|
||||
// CHECK-NEXT: "linkage": "exported"
|
||||
// CHECK-NEXT: "linkage": "exported",
|
||||
// CHECK-NEXT: "introduced": "10.14"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "name": "_$s8MyModule4TestC7method2yyFZTq",
|
||||
// CHECK-NEXT: "access": "public",
|
||||
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
|
||||
// CHECK-NEXT: "linkage": "exported"
|
||||
// CHECK-NEXT: "linkage": "exported",
|
||||
// CHECK-NEXT: "introduced": "10.14"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "name": "_$s8MyModule4TestC7nonObjcyyFTj",
|
||||
@@ -140,7 +145,8 @@ public var myGlobalVar: Int = 42
|
||||
// CHECK-NEXT: "name": "_$s8MyModule4TestCMa",
|
||||
// CHECK-NEXT: "access": "public",
|
||||
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
|
||||
// CHECK-NEXT: "linkage": "exported"
|
||||
// CHECK-NEXT: "linkage": "exported",
|
||||
// CHECK-NEXT: "introduced": "10.13"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "name": "_$s8MyModule4TestCMn",
|
||||
@@ -167,7 +173,8 @@ public var myGlobalVar: Int = 42
|
||||
// CHECK-NEXT: "name": "_$s8MyModule4TestCN",
|
||||
// CHECK-NEXT: "access": "public",
|
||||
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
|
||||
// CHECK-NEXT: "linkage": "exported"
|
||||
// CHECK-NEXT: "linkage": "exported",
|
||||
// CHECK-NEXT: "introduced": "10.13"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "name": "_$s8MyModule4TestCfD",
|
||||
@@ -317,7 +324,8 @@ public var myGlobalVar: Int = 42
|
||||
// CHECK-NEXT: "name": "_$s8MyModule7DerivedCMa",
|
||||
// CHECK-NEXT: "access": "public",
|
||||
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
|
||||
// CHECK-NEXT: "linkage": "exported"
|
||||
// CHECK-NEXT: "linkage": "exported",
|
||||
// CHECK-NEXT: "introduced": "10.13"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "name": "_$s8MyModule7DerivedCMn",
|
||||
@@ -337,7 +345,8 @@ public var myGlobalVar: Int = 42
|
||||
// CHECK-NEXT: "name": "_$s8MyModule7DerivedCN",
|
||||
// CHECK-NEXT: "access": "public",
|
||||
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
|
||||
// CHECK-NEXT: "linkage": "exported"
|
||||
// CHECK-NEXT: "linkage": "exported",
|
||||
// CHECK-NEXT: "introduced": "10.13"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "name": "_$s8MyModule7DerivedCfD",
|
||||
@@ -370,7 +379,8 @@ public var myGlobalVar: Int = 42
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "name": "method2",
|
||||
// CHECK-NEXT: "access": "public",
|
||||
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface"
|
||||
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
|
||||
// CHECK-NEXT: "introduced": "10.14"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: },
|
||||
|
||||
@@ -155,7 +155,7 @@ public func spiAvailableFunc() {}
|
||||
// CHECK-SPI-NEXT: },
|
||||
// CHECK-SPI-NEXT: {
|
||||
// CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCMa",
|
||||
// CHECK-SPI-NEXT: "access": "public",
|
||||
// CHECK-SPI-NEXT: "access": "private",
|
||||
// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule",
|
||||
// CHECK-SPI-NEXT: "linkage": "exported"
|
||||
// CHECK-SPI-NEXT: },
|
||||
@@ -179,7 +179,7 @@ public func spiAvailableFunc() {}
|
||||
// CHECK-SPI-NEXT: },
|
||||
// CHECK-SPI-NEXT: {
|
||||
// CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCN",
|
||||
// CHECK-SPI-NEXT: "access": "public",
|
||||
// CHECK-SPI-NEXT: "access": "private",
|
||||
// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule",
|
||||
// CHECK-SPI-NEXT: "linkage": "exported"
|
||||
// CHECK-SPI-NEXT: },
|
||||
|
||||
@@ -33,7 +33,8 @@ public struct TestStruct {
|
||||
// CHECK-NEXT: "name": "_$s8MyModule10TestStructVMa",
|
||||
// CHECK-NEXT: "access": "public",
|
||||
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
|
||||
// CHECK-NEXT: "linkage": "exported"
|
||||
// CHECK-NEXT: "linkage": "exported",
|
||||
// CHECK-NEXT: "introduced": "10.13"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "name": "_$s8MyModule10TestStructVMn",
|
||||
@@ -46,7 +47,8 @@ public struct TestStruct {
|
||||
// CHECK-NEXT: "name": "_$s8MyModule10TestStructVN",
|
||||
// CHECK-NEXT: "access": "public",
|
||||
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
|
||||
// CHECK-NEXT: "linkage": "exported"
|
||||
// CHECK-NEXT: "linkage": "exported",
|
||||
// CHECK-NEXT: "introduced": "10.13"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "interfaces": [],
|
||||
|
||||
Reference in New Issue
Block a user