Skip to content

[interop] add an option to emit C++ header interface for a module #40923

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

Merged
merged 1 commit into from
Jan 20, 2022

Conversation

hyp
Copy link
Contributor

@hyp hyp commented Jan 20, 2022

This is an initial patch to start adding support for emitting C++ header interfaces for a module. It adds two option flags - -emit-cxx-header and -emit-cxx-header-path, similar to what exists for Objective-C headers. The added flag calls into a new printAsCxx function, which doesn't print out the module contents yet, but will do so in the future. The PrintAsObjC library will be renamed to PrintAsClang in a follow-up PR.

@hyp hyp added the c++ interop Feature: Interoperability with C++ label Jan 20, 2022
@hyp
Copy link
Contributor Author

hyp commented Jan 20, 2022

@swift-ci please smoke test

@hyp
Copy link
Contributor Author

hyp commented Jan 20, 2022

Also, driver support for this option will be added in a follow-up patch too.

@@ -0,0 +1,54 @@
// RUN: %empty-directory(%t)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to put this in Interop? Like test/Interop/Swift or something?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, not sure. I think something like test/Interop/Swift doesn't make the most sense as it implies Swift is interoperating with itself. I think sticking to PrintAsCxx might make more sense.

@@ -0,0 +1,54 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %s -typecheck -emit-cxx-header-path %t/empty.h
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: do you need -typecheck? Can this just be %target-swift-frontend -emit-cxx-header-path %t/empty.h?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, as the default mode doesn't type check and in the default mode we get this error as per canActionEmitClangHeader:

<unknown>:0: error: this mode does not support emitting C++ headers

Copy link
Contributor

@zoecarver zoecarver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so awesome! Can't wait to see it land! 🚀

@hyp
Copy link
Contributor Author

hyp commented Jan 20, 2022

@swift-ci please test

Copy link
Contributor

@egorzhdan egorzhdan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

///
/// \returns true if there were any errors
///
/// \see swift::printAsCxx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: that function is spelled swift::printAsCXX with capital XX :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I'll fix it up in the next patch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hyp hyp merged commit e0eec4d into swiftlang:main Jan 20, 2022
@@ -578,6 +587,7 @@ createFromTypeToPathMap(const TypeToPathMap *map) {
return paths;
const std::pair<file_types::ID, std::string &> typesAndStrings[] = {
{file_types::TY_ObjCHeader, paths.ObjCHeaderOutputPath},
{file_types::TY_ObjCHeader, paths.CxxHeaderOutputPath},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a problem, because we have two different outputs associated with the same entry in the output file map, so we'll end up writing both the ObjC and C++ header to the same place. I've fixed the issue via #41015, but I think we should reconsider having separate ObjC vs. C++ generated headers. It's a mess for the build system, and what would we do about Objective-C++? Instead, I think we should generate a single header that uses #ifdefs to appropriately compile as C/ObjC/C++/ObjC++.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Doug, thanks for fixing this, and sorry about the breakage. I'm not sure if we would like to generate a single header, instead we actually would prefer to generate multiple C++ headers as they will be target-specific, one per target, and then have the build system create a unified C++ header one from them. Do you think that would be a reasonable idea, and should we even support path map in that case? Also, I don't believe we want to emit Objective-C++ headers, as that would be ambiguous - we would either want to emit Objective-C or C++, and then the programmer can import their preferred interface into Objective-C++ as desired.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ interop Feature: Interoperability with C++
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants