Skip to content

Commit 4fd0671

Browse files
authored
Merge pull request swiftlang#25870 from pschuh/cpp-1
Add -enable-cxx-interop flag and support for extern "C" {}
2 parents 3f0e69f + fa69a73 commit 4fd0671

File tree

16 files changed

+97
-25
lines changed

16 files changed

+97
-25
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ namespace swift {
147147
/// configuration options.
148148
bool EnableObjCInterop = true;
149149

150+
/// Enable C++ interop code generation and build configuration
151+
/// options. Disabled by default because there is no way to control the
152+
/// language mode of clang on a per-header or even per-module basis. Also
153+
/// disabled because it is not complete.
154+
bool EnableCXXInterop = false;
155+
150156
/// On Darwin platforms, use the pre-stable ABI's mark bit for Swift
151157
/// classes instead of the stable ABI's bit. This is needed when
152158
/// targeting OSes prior to macOS 10.14.4 and iOS 12.2, where

include/swift/Option/FrontendOptions.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,11 @@ def emit_sorted_sil : Flag<["-"], "emit-sorted-sil">,
500500
def emit_syntax : Flag<["-"], "emit-syntax">,
501501
HelpText<"Parse input file(s) and emit the Syntax tree(s) as JSON">, ModeOpt;
502502

503+
def enable_cxx_interop :
504+
Flag<["-"], "enable-cxx-interop">,
505+
HelpText<"Enable C++ interop code generation and config directives">,
506+
Flags<[FrontendOption, HelpHidden]>;
507+
503508
def use_malloc : Flag<["-"], "use-malloc">,
504509
HelpText<"Allocate internal data structures using malloc "
505510
"(for memory debugging)">;

lib/ClangImporter/ClangImporter.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,8 +498,11 @@ getNormalInvocationArguments(std::vector<std::string> &invocationArgStrs,
498498
"-Werror=non-modular-include-in-framework-module");
499499

500500
if (LangOpts.EnableObjCInterop) {
501-
invocationArgStrs.insert(invocationArgStrs.end(),
502-
{"-x", "objective-c", "-std=gnu11", "-fobjc-arc"});
501+
bool EnableCXXInterop = LangOpts.EnableCXXInterop;
502+
invocationArgStrs.insert(
503+
invocationArgStrs.end(),
504+
{"-x", EnableCXXInterop ? "objective-c++" : "objective-c",
505+
EnableCXXInterop ? "-std=gnu++17" : "-std=gnu11", "-fobjc-arc"});
503506
// TODO: Investigate whether 7.0 is a suitable default version.
504507
if (!triple.isOSDarwin())
505508
invocationArgStrs.insert(invocationArgStrs.end(),
@@ -518,7 +521,10 @@ getNormalInvocationArguments(std::vector<std::string> &invocationArgStrs,
518521
});
519522

520523
} else {
521-
invocationArgStrs.insert(invocationArgStrs.end(), {"-x", "c", "-std=gnu11"});
524+
bool EnableCXXInterop = LangOpts.EnableCXXInterop;
525+
invocationArgStrs.insert(invocationArgStrs.end(),
526+
{"-x", EnableCXXInterop ? "c++" : "c",
527+
EnableCXXInterop ? "-std=gnu++17" : "-std=gnu11"});
522528
}
523529

524530
// Set C language options.

lib/ClangImporter/ImportDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8399,7 +8399,7 @@ bool ClangImporter::Implementation::addMemberAndAlternatesToExtension(
83998399
// Quickly check the context and bail out if it obviously doesn't
84008400
// belong here.
84018401
if (auto *importDC = newName.getEffectiveContext().getAsDeclContext())
8402-
if (importDC->isTranslationUnit())
8402+
if (importDC->isFileContext())
84038403
return true;
84048404

84058405
// Then try to import the decl under the specified name.

lib/ClangImporter/ImportName.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,8 +1404,8 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
14041404
case clang::DeclarationName::CXXOperatorName:
14051405
case clang::DeclarationName::CXXUsingDirective:
14061406
case clang::DeclarationName::CXXDeductionGuideName:
1407-
// Handling these is part of C++ interoperability.
1408-
llvm_unreachable("unhandled C++ interoperability");
1407+
// TODO: Handling these is part of C++ interoperability.
1408+
return ImportedName();
14091409

14101410
case clang::DeclarationName::Identifier:
14111411
// Map the identifier.

lib/ClangImporter/SwiftLookupTable.cpp

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ class SwiftLookupTableWriter : public clang::ModuleFileExtensionWriter {
8181
llvm::BitstreamWriter &stream) override;
8282

8383
void populateTable(SwiftLookupTable &table, NameImporter &);
84+
85+
void populateTableWithDecl(SwiftLookupTable &table,
86+
NameImporter &nameImporter, clang::Decl *decl);
8487
};
8588

8689
/// Module file extension reader for the Swift lookup tables.
@@ -1793,21 +1796,35 @@ void importer::finalizeLookupTable(SwiftLookupTable &table,
17931796
}
17941797
}
17951798

