-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[interop][SwiftToC++] print C++ interface for top-level Swift functions #40995
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
@swift-ci please test |
Build failed |
@@ -2012,7 +2147,8 @@ class DeclAndTypePrinter::Implementation | |||
public: | |||
void print(Type ty, Optional<OptionalTypeKind> optionalKind, | |||
Identifier name = Identifier(), | |||
IsFunctionParam_t isFuncParam = IsNotFunctionParam) { | |||
IsFunctionParam_t isFuncParam = IsNotFunctionParam, | |||
size_t *nameIndex = nullptr) { |
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.
This doesn't make sense as an API. Please use optional, or maybe a signed type. But optional is probably best.
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.
I was also thinking, maybe we could compute this in the caller and just pass it as name
.
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.
Another thought: this requires a bit of refactoring but name
doesn't need to be an Identifier
which might help. We could refactor it to be a std::string
and in the caller just use std::to_string
.
std::tie(objTy, kind) = | ||
getObjectTypeAndOptionality(param, param->getInterfaceType()); | ||
print(objTy, kind, param->getName(), IsFunctionParam, | ||
printEmptyParamNames ? &index : nullptr); |
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.
See below comment.
os << "inline "; | ||
printFunctionDeclAsCFunctionDecl(FD, | ||
FD->getName().getBaseIdentifier().get(), | ||
resultTy, /*printEmptyParamNames=*/true); |
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.
Why only print empty param names some places? Seems like that should maybe be a global config. Then you also wouldn't have to launder an int down to print
.
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.
we need to print out empty parameters for the inline thunks specifically as we need to use them in the body.
|
||
namespace swift { | ||
|
||
namespace cxx_synthesis { |
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.
I don't think there's anything wrong with this, but usually, there'd be some object which we put all these functions in. Maybe Implementation
?
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.
Sure, I can pull it into an object class.
} | ||
} | ||
|
||
StringRef getSymbolName() const { |
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.
This is returning a reference to a string owned by the object, which is a bug waiting to happen. I wonder if it wouldn't be better to allocate mangledName
in the AST context and just hold one StringRef
.
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.
Good idea.
} | ||
|
||
void printAbstractFunctionAsCxxFunctionThunk( | ||
FuncDecl *FD, const FuncionSwiftABIInformation &funcABI) { |
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.
FuncDecl *FD, const FuncionSwiftABIInformation &funcABI) { | |
FuncDecl *FD, const FuncionSwiftABIInformation &funcABI) { | |
assert(outputLang == OutputLanguageMode::Cxx); |
}; | ||
|
||
FuncionSwiftABIInformation | ||
printSwiftABIFunctionSignatureAsCxxFunction(FuncDecl *FD) { |
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.
Maybe add a comment above this and printAbstractFunctionAsCxxFunctionThunk
to explain roughly what they do and why you would use one vs the other.
auto params = FD->getParameters(); | ||
if (params->size()) { | ||
size_t index = 1; | ||
interleave( |
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.
Nit: interleaveComma
// CHECK: extern "C" int cfuncPassTwo(int x, int y) noexcept; | ||
// CHECK: } | ||
|
||
@_cdecl("cfuncPassTwo") |
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 kind of interesting that this cdecl name is different from the declared fn, so maybe the name should be differentCDeclName
or something like that. What do you think?
(Or maybe the test name?)
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.
Yeah, that makes sense to me.
@@ -0,0 +1,19 @@ | |||
// RUN: %empty-directory(%t) | |||
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %s -typecheck -module-name CdeclFunctions -emit-cxx-header-path %t/empty.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.
Do we need the mock sdk here?
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.
Nope, removed.
// RUN: %check-cxx-header-in-clang -std=c++14 %t/empty.h | ||
// RUN: %check-cxx-header-in-clang -std=c++17 %t/empty.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.
We can't automate this to run 5-10 configs?
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.
Good idea. I can do that as a follow-up.
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.
Added support here: #41794
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.
Overall, looks really good. Excited to see the progress! I may have a couple more comments, but generally it looks good.
@LebJe, @hooray I noticed both of you have been putting emojis on the interop patches. If you're just watching from the side lines, that's totally fine (and thanks for the encouragement). But if you want to get involved in the project, please reach out to me (either on the forums or my email) and I can help you get started :) |
@zoecarver @hyp is this a better alternative to @_cdecl? |
I mean, "better" is really subjective. I think we may actually not take this path of "export everything," and instead require users to mark the functions they want exported. Maybe this can be one of the first working group discussions :) |
db66120
to
fcdcb2a
Compare
@zoecarver please take another look. I will need to make some changes in a follow-up PR related to unified header, but I would like to land this one first. |
@swift-ci please test |
So this is still exporting everything? |
For now yes, I will need to resolve that in the future follow-up PRs |
@swift-ci please test linux platform |
@swift-ci please test windows platform |
@swift-ci please test linux platform |
@swift-ci please test |
… with /MD msvc mode
@swift-ci please test |
@swift-ci please test |
@swift-ci please test linux platform |
@swift-ci please smoke test |
1 similar comment
@swift-ci please smoke test |
@swift-ci please smoke test linux platform |
Emit C++ function thunks that correspond to Swift top-level functions, alongside their
extern "C"
function signatures, which are places in the_impl
namespace in the module's namespace.