Skip to content

Commit 53b4e70

Browse files
authored
Merge pull request #8822 from huonw/symbol-list-5
Yet more TBDGen work: mostly classes.
2 parents 7a4c761 + 5ce7289 commit 53b4e70

File tree

12 files changed

+243
-50
lines changed

12 files changed

+243
-50
lines changed

include/swift/AST/Decl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3311,6 +3311,15 @@ class ClassDecl : public NominalTypeDecl {
33113311
/// might have implicitly @objc members, but will never itself be @objc.
33123312
ObjCClassKind checkObjCAncestry() const;
33133313

3314+
/// The type of metaclass to use for an class.
3315+
enum class MetaclassKind : uint8_t {
3316+
ObjC,
3317+
SwiftStub,
3318+
};
3319+
3320+
/// Determine which sort of metaclass to use for this class
3321+
MetaclassKind getMetaclassKind() const;
3322+
33143323
/// Retrieve the name to use for this class when interoperating with
33153324
/// the Objective-C runtime.
33163325
StringRef getObjCRuntimeName(llvm::SmallVectorImpl<char> &buffer) const;

lib/AST/Decl.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2584,6 +2584,13 @@ ObjCClassKind ClassDecl::checkObjCAncestry() const {
25842584
return kind;
25852585
}
25862586

2587+
ClassDecl::MetaclassKind ClassDecl::getMetaclassKind() const {
2588+
assert(getASTContext().LangOpts.EnableObjCInterop &&
2589+
"querying metaclass kind without objc interop");
2590+
auto objc = checkObjCAncestry() != ObjCClassKind::NonObjC;
2591+
return objc ? MetaclassKind::ObjC : MetaclassKind::SwiftStub;
2592+
}
2593+
25872594
/// Mangle the name of a protocol or class for use in the Objective-C
25882595
/// runtime.
25892596
static StringRef mangleObjCRuntimeName(const NominalTypeDecl *nominal,

lib/IRGen/GenDecl.cpp

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2412,48 +2412,27 @@ llvm::Constant *IRGenModule::getAddrOfObjCClass(ClassDecl *theClass,
24122412
return addr;
24132413
}
24142414

2415-
/// Fetch a global reference to the given Objective-C metaclass.
2416-
/// The result is always a GlobalValue of ObjCClassPtrTy.
2417-
llvm::Constant *IRGenModule::getAddrOfObjCMetaclass(ClassDecl *theClass,
2418-
ForDefinition_t forDefinition) {
2419-
assert(ObjCInterop && "getting address of ObjC metaclass in no-interop mode");
2420-
assert(!theClass->isForeign());
2421-
LinkEntity entity = LinkEntity::forObjCMetaclass(theClass);
2422-
auto DbgTy = DebugTypeInfo::getObjCClass(
2423-
theClass, ObjCClassPtrTy, getPointerSize(), getPointerAlignment());
2424-
auto addr = getAddrOfLLVMVariable(entity, getPointerAlignment(),
2425-
forDefinition, ObjCClassStructTy, DbgTy);
2426-
return addr;
2427-
}
2415+
/// Fetch the declaration of a metaclass object. The result is always a
2416+
/// GlobalValue of ObjCClassPtrTy, and is either the Objective-C metaclass or
2417+
/// the Swift metaclass stub, depending on whether the class is published as an
2418+
/// ObjC class.
2419+
llvm::Constant *
2420+
IRGenModule::getAddrOfMetaclassObject(ClassDecl *decl,
2421+
ForDefinition_t forDefinition) {
2422+
assert((!decl->isGenericContext() || decl->hasClangNode()) &&
2423+
"generic classes do not have a static metaclass object");
2424+
2425+
auto entity = decl->getMetaclassKind() == ClassDecl::MetaclassKind::ObjC
2426+
? LinkEntity::forObjCMetaclass(decl)
2427+
: LinkEntity::forSwiftMetaclassStub(decl);
24282428

2429-
/// Fetch the declaration of the metaclass stub for the given class type.
2430-
/// The result is always a GlobalValue of ObjCClassPtrTy.
2431-
llvm::Constant *IRGenModule::getAddrOfSwiftMetaclassStub(ClassDecl *theClass,
2432-
ForDefinition_t forDefinition) {
2433-
assert(ObjCInterop && "getting address of metaclass stub in no-interop mode");
2434-
LinkEntity entity = LinkEntity::forSwiftMetaclassStub(theClass);
24352429
auto DbgTy = DebugTypeInfo::getObjCClass(
2436-
theClass, ObjCClassPtrTy, getPointerSize(), getPointerAlignment());
2430+
decl, ObjCClassPtrTy, getPointerSize(), getPointerAlignment());
24372431
auto addr = getAddrOfLLVMVariable(entity, getPointerAlignment(),
24382432
forDefinition, ObjCClassStructTy, DbgTy);
24392433
return addr;
24402434
}
24412435

2442-
/// Fetch the declaration of a metaclass object. This performs either
2443-
/// getAddrOfSwiftMetaclassStub or getAddrOfObjCMetaclass, depending
2444-
/// on whether the class is published as an ObjC class.
2445-
llvm::Constant *IRGenModule::getAddrOfMetaclassObject(ClassDecl *decl,
2446-
ForDefinition_t forDefinition) {
2447-
assert((!decl->isGenericContext() || decl->hasClangNode())
2448-
&& "generic classes do not have a static metaclass object");
2449-
if (decl->checkObjCAncestry() != ObjCClassKind::NonObjC ||
2450-
decl->hasClangNode()) {
2451-
return getAddrOfObjCMetaclass(decl, forDefinition);
2452-
} else {
2453-
return getAddrOfSwiftMetaclassStub(decl, forDefinition);
2454-
}
2455-
}
2456-
24572436
/// Fetch the type metadata access function for a non-generic type.
24582437
llvm::Function *
24592438
IRGenModule::getAddrOfTypeMetadataAccessFunction(CanType type,

lib/IRGen/GenMeta.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3981,6 +3981,8 @@ static void emitObjCClassSymbol(IRGenModule &IGM,
39813981
metadata->getLinkage(),
39823982
classSymbol.str(), metadata,
39833983
IGM.getModule());
3984+
alias->setVisibility(metadata->getVisibility());
3985+
39843986
if (IGM.useDllStorage())
39853987
alias->setDLLStorageClass(metadata->getDLLStorageClass());
39863988
}

lib/IRGen/IRGenModule.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -955,10 +955,6 @@ private: \
955955
llvm::Constant *getAddrOfObjCClass(ClassDecl *D,
956956
ForDefinition_t forDefinition);
957957
Address getAddrOfObjCClassRef(ClassDecl *D);
958-
llvm::Constant *getAddrOfObjCMetaclass(ClassDecl *D,
959-
ForDefinition_t forDefinition);
960-
llvm::Constant *getAddrOfSwiftMetaclassStub(ClassDecl *D,
961-
ForDefinition_t forDefinition);
962958
llvm::Constant *getAddrOfMetaclassObject(ClassDecl *D,
963959
ForDefinition_t forDefinition);
964960
llvm::Function *getAddrOfSILFunction(SILFunction *f,

lib/TBDGen/TBDGen.cpp

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,12 @@ void TBDGenVisitor::visitNominalTypeDecl(NominalTypeDecl *NTD) {
199199

200200
addSymbol(LinkEntity::forNominalTypeDescriptor(NTD));
201201

202-
addSymbol(LinkEntity::forTypeMetadata(declaredType,
203-
TypeMetadataAddress::AddressPoint,
204-
/*isPattern=*/false));
202+
// Generic types do not get metadata directly, only through the function.
203+
if (!NTD->isGenericContext()) {
204+
addSymbol(LinkEntity::forTypeMetadata(declaredType,
205+
TypeMetadataAddress::AddressPoint,
206+
/*isPattern=*/false));
207+
}
205208
addSymbol(LinkEntity::forTypeMetadataAccessFunction(declaredType));
206209

207210
// There are symbols associated with any protocols this type conforms to.
@@ -211,6 +214,11 @@ void TBDGenVisitor::visitNominalTypeDecl(NominalTypeDecl *NTD) {
211214
if (!needsWTable)
212215
continue;
213216

217+
// Only normal conformances get symbols; the others get any public symbols
218+
// from their parent normal conformance.
219+
if (conformance->getKind() != ProtocolConformanceKind::Normal)
220+
continue;
221+
214222
addSymbol(LinkEntity::forDirectProtocolWitnessTable(conformance));
215223
addSymbol(LinkEntity::forProtocolWitnessTableAccessFunction(conformance));
216224
}
@@ -230,9 +238,20 @@ void TBDGenVisitor::visitClassDecl(ClassDecl *CD) {
230238
return;
231239

232240
auto &ctxt = CD->getASTContext();
233-
234-
if (ctxt.LangOpts.EnableObjCInterop) {
235-
addSymbol(LinkEntity::forSwiftMetaclassStub(CD));
241+
auto isGeneric = CD->isGenericContext();
242+
auto objCCompatible = ctxt.LangOpts.EnableObjCInterop && !isGeneric;
243+
auto isObjC = objCCompatible && CD->isObjC();
244+
245+
// Metaclasses and ObjC class (duh) are a ObjC thing, and so are not needed in
246+
// build artifacts/for classes which can't touch ObjC.
247+
if (objCCompatible) {
248+
if (isObjC)
249+
addSymbol(LinkEntity::forObjCClass(CD));
250+
251+
if (CD->getMetaclassKind() == ClassDecl::MetaclassKind::ObjC)
252+
addSymbol(LinkEntity::forObjCMetaclass(CD));
253+
else
254+
addSymbol(LinkEntity::forSwiftMetaclassStub(CD));
236255
}
237256

238257
// Some members of classes get extra handling, beyond members of struct/enums,
@@ -243,17 +262,21 @@ void TBDGenVisitor::visitClassDecl(ClassDecl *CD) {
243262
continue;
244263

245264
auto var = dyn_cast<VarDecl>(value);
246-
auto hasFieldOffset = var && var->hasStorage() && !var->isStatic();
265+
auto hasFieldOffset =
266+
!isGeneric && var && var->hasStorage() && !var->isStatic();
247267
if (hasFieldOffset) {
248-
// These fields are always direct.
249-
addSymbol(LinkEntity::forFieldOffset(var, /*isIndirect=*/false));
268+
// Field are only direct if the class's internals are completely known.
269+
auto isIndirect = !CD->hasFixedLayout();
270+
addSymbol(LinkEntity::forFieldOffset(var, isIndirect));
250271
}
251272

252273
// The non-allocating forms of the constructors and destructors.
253274
if (auto ctor = dyn_cast<ConstructorDecl>(value)) {
254275
addSymbol(SILDeclRef(ctor, SILDeclRef::Kind::Initializer));
255276
} else if (auto dtor = dyn_cast<DestructorDecl>(value)) {
256-
addSymbol(SILDeclRef(dtor, SILDeclRef::Kind::Destroyer));
277+
// ObjC classes don't have a symbol for their destructor.
278+
if (!isObjC)
279+
addSymbol(SILDeclRef(dtor, SILDeclRef::Kind::Destroyer));
257280
}
258281
}
259282

@@ -272,4 +295,7 @@ void swift::enumeratePublicSymbols(FileUnit *file, StringSet &symbols,
272295
TBDGenVisitor visitor(symbols, linkInfo, file->getParentModule());
273296
for (auto d : decls)
274297
visitor.visit(d);
298+
299+
if (file->hasEntryPoint())
300+
symbols.insert("main");
275301
}

test/IRGen/objc_class_export.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
// -- TODO: The OBJC_CLASS symbol should reflect the qualified runtime name of
6464
// Foo.
6565
// CHECK: @_T017objc_class_export3FooCN = hidden alias %swift.type, bitcast (i64* getelementptr inbounds ({{.*}} @_T017objc_class_export3FooCMf, i32 0, i32 2) to %swift.type*)
66-
// CHECK: @"OBJC_CLASS_$__TtC17objc_class_export3Foo" = alias %swift.type, %swift.type* @_T017objc_class_export3FooCN
66+
// CHECK: @"OBJC_CLASS_$__TtC17objc_class_export3Foo" = hidden alias %swift.type, %swift.type* @_T017objc_class_export3FooCN
6767

6868
import gizmo
6969

test/TBD/Input/objc_class_header.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@protocol ObjCProtocol
2+
@end

test/TBD/class.swift

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,30 @@ open class OpenStatics {
7676
}
7777
}
7878

79+
open class OpenGeneric<T, U, V> {
80+
public var publicVar: T
81+
internal var internalVar: U
82+
private var privateVar: V
83+
84+
public var publicVarConcrete: Int = 0
85+
internal var internalVarConcrete: Int = 0
86+
private var privateVarConcrete: Int = 0
87+
88+
public init<S>(t: T, u: U, v: V, _: S) {
89+
publicVar = t
90+
internalVar = u
91+
privateVar = v
92+
}
93+
94+
public func publicGeneric<A>(_: A) {}
95+
internal func internalGeneric<A>(_: A) {}
96+
private func privateGeneric<A>(_: A) {}
97+
98+
public static func publicStaticGeneric<A>(_: A) {}
99+
internal static func internalStaticGeneric<A>(_: A) {}
100+
private static func privateStaticGeneric<A>(_: A) {}
101+
}
102+
79103
public class PublicNothing {}
80104

81105
public class PublicInit {
@@ -152,6 +176,30 @@ public class PublicStatics {
152176
}
153177
}
154178

179+
public class PublicGeneric<T, U, V> {
180+
public var publicVar: T
181+
internal var internalVar: U
182+
private var privateVar: V
183+
184+
public var publicVarConcrete: Int = 0
185+
internal var internalVarConcrete: Int = 0
186+
private var privateVarConcrete: Int = 0
187+
188+
public init<S>(t: T, u: U, v: V, _: S) {
189+
publicVar = t
190+
internalVar = u
191+
privateVar = v
192+
}
193+
194+
public func publicGeneric<A>(_: A) {}
195+
internal func internalGeneric<A>(_: A) {}
196+
private func privateGeneric<A>(_: A) {}
197+
198+
public static func publicStaticGeneric<A>(_: A) {}
199+
internal static func internalStaticGeneric<A>(_: A) {}
200+
private static func privateStaticGeneric<A>(_: A) {}
201+
}
202+
155203

156204
internal class InternalNothing {}
157205

@@ -210,6 +258,26 @@ internal class InternalStatics {
210258
}
211259
}
212260

261+
internal class InternalGeneric<T, U, V> {
262+
internal var internalVar: U
263+
private var privateVar: V
264+
265+
internal var internalVarConcrete: Int = 0
266+
private var privateVarConcrete: Int = 0
267+
268+
internal init<S>(t: T, u: U, v: V, _: S) {
269+
internalVar = u
270+
privateVar = v
271+
}
272+
273+
internal func internalGeneric<A>(_: A) {}
274+
private func privateGeneric<A>(_: A) {}
275+
276+
internal static func internalStaticGeneric<A>(_: A) {}
277+
private static func privateStaticGeneric<A>(_: A) {}
278+
}
279+
280+
213281
private class PrivateNothing {}
214282

215283
private class PrivateInit {
@@ -249,3 +317,17 @@ private class PrivateStatics {
249317
set {}
250318
}
251319
}
320+
321+
private class PrivateGeneric<T, U, V> {
322+
private var privateVar: V
323+
324+
private var privateVarConcrete: Int = 0
325+
326+
private init<S>(t: T, u: U, v: V, _: S) {
327+
privateVar = v
328+
}
329+
330+
private func privateGeneric<A>(_: A) {}
331+
332+
private static func privateStaticGeneric<A>(_: A) {}
333+
}

test/TBD/class_objc.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %target-swift-frontend -c -parse-as-library -module-name test -import-objc-header %S/Input/objc_class_header.h -validate-tbd-against-ir %s
2+
3+
// REQUIRES: objc_interop
4+
5+
import Foundation
6+
7+
public class PublicEmpty: NSObject {}
8+
9+
public class PublicSubPublicEmpty: PublicEmpty {}
10+
internal class InternalSubPublicEmpty: PublicEmpty {}
11+
private class PrivateSubPublicEmpty: PublicEmpty {}
12+
13+
14+
internal class InternalEmpty: NSObject {}
15+
16+
internal class InternalSubInternalEmpty: InternalEmpty {}
17+
private class PrivateSubInternalEmpty: InternalEmpty {}
18+
19+
20+
private class PrivateEmpty: NSObject {}
21+
22+
private class PrivateSubPrivateEmpty: PrivateEmpty {}
23+
24+
25+
public class PublicInheritObjCProtocol: NSObject, ObjCProtocol {}
26+
27+
internal class InternalInheritObjCProtocol: NSObject, ObjCProtocol {}
28+
29+
private class PrivateInheritObjCProtocol: NSObject, ObjCProtocol {}

test/TBD/main.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// RUN: %target-swift-frontend -c -module-name test -validate-tbd-against-ir %s
2+
3+
// Top-level code (i.e. implicit `main`) should be handled

0 commit comments

Comments
 (0)