Skip to content

Commit bfe72b4

Browse files
authored
Merge pull request #75589 from swiftlang/egorzhdan/linux-libcxx-interop
[cxx-interop] Allow compiling with libc++ on Linux
2 parents a1eed1f + 059f0f9 commit bfe72b4

31 files changed

+348
-28
lines changed

include/swift/AST/Decl.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
722722
HasAnyUnavailableDuringLoweringValues : 1
723723
);
724724

725-
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1,
725+
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+8,
726726
/// If the module is compiled as static library.
727727
StaticLibrary : 1,
728728

@@ -780,6 +780,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
780780
/// Whether this module has been built with C++ interoperability enabled.
781781
HasCxxInteroperability : 1,
782782

783+
/// Whether this module uses the platform default C++ stdlib, or an
784+
/// overridden C++ stdlib.
785+
CXXStdlibKind : 8,
786+
783787
/// Whether this module has been built with -allow-non-resilient-access.
784788
AllowNonResilientAccess : 1,
785789

include/swift/AST/DiagnosticEngine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ namespace swift {
5050
class ValueDecl;
5151
class SourceFile;
5252

53+
enum class CXXStdlibKind : uint8_t;
5354
enum class DescriptivePatternKind : uint8_t;
5455
enum class SelfAccessKind : uint8_t;
5556
enum class ReferenceOwnership : uint8_t;

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,10 @@ ERROR(need_cxx_interop_to_import_module,none,
942942
NOTE(enable_cxx_interop_docs,none,
943943
"visit https://www.swift.org/documentation/cxx-interop/project-build-setup to learn how to enable C++ interoperability", ())
944944

945+
ERROR(cxx_stdlib_kind_mismatch,none,
946+
"module %0 was built with %1, but current compilation uses %2",
947+
(Identifier, StringRef, StringRef))
948+
945949
ERROR(modularization_issue_decl_moved,Fatal,
946950
"reference to %select{top-level declaration|type}0 %1 broken by a context change; "
947951
"%1 was expected to be in %2, but now a candidate is found only in %3",

include/swift/AST/Module.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "swift/AST/Type.h"
2828
#include "swift/Basic/Assertions.h"
2929
#include "swift/Basic/BasicSourceInfo.h"
30+
#include "swift/Basic/CXXStdlibKind.h"
3031
#include "swift/Basic/Compiler.h"
3132
#include "swift/Basic/Debug.h"
3233
#include "swift/Basic/OptionSet.h"
@@ -705,6 +706,13 @@ class ModuleDecl
705706
Bits.ModuleDecl.HasCxxInteroperability = enabled;
706707
}
707708

709+
CXXStdlibKind getCXXStdlibKind() const {
710+
return static_cast<CXXStdlibKind>(Bits.ModuleDecl.CXXStdlibKind);
711+
}
712+
void setCXXStdlibKind(CXXStdlibKind kind) {
713+
Bits.ModuleDecl.CXXStdlibKind = static_cast<uint8_t>(kind);
714+
}
715+
708716
/// \returns true if this module is a system module; note that the StdLib is
709717
/// considered a system module.
710718
bool isSystemModule() const {

include/swift/AST/ModuleDependencies.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/AST/Import.h"
2222
#include "swift/AST/LinkLibrary.h"
2323
#include "swift/AST/SearchPathOptions.h"
24+
#include "swift/Basic/CXXStdlibKind.h"
2425
#include "swift/Basic/LLVM.h"
2526
#include "clang/CAS/CASOptions.h"
2627
#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
@@ -135,7 +136,7 @@ void registerBackDeployLibraries(
135136
std::function<void(const LinkLibrary &)> RegistrationCallback);
136137
void registerCxxInteropLibraries(
137138
const llvm::Triple &Target, StringRef mainModuleName, bool hasStaticCxx,
138-
bool hasStaticCxxStdlib,
139+
bool hasStaticCxxStdlib, CXXStdlibKind cxxStdlibKind,
139140
std::function<void(const LinkLibrary &)> RegistrationCallback);
140141
} // namespace dependencies
141142

include/swift/Basic/CXXStdlibKind.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===--- CXXStdlibKind.h ----------------------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_BASIC_CXX_STDLIB_KIND_H
14+
#define SWIFT_BASIC_CXX_STDLIB_KIND_H
15+
16+
namespace swift {
17+
18+
enum class CXXStdlibKind : uint8_t {
19+
Unknown = 0,
20+
21+
/// libc++ is the default C++ stdlib on Darwin platforms. It is also supported
22+
/// on Linux when explicitly requested via `-Xcc -stdlib=libc++` flag.
23+
Libcxx = 1,
24+
25+
/// libstdc++ is the default C++ stdlib on most Linux distributions.
26+
Libstdcxx = 2,
27+
28+
/// msvcprt is used when targeting Windows.
29+
Msvcprt = 3,
30+
};
31+
32+
inline std::string to_string(CXXStdlibKind kind) {
33+
switch (kind) {
34+
case CXXStdlibKind::Unknown:
35+
return "unknown C++ stdlib";
36+
case CXXStdlibKind::Libcxx:
37+
return "libc++";
38+
case CXXStdlibKind::Libstdcxx:
39+
return "libstdc++";
40+
case CXXStdlibKind::Msvcprt:
41+
return "msvcprt";
42+
}
43+
llvm_unreachable("unhandled CXXStdlibKind");
44+
}
45+
46+
} // namespace swift
47+
48+
#endif // SWIFT_BASIC_CXX_STDLIB_KIND_H

include/swift/Basic/LangOptions.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define SWIFT_BASIC_LANGOPTIONS_H
2020

2121
#include "swift/AST/DiagnosticsFrontend.h"
22+
#include "swift/Basic/CXXStdlibKind.h"
2223
#include "swift/Basic/Feature.h"
2324
#include "swift/Basic/FixedBitSet.h"
2425
#include "swift/Basic/FunctionBodySkipping.h"
@@ -325,6 +326,16 @@ namespace swift {
325326
void setCxxInteropFromArgs(llvm::opt::ArgList &Args,
326327
swift::DiagnosticEngine &Diags);
327328

329+
/// The C++ standard library used for the current build. This can differ
330+
/// from the default C++ stdlib on a particular platform when `-Xcc
331+
/// -stdlib=xyz` was passed to the compiler.
332+
CXXStdlibKind CXXStdlib = CXXStdlibKind::Unknown;
333+
CXXStdlibKind PlatformDefaultCXXStdlib = CXXStdlibKind::Unknown;
334+
335+
bool isUsingPlatformDefaultCXXStdlib() const {
336+
return CXXStdlib == PlatformDefaultCXXStdlib;
337+
}
338+
328339
bool CForeignReferenceTypes = false;
329340

330341
/// Imports getters and setters as computed properties.

include/swift/ClangImporter/ClangImporter.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ namespace llvm {
2626
class Triple;
2727
class FileCollectorBase;
2828
template<typename Fn> class function_ref;
29+
namespace opt {
30+
class InputArgList;
31+
}
2932
namespace vfs {
3033
class FileSystem;
3134
class OutputBackend;
@@ -51,6 +54,9 @@ namespace clang {
5154
class DeclarationName;
5255
class CompilerInvocation;
5356
class TargetOptions;
57+
namespace driver {
58+
class Driver;
59+
}
5460
namespace tooling {
5561
namespace dependencies {
5662
struct ModuleDeps;
@@ -74,9 +80,11 @@ class EnumDecl;
7480
class FuncDecl;
7581
class ImportDecl;
7682
class IRGenOptions;
83+
class LangOptions;
7784
class ModuleDecl;
7885
struct ModuleDependencyID;
7986
class NominalTypeDecl;
87+
class SearchPathOptions;
8088
class StructDecl;
8189
class SwiftLookupTable;
8290
class TypeDecl;
@@ -196,6 +204,22 @@ class ClangImporter final : public ClangModuleLoader {
196204
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
197205
const std::vector<std::string> &CC1Args);
198206

207+
/// Creates a Clang Driver based on the Swift compiler options.
208+
///
209+
/// \return a pair of the Clang Driver and the diagnostic engine, which needs
210+
/// to be alive during the use of the Driver.
211+
static std::pair<clang::driver::Driver,
212+
llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine>>
213+
createClangDriver(
214+
const LangOptions &LangOpts,
215+
const ClangImporterOptions &ClangImporterOpts,
216+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs = nullptr);
217+
218+
static llvm::opt::InputArgList
219+
createClangArgs(const ClangImporterOptions &ClangImporterOpts,
220+
const SearchPathOptions &SearchPathOpts,
221+
clang::driver::Driver &clangDriver);
222+
199223
ClangImporter(const ClangImporter &) = delete;
200224
ClangImporter(ClangImporter &&) = delete;
201225
ClangImporter &operator=(const ClangImporter &) = delete;

include/swift/Frontend/Frontend.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ class CompilerInvocation {
256256
/// FIXME: Remove this after all the clients start sending it.
257257
void setDefaultInProcessPluginServerPathIfNecessary();
258258

259+
/// Determine which C++ stdlib should be used for this compilation, and which
260+
/// C++ stdlib is the default for the specified target.
261+
void computeCXXStdlibOptions();
262+
259263
/// Computes the runtime resource path relative to the given Swift
260264
/// executable.
261265
static void computeRuntimeResourcePathFromExecutablePath(

include/swift/Serialization/Validation.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define SWIFT_SERIALIZATION_VALIDATION_H
1515

1616
#include "swift/AST/Identifier.h"
17+
#include "swift/Basic/CXXStdlibKind.h"
1718
#include "swift/Basic/LLVM.h"
1819
#include "swift/Basic/Version.h"
1920
#include "swift/Serialization/SerializationOptions.h"
@@ -128,6 +129,7 @@ class ExtendedValidationInfo {
128129
StringRef ModuleABIName;
129130
StringRef ModulePackageName;
130131
StringRef ExportAsName;
132+
CXXStdlibKind CXXStdlib;
131133
struct {
132134
unsigned ArePrivateImportsEnabled : 1;
133135
unsigned IsSIB : 1;
@@ -241,6 +243,9 @@ class ExtendedValidationInfo {
241243
void setHasCxxInteroperability(bool val) {
242244
Bits.HasCxxInteroperability = val;
243245
}
246+
247+
CXXStdlibKind getCXXStdlibKind() const { return CXXStdlib; }
248+
void setCXXStdlibKind(CXXStdlibKind kind) { CXXStdlib = kind; }
244249
};
245250

246251
struct SearchPath {

0 commit comments

Comments
 (0)