-
-
Notifications
You must be signed in to change notification settings - Fork 271
Improve Objective-C support #4777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8225ff0
71ed496
67ef162
ffbf6ca
f2ac1d2
cb785fb
9a9f292
b2c30f6
3679436
9cbd156
4246d42
2670dbb
58e04b3
da1cfbb
bcaff89
bc64a73
a28981a
a7f6ef0
3895396
92bbe08
0fd521d
627db4f
dd062ea
37a701d
f0a5b4c
1b2cc5d
8212b12
aa9b892
29c9616
a885a90
7d857c9
def16ff
3b86873
056e457
c1a76f8
442f248
9b32dc8
19189ea
091bdb2
d252845
ed01dbc
47638ed
9c63811
2606073
b561bd4
d106402
9690109
9c4700a
05ab567
f9fd977
cdae5b8
b923a57
4d8ec8b
ccec2ea
c8e743e
f9bf25a
f577f51
0d84d40
8ac9a36
5410e04
1fc06e4
e6d6548
db91254
c9bed7a
7423d0a
5d86126
fd35f83
9244874
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -156,6 +156,9 @@ extern (C++) struct ObjcClassDeclaration | |
| /// `true` if this class is externally defined. | ||
| bool isExtern = false; | ||
|
|
||
| /// `true` if this class is a Swift stub | ||
| version(IN_LLVM) bool isSwiftStub = false; | ||
|
|
||
| /// Name of this class. | ||
| Identifier identifier; | ||
|
|
||
|
|
@@ -264,6 +267,16 @@ extern(C++) abstract class Objc | |
| */ | ||
| abstract void setAsOptional(FuncDeclaration functionDeclaration, Scope* sc) const; | ||
|
|
||
| /** | ||
| * Marks the given class as a Swift stub class. | ||
| * | ||
| * Params: | ||
| * cd = the class declaration to set as a swift stub | ||
| * sc = the scope from the semantic phase | ||
| */ | ||
| version(IN_LLVM) | ||
| abstract void setAsSwiftStub(ClassDeclaration cd, Scope* sc) const; | ||
|
|
||
| /** | ||
| * Validates function declarations declared optional. | ||
| * | ||
|
|
@@ -452,6 +465,12 @@ static if (!IN_LLVM) | |
| // noop | ||
| } | ||
|
|
||
| version(IN_LLVM) | ||
| override void setAsSwiftStub(ClassDeclaration, Scope*) const | ||
| { | ||
| // noop | ||
| } | ||
|
|
||
| override void validateOptional(FuncDeclaration) const | ||
| { | ||
| // noop | ||
|
|
@@ -532,6 +551,7 @@ version (IN_LLVM) {} else | |
| { | ||
| cd.classKind = ClassKind.objc; | ||
| cd.objc.isExtern = (cd.storage_class & STC.extern_) > 0; | ||
| this.setAsSwiftStub(cd, cd._scope); | ||
| } | ||
|
|
||
| override void setObjc(InterfaceDeclaration id) | ||
|
|
@@ -826,6 +846,42 @@ version (IN_LLVM) {} else | |
| errorSupplemental(expression.loc, "`tupleof` is not available for members " ~ | ||
| "of Objective-C classes. Please use the Objective-C runtime instead"); | ||
| } | ||
|
|
||
| version(IN_LLVM) { | ||
| override void setAsSwiftStub(ClassDeclaration cd, Scope* sc) const | ||
| { | ||
| const count = declaredAsSwiftStubCount(cd, sc); | ||
| cd.objc.isSwiftStub = count > 0; | ||
|
|
||
| if (count > 1) | ||
| .error(cd.loc, "%s `%s` can only declare a class as a swift stub once", cd.kind, cd.toPrettyChars); | ||
| } | ||
|
|
||
| /// Returns: the number of times `cd` has been declared as optional. | ||
| private int declaredAsSwiftStubCount(ClassDeclaration cd, Scope* sc) const | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this exactly the same as
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Possibly but I don't know my way around this codebase very well. Takes a long time to figure out how anything works. Also the Swift stub UDA only applies to classes, as it affects how the isa pointer/classref is dereferenced.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, isn't
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I copied it and modified it as needed since I didn't see an obvious way of checking for UDAs otherwise. I'll look into making it a reusable function after I get some rest.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like you can replace
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, something like that |
||
| { | ||
| int count; | ||
|
|
||
| foreachUda(cd, sc, (e) { | ||
| if (!e.isTypeExp()) | ||
| return 0; | ||
|
|
||
| auto typeExp = e.isTypeExp(); | ||
|
|
||
| if (typeExp.type.ty != Tenum) | ||
| return 0; | ||
|
|
||
| auto typeEnum = cast(TypeEnum) typeExp.type; | ||
|
|
||
| if (isCoreUda(typeEnum.sym, Id.udaSwiftStub)) | ||
| count++; | ||
|
|
||
| return 0; | ||
| }); | ||
|
|
||
| return count; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /* | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,6 +48,10 @@ static llvm::cl::opt<bool> linkNoCpp( | |
| "link-no-cpp", llvm::cl::ZeroOrMore, llvm::cl::Hidden, | ||
| llvm::cl::desc("Disable automatic linking with the C++ standard library.")); | ||
|
|
||
| static llvm::cl::opt<bool> linkNoObjc( | ||
| "link-no-objc", llvm::cl::ZeroOrMore, llvm::cl::Hidden, | ||
| llvm::cl::desc("Disable automatic linking with the Objective-C runtime library.")); | ||
|
|
||
| ////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| namespace { | ||
|
|
@@ -72,6 +76,7 @@ class ArgsBuilder { | |
| virtual void addXRayLinkFlags(const llvm::Triple &triple); | ||
| virtual bool addCompilerRTArchiveLinkFlags(llvm::StringRef baseName, | ||
| const llvm::Triple &triple); | ||
| virtual void addObjcStdlibLinkFlags(const llvm::Triple &triple); | ||
|
|
||
| virtual void addLinker(); | ||
| virtual void addUserSwitches(); | ||
|
|
@@ -467,6 +472,13 @@ void ArgsBuilder::addCppStdlibLinkFlags(const llvm::Triple &triple) { | |
| } | ||
| } | ||
|
|
||
| void ArgsBuilder::addObjcStdlibLinkFlags(const llvm::Triple &triple) { | ||
| if (linkNoObjc) | ||
| return; | ||
|
|
||
| args.push_back("-lobjc"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is different behavior compared to DMD. |
||
| } | ||
|
|
||
| // Adds all required link flags for PGO. | ||
| void ArgsBuilder::addProfileRuntimeLinkFlags(const llvm::Triple &triple) { | ||
| const auto searchPaths = | ||
|
|
@@ -725,6 +737,13 @@ void ArgsBuilder::addDefaultPlatformLibs() { | |
| break; | ||
| } | ||
|
|
||
| if (triple.isOSDarwin()) { | ||
|
|
||
| // libobjc is more or less required, so we link against it here. | ||
| // This could be prettier, though. | ||
| addObjcStdlibLinkFlags(triple); | ||
| } | ||
|
|
||
| if (triple.isWindowsGNUEnvironment()) { | ||
| // This is really more of a kludge, as linking in the Winsock functions | ||
| // should be handled by the pragma(lib, ...) in std.socket, but it | ||
|
|
||
LunaTheFoxgirl marked this conversation as resolved.
Show resolved
Hide resolved
|
Uh oh!
There was an error while loading. Please reload this page.