Skip to content

Commit a26196b

Browse files
committed
[cxx-interop] Extract the C++ stdlib kind from Clang Driver
rdar://118357548 / #69825
1 parent ca0add4 commit a26196b

File tree

3 files changed

+60
-26
lines changed

3 files changed

+60
-26
lines changed

include/swift/ClangImporter/ClangImporter.h

Lines changed: 18 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,16 @@ class ClangImporter final : public ClangModuleLoader {
196204
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
197205
const std::vector<std::string> &CC1Args);
198206

207+
static clang::driver::Driver createClangDriver(
208+
const LangOptions &LangOpts,
209+
const ClangImporterOptions &ClangImporterOpts,
210+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs = nullptr);
211+
212+
static llvm::opt::InputArgList
213+
createClangArgs(const ClangImporterOptions &ClangImporterOpts,
214+
const SearchPathOptions &SearchPathOpts,
215+
clang::driver::Driver &clangDriver);
216+
199217
ClangImporter(const ClangImporter &) = delete;
200218
ClangImporter(ClangImporter &&) = delete;
201219
ClangImporter &operator=(const ClangImporter &) = delete;

lib/ClangImporter/ClangIncludePaths.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,13 @@ parseClangDriverArgs(const clang::driver::Driver &clangDriver,
112112
return clangDriver.getOpts().ParseArgs(args, unused1, unused2);
113113
}
114114