1799+
void SwiftLookupTableWriter::populateTableWithDecl(SwiftLookupTable &table,
1800+
NameImporter &nameImporter,
1801+
clang::Decl *decl) {
1802+
// Skip anything from an AST file.
1803+
if (decl->isFromASTFile())
1804+
return;
1805+
1806+
// Iterate into extern "C" {} type declarations.
1807+
if (auto linkageDecl = dyn_cast<clang::LinkageSpecDecl>(decl)) {
1808+
for (auto *decl : linkageDecl->noload_decls()) {
1809+
populateTableWithDecl(table, nameImporter, decl);
1810+
}
1811+
return;
1812+
}
1813+
1814+
// Skip non-named declarations.
1815+
auto named = dyn_cast<clang::NamedDecl>(decl);
1816+
if (!named)
1817+
return;
1818+
1819+
// Add this entry to the lookup table.
1820+
addEntryToLookupTable(table, named, nameImporter);
1821+
}
1822+
17961823
void SwiftLookupTableWriter::populateTable(SwiftLookupTable &table,
17971824
NameImporter &nameImporter) {
17981825
auto &sema = nameImporter.getClangSema();
17991826
for (auto decl : sema.Context.getTranslationUnitDecl()->noload_decls()) {
1800-
// Skip anything from an AST file.
1801-
if (decl->isFromASTFile())
1802-
continue;
1803-
1804-
// Skip non-named declarations.
1805-
auto named = dyn_cast<clang::NamedDecl>(decl);
1806-
if (!named)
1807-
continue;
1808-
1809-
// Add this entry to the lookup table.
1810-
addEntryToLookupTable(table, named, nameImporter);
1827+
populateTableWithDecl(table, nameImporter, decl);
18111828
}
18121829

18131830
// Add macros to the lookup table.

lib/ClangImporter/SwiftLookupTable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ class EffectiveClangContext {
196196
DC = omDecl->getCanonicalDecl();
197197
} else if (auto fDecl = dyn_cast<clang::FunctionDecl>(dc)) {
198198
DC = fDecl->getCanonicalDecl();
199+
} else if (auto nsDecl = dyn_cast<clang::NamespaceDecl>(dc)) {
200+
DC = nsDecl->getCanonicalDecl();
199201
} else {
200202
assert(isa<clang::TranslationUnitDecl>(dc) ||
201203
isa<clang::ObjCContainerDecl>(dc) &&

lib/Driver/ToolChains.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ static void addCommonFrontendArgs(const ToolChain &TC, const OutputInfo &OI,
194194
inputArgs.AddLastArg(arguments, options::OPT_enable_library_evolution);
195195
inputArgs.AddLastArg(arguments, options::OPT_enable_testing);
196196
inputArgs.AddLastArg(arguments, options::OPT_enable_private_imports);
197+
inputArgs.AddLastArg(arguments, options::OPT_enable_cxx_interop);
197198
inputArgs.AddLastArg(arguments, options::OPT_g_Group);
198199
inputArgs.AddLastArg(arguments, options::OPT_debug_info_format);
199200
inputArgs.AddLastArg(arguments, options::OPT_import_underlying_module);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
499499
TargetArg = A->getValue();
500500
}
501501

502+
Opts.EnableCXXInterop |= Args.hasArg(OPT_enable_cxx_interop);
502503
Opts.EnableObjCInterop =
503504
Args.hasFlag(OPT_enable_objc_interop, OPT_disable_objc_interop,
504505
Target.isOSDarwin());

stdlib/public/SwiftShims/GlobalObjects.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424
#include "Visibility.h"
2525

2626
#ifdef __cplusplus
27-
namespace swift { extern "C" {
27+
#ifndef __swift__
28+
namespace swift {
29+
#endif
30+
extern "C" {
2831
#endif
2932

3033
struct _SwiftArrayBodyStorage {
@@ -102,7 +105,10 @@ static_assert(
102105
4 * sizeof(__swift_intptr_t) + sizeof(__swift_int64_t),
103106
"_SwiftSetBodyStorage has unexpected size");
104107

105-
}} // extern "C", namespace swift
108+
} // extern "C"
109+
#ifndef __swift__
110+
} // namespace swift
111+
#endif
106112
#endif
107113

108114
#endif

0 commit comments

Comments
 (0)