This is an archive of the discontinued LLVM Phabricator instance.

[clang] CodeGen: Make getOrEmitProtocol public for Swift
ClosedPublic

Authored by aschwaighofer on Mar 30 2020, 11:24 AM.

Details

Summary

Swift would like to use clang's abis to emit protocol declarations.

It needs to a hook to register when inherited protocols are emitted.

This commits adds the public API:

emitProtocolDecl(CodeGenModule &CGM, const ObjCProtocolDecl *p,

llvm::function_ref<llvm::Constant *(const ObjCProtocolDecl *)>
    createProtocolReference);

rdar://60888524

Diff Detail

Event Timeline

aschwaighofer created this revision.Mar 30 2020, 11:24 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 30 2020, 11:25 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
rjmccall added inline comments.Mar 30 2020, 12:13 PM
clang/include/clang/CodeGen/CodeGenABITypes.h
148

I would call this emitObjCProtocolObject or something, and maybe say in the comment:

Get a pointer to a protocol object for the given declaration, emitting it if it hasn't already been emitted in this translation unit. Note that the ABI for emitting a protocol reference in code (e.g. for a @protocol expression) in most runtimes is not as simple as just materializing a pointer to this object.

Can you explain the need for the callback? Are you expecting to use this for Swift-declared protocols by synthesizing an ObjC protocol declaration for them? I can see why you'd need a callback in that case.

Can you explain the need for the callback? Are you expecting to use this for Swift-declared protocols by synthesizing an ObjC protocol declaration for them? I can see why you'd need a callback in that case.

The objective C protocol references other protocols in its inherited list. Swift has an internal list that keeps track of those protocols references and makes sure to initialized them for the debugger and also makes sure that the underlying protocol structure is emitted. The call back is to keep this list in sync.

  • Change API name to emitObjCProtocolObject.
  • Make stuff compile on current ToT.
aschwaighofer marked an inline comment as done.Mar 30 2020, 2:58 PM
aschwaighofer added inline comments.
clang/include/clang/CodeGen/CodeGenABITypes.h
148

Can you explain the need for the callback? Are you expecting to use this for Swift-declared protocols by synthesizing an ObjC protocol declaration for them? I can see why you'd need a callback in that case.

The objective C protocol references other protocols in its inherited list. Swift has an internal list that keeps track of those protocols references and makes sure to initialized them for the debugger and also makes sure that the underlying protocol structure is emitted. The call back is to keep this list in sync.

rjmccall added inline comments.Mar 30 2020, 9:15 PM
clang/include/clang/CodeGen/CodeGenABITypes.h
148

The problem is that this is really, really intertwined with the ABI logic. This callback basically has to know exactly how the caller is calling it and and what it's expected to build in response.

Swift code can use arbitrary inline Objective-C functions and therefore emit arbitrary Objective-C code. Is there an approach that handles that while also being less invasive for Clang IRGen? Can we, e.g., inspect the built llvm::Module to figure out retroactively what protocol refs we need to update dynamically instead of trying to track them during the build?

  • Remove callback. Swift can inspect the generated IR and update it.
aschwaighofer marked an inline comment as done.Mar 31 2020, 11:41 AM
aschwaighofer added inline comments.
clang/include/clang/CodeGen/CodeGenABITypes.h
148

Yes. I think you are right. Swift can inspect the generated IR and update it.

https://github.com/aschwaighofer/swift/commit/d29daf41ec3a51405df31591dad6fea97dbc58e0

I have removed the callback.

rjmccall added inline comments.Mar 31 2020, 2:11 PM
clang/lib/CodeGen/CGObjCGNU.cpp
623

I think this is just the (unfortunately-named) GenerateProtocolRef (the one that just takes a protocol and not a CGF).

clang/lib/CodeGen/CGObjCRuntime.h
217

Can this name more closely parallel the "external" name, like getOrEmitProtocolObject?

Also, I think we're incrementally lowercasing new method names.

aschwaighofer marked an inline comment as done.Mar 31 2020, 4:11 PM
aschwaighofer added inline comments.
clang/lib/CodeGen/CGObjCRuntime.h
217

This is an already existing method. I just moved it higher in the class hierarchy to CGObjCRuntime from CGObjCMac so that it is callable from getOrEmitProtocolObject.

aschwaighofer marked an inline comment as done.Mar 31 2020, 4:31 PM
aschwaighofer added inline comments.
clang/lib/CodeGen/CGObjCRuntime.h
217

s/getOrEmitProtocolObject/emitObjCProtocolObject

rjmccall added inline comments.Mar 31 2020, 6:54 PM
clang/lib/CodeGen/CGObjCRuntime.h
217

I see. Well, in that case, I won't ask you to rename it, but please do implement it for the GNU runtime as I mentioned.

  • Implement for the GNU runtimes
aschwaighofer marked an inline comment as done.Apr 1 2020, 5:28 AM
aschwaighofer added inline comments.
clang/lib/CodeGen/CGObjCRuntime.h
217

Done. I introduced
CGObjCGNU::GenerateProtocolRef(const ObjCProtocolDecl *PD) because it only existed in the CGObjCGNUstep2 subclass.

rjmccall accepted this revision.Apr 1 2020, 8:36 AM

Thanks, LGTM.

This revision is now accepted and ready to land.Apr 1 2020, 8:36 AM
This revision was automatically updated to reflect the committed changes.