115-
static clang::driver::Driver
116-
createClangDriver(const ASTContext &ctx,
117-
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs) {
115+
clang::driver::Driver ClangImporter::createClangDriver(
116+
const LangOptions &LangOpts, const ClangImporterOptions &ClangImporterOpts,
117+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs) {
118118
auto clangDiags = clang::CompilerInstance::createDiagnostics(
119119
new clang::DiagnosticOptions());
120-
clang::driver::Driver clangDriver(ctx.ClangImporterOpts.clangPath,
121-
ctx.LangOpts.Target.str(), *clangDiags,
120+
clang::driver::Driver clangDriver(ClangImporterOpts.clangPath,
121+
LangOpts.Target.str(), *clangDiags,
122122
"clang LLVM compiler", vfs);
123123
return clangDriver;
124124
}
@@ -162,21 +162,23 @@ static std::optional<Path> findFirstIncludeDir(
162162
return std::nullopt;
163163
}
164164

165-
static llvm::opt::InputArgList
166-
createClangArgs(const ASTContext &ctx, clang::driver::Driver &clangDriver) {
165+
llvm::opt::InputArgList
166+
ClangImporter::createClangArgs(const ClangImporterOptions &ClangImporterOpts,
167+
const SearchPathOptions &SearchPathOpts,
168+
clang::driver::Driver &clangDriver) {
167169
// Flags passed to Swift with `-Xcc` might affect include paths.
168170
std::vector<const char *> clangArgs;
169-
for (const auto &each : ctx.ClangImporterOpts.ExtraArgs) {
171+
for (const auto &each : ClangImporterOpts.ExtraArgs) {
170172
clangArgs.push_back(each.c_str());
171173
}
172174
llvm::opt::InputArgList clangDriverArgs =
173175
parseClangDriverArgs(clangDriver, clangArgs);
174176
// If an SDK path was explicitly passed to Swift, make sure to pass it to
175177
// Clang driver as well. It affects the resulting include paths.
176-
auto sdkPath = ctx.SearchPathOpts.getSDKPath();
178+
auto sdkPath = SearchPathOpts.getSDKPath();
177179
if (!sdkPath.empty())
178180
clangDriver.SysRoot = sdkPath.str();
179-
if (auto sysroot = ctx.SearchPathOpts.getSysRoot())
181+
if (auto sysroot = SearchPathOpts.getSysRoot())
180182
clangDriver.SysRoot = sysroot->str();
181183
return clangDriverArgs;
182184
}
@@ -188,8 +190,10 @@ getLibcFileMapping(ASTContext &ctx, StringRef modulemapFileName,
188190
const llvm::Triple &triple = ctx.LangOpts.Target;
189191

190192
// Extract the libc path from Clang driver.
191-
auto clangDriver = createClangDriver(ctx, vfs);
192-
auto clangDriverArgs = createClangArgs(ctx, clangDriver);
193+
auto clangDriver = ClangImporter::createClangDriver(
194+
ctx.LangOpts, ctx.ClangImporterOpts, vfs);
195+
auto clangDriverArgs = ClangImporter::createClangArgs(
196+
ctx.ClangImporterOpts, ctx.SearchPathOpts, clangDriver);
193197

194198
llvm::opt::ArgStringList includeArgStrings;
195199
const auto &clangToolchain =
@@ -262,8 +266,10 @@ static void getLibStdCxxFileMapping(
262266
return;
263267

264268
// Extract the libstdc++ installation path from Clang driver.
265-
auto clangDriver = createClangDriver(ctx, vfs);
266-
auto clangDriverArgs = createClangArgs(ctx, clangDriver);
269+
auto clangDriver = ClangImporter::createClangDriver(
270+
ctx.LangOpts, ctx.ClangImporterOpts, vfs);
271+
auto clangDriverArgs = ClangImporter::createClangArgs(
272+
ctx.ClangImporterOpts, ctx.SearchPathOpts, clangDriver);
267273

268274
llvm::opt::ArgStringList stdlibArgStrings;
269275
const auto &clangToolchain =
@@ -457,8 +463,10 @@ SmallVector<std::pair<std::string, std::string>, 2> GetWindowsFileMappings(
457463
if (!Triple.isWindowsMSVCEnvironment())
458464
return Mappings;
459465

460-
clang::driver::Driver Driver = createClangDriver(Context, driverVFS);
461-
const llvm::opt::InputArgList Args = createClangArgs(Context, Driver);
466+
clang::driver::Driver Driver = ClangImporter::createClangDriver(
467+
Context.LangOpts, Context.ClangImporterOpts, driverVFS);
468+
const llvm::opt::InputArgList Args = ClangImporter::createClangArgs(
469+
Context.ClangImporterOpts, Context.SearchPathOpts, Driver);
462470
const clang::driver::ToolChain &ToolChain = Driver.getToolChain(Args, Triple);
463471
llvm::vfs::FileSystem &VFS = ToolChain.getVFS();
464472

lib/Frontend/CompilerInvocation.cpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "clang/Driver/Driver.h"
1314
#include "swift/AST/SILOptions.h"
1415
#include "swift/Basic/DiagnosticOptions.h"
1516
#include "swift/Frontend/Frontend.h"
@@ -335,6 +336,22 @@ setBridgingHeaderFromFrontendOptions(ClangImporterOptions &ImporterOpts,
335336
FrontendOpts.InputsAndOutputs.getFilenameOfFirstInput();
336337
}
337338

339+
static void setCXXStdlibOpts(LangOptions &LangOpts,
340+
const ClangImporterOptions &ClangImporterOpts,
341+
const SearchPathOptions &SearchPathOpts) {
342+
clang::driver::Driver clangDriver =
343+
ClangImporter::createClangDriver(LangOpts, ClangImporterOpts);
344+
auto clangDriverArgs = ClangImporter::createClangArgs(
345+
ClangImporterOpts, SearchPathOpts, clangDriver);
346+
const auto &clangTC =
347+
clangDriver.getToolChain(clangDriverArgs, LangOpts.Target);
348+
auto cxxStdlibKind = clangTC.GetCXXStdlibType(clangDriverArgs);
349+
if (LangOpts.Target.isOSLinux() &&
350+
cxxStdlibKind == clang::driver::ToolChain::CST_Libcxx) {
351+
LangOpts.CXXStdlib = CXXStdlibKind::OverrideLibcxx;
352+
}
353+
}
354+
338355
void CompilerInvocation::setRuntimeResourcePath(StringRef Path) {
339356
SearchPathOpts.RuntimeResourcePath = Path.str();
340357
updateRuntimeLibraryPaths(SearchPathOpts, FrontendOpts, LangOpts);
@@ -627,16 +644,6 @@ void LangOptions::setCxxInteropFromArgs(ArgList &Args,
627644
cxxInteropCompatVersion =
628645
validateCxxInteropCompatibilityMode("swift-5.9").second;
629646
}
630-
631-
for (const Arg *A : Args.filtered(options::OPT_Xcc)) {
632-
StringRef clangArg = A->getValue();
633-
if (clangArg.consume_front("-stdlib")) {
634-
clangArg.consume_front("=");
635-
if (clangArg.equals("libc++") && Target.isOSLinux())
636-
CXXStdlib = CXXStdlibKind::OverrideLibcxx;
637-
// If the stdlib argument is invalid, Clang will emit an error.
638-
}
639-
}
640647
}
641648

642649
static std::optional<swift::StrictConcurrency>
@@ -3602,6 +3609,7 @@ bool CompilerInvocation::parseArgs(
36023609
// Now that we've parsed everything, setup some inter-option-dependent state.
36033610
setIRGenOutputOptsFromFrontendOptions(IRGenOpts, FrontendOpts);
36043611
setBridgingHeaderFromFrontendOptions(ClangImporterOpts, FrontendOpts);
3612+
setCXXStdlibOpts(LangOpts, ClangImporterOpts, SearchPathOpts);
36053613
if (LangOpts.hasFeature(Feature::Embedded)) {
36063614
IRGenOpts.InternalizeAtLink = true;
36073615
IRGenOpts.DisableLegacyTypeInfo = true;

0 commit comments

Comments
 (0)