-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[cxx-interop] ClangDeclFinder to handle problematic codegen cases #39551
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
Conversation
@zoecarver @egorzhdan @hyp I'd appreciate any comments or considerations here. I intend to continue expanding on this patch, but this is what I have that partly works for now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty good. A few comments, but I want to look into possibly factoring this into the existing ClangDeclFinder
.
Thanks for the patch!
lib/IRGen/GenClangDecl.cpp
Outdated
@@ -82,6 +84,100 @@ clang::Decl *getDeclWithExecutableCode(clang::Decl *decl) { | |||
return nullptr; | |||
} | |||
|
|||
auto walkCallGraphFromCtor(const clang::CXXConstructorDecl *toplevelCtor, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's too bad that the existing ClangDeclFinder
can't be used/extended here. I'm going to look into this API a bit more to see if we could potentially re-use anything.
@@ -0,0 +1,15 @@ | |||
inline int Answer() { return 42; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General notes for the tests:
- Let's match the existing naming convention. TitleCase for classes and camelCase for functions.
- Name the functions based on what they do. So this might be named
returns42
and the next one might bepassThroughArg
. header-defined-functions
doesn't really explain what's being tested here. This is testing when a data member's initializer uses an inline function, so maybe this should go inCxx/class/initializer-from-inline.h
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zoecarver I've addressed most of the review feedback. Ready for more.
test/Interop/Cxx/header-defined-functions/header-defined-functions.swift
Outdated
Show resolved
Hide resolved
d893e96
to
57ae094
Compare
@zoecarver Current diff handles most of the std::vector case as well. I think one big thing I was doing wrong was not picking up a decl if the method body was empty. As this point the only missing linkonceodr function is the destructor. Having some trouble figuring out what the right plumbing is to invoke |
Until this PR lands: swiftlang/swift#39551 this support code is needed.
At the moment, header defined functions do necessarily get codegened by C++-Interop if they are invoked purely on the call path from a constructor. What this means is that when you have inline or template functions that are header defined and are only invoked on a call graph path that only originates from a C++ constructor that is invoked from Swift, that you get LLVM IR Function declares instead of Function defines with linkonceodr. This results in link errors unless those functions happen to be invoked or template instantiated from another TU that gets linked in. This patch teaches the ClangDeclFinder to look for these cases and add them to the list of decls that get handled by HandleTopLevelDecl.
#40867 is a much nicer and more complete solution. Closing. |
#40867 has been in the tree for some time so I tried the examples in the description of SR-15272, notably the one involving |
I'd be interested to explore this more. Are you using a just-built Swift compiler? Do you know what APIs aren't linking? Maybe you can provide the input program you're using? |
Sure, I'll provide as many details as I can. I effectively merged the 2 programs referenced in SR-15272. Here's what I have (all files in the same directory): A.h
Vec.h
module.modulemap
test.swift
I then built I replaced some parts of the longer paths to cut down on a much larger command, hopefully it makes sense.
Let me know if there's anything else you'd like to know. |
At the moment, header defined functions do necessarily get codegened by
C++-Interop if they are invoked purely on the call path from a
constructor. What this means is that when you have inline or template
functions that are header defined and are only invoked on a call graph
path that only originates from a C++ constructor that is invoked from
Swift, that you get LLVM IR Function declares instead of Function
defines with linkonceodr. This results in link errors unless those
functions happen to be invoked or template instantiated from another TU
that gets linked in.
This patch teaches the ClangDeclFinder to look for these cases and add
them to the list of decls that get handled by HandleTopLevelDecl.
Partly addresses SR-15272