Skip to content

Commit 6411327

Browse files
committed
ClangImporter: run Clang with a proper executable path (pt 2)
This change re-applies swiftlang#36749 after it has been reverted in swiftlang#37805 because of a broken standalone stdlib build.
1 parent 3368d9c commit 6411327

File tree

12 files changed

+62
-3
lines changed

12 files changed

+62
-3
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,10 @@ namespace swift {
642642
/// Options for controlling the behavior of the Clang importer.
643643
class ClangImporterOptions final {
644644
public:
645+
/// The path to the Clang compiler executable.
646+
/// Used to detect the default include paths.
647+
std::string clangPath = "clang";
648+
645649
/// The module cache path which the Clang importer should use.
646650
std::string ModuleCachePath;
647651

lib/ClangImporter/ClangImporter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ ClangImporter::getClangArguments(ASTContext &ctx) {
957957
std::vector<std::string> invocationArgStrs;
958958
// Clang expects this to be like an actual command line. So we need to pass in
959959
// "clang" for argv[0]
960-
invocationArgStrs.push_back("clang");
960+
invocationArgStrs.push_back(ctx.ClangImporterOpts.clangPath);
961961
switch (ctx.ClangImporterOpts.Mode) {
962962
case ClangImporterOptions::Modes::Normal:
963963
case ClangImporterOptions::Modes::PrecompiledModule:

lib/Driver/ToolChains.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
263263
inputArgs.AddLastArg(arguments, options::OPT_swift_version);
264264
inputArgs.AddLastArg(arguments, options::OPT_enforce_exclusivity_EQ);
265265
inputArgs.AddLastArg(arguments, options::OPT_stats_output_dir);
266+
inputArgs.AddLastArg(arguments, options::OPT_tools_directory);
266267
inputArgs.AddLastArg(arguments, options::OPT_trace_stats_events);
267268
inputArgs.AddLastArg(arguments, options::OPT_profile_stats_events);
268269
inputArgs.AddLastArg(arguments, options::OPT_profile_stats_entities);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ void CompilerInvocation::setMainExecutablePath(StringRef Path) {
6666
Path, FrontendOpts.UseSharedResourceFolder, LibPath);
6767
setRuntimeResourcePath(LibPath.str());
6868

69+
llvm::SmallString<128> clangPath(Path);
70+
llvm::sys::path::remove_filename(clangPath);
71+
llvm::sys::path::append(clangPath, "clang");
72+
ClangImporterOpts.clangPath = std::string(clangPath);
73+
6974
llvm::SmallString<128> DiagnosticDocsPath(Path);
7075
llvm::sys::path::remove_filename(DiagnosticDocsPath); // Remove /swift
7176
llvm::sys::path::remove_filename(DiagnosticDocsPath); // Remove /bin
@@ -952,6 +957,18 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts,
952957
StringRef workingDirectory) {
953958
using namespace options;
954959

960+
if (const Arg *a = Args.getLastArg(OPT_tools_directory)) {
961+
// If a custom tools directory is specified, try to find Clang there.
962+
// This is useful when the Swift executable is located in a different
963+
// directory than the Clang/LLVM executables, for example, when building
964+
// the Swift project itself.
965+
llvm::SmallString<128> clangPath(a->getValue());
966+
llvm::sys::path::append(clangPath, "clang");
967+
if (llvm::sys::fs::exists(clangPath)) {
968+
Opts.clangPath = std::string(clangPath);
969+
}
970+
}
971+
955972
if (const Arg *A = Args.getLastArg(OPT_module_cache_path)) {
956973
Opts.ModuleCachePath = A->getValue();
957974
}

stdlib/cmake/modules/SwiftSource.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,10 @@ function(_compile_swift_files
403403
compute_library_subdir(library_subdir
404404
"${library_subdir_sdk}" "${SWIFTFILE_ARCHITECTURE}")
405405

406+
if(NOT "${SWIFT_NATIVE_CLANG_TOOLS_PATH}" STREQUAL "")
407+
list(APPEND swift_flags "-tools-directory" "${SWIFT_NATIVE_CLANG_TOOLS_PATH}")
408+
endif()
409+
406410
# If we have a custom module cache path, use it.
407411
if (SWIFT_MODULE_CACHE_PATH)
408412
list(APPEND swift_flags "-module-cache-path" "${SWIFT_MODULE_CACHE_PATH}")

test/Interop/Cxx/stdlib/Inputs/fake-toolchain/bin/clang

Whitespace-only changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef TEST_INTEROP_CXX_STDLIB_INPUTS_FAKE_TOOLCHAIN_H
2+
#define TEST_INTEROP_CXX_STDLIB_INPUTS_FAKE_TOOLCHAIN_H
3+
4+
namespace FakeNamespace {
5+
6+
void foo(int x) {}
7+
8+
}; // namespace FakeNamespace
9+
10+
#endif
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module FakeToolchain [system] {
2+
header "fake-toolchain.h"
3+
export *
4+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %target-swift-ide-test -print-module -module-to-print=FakeToolchain -tools-directory %S/Inputs/fake-toolchain/bin -source-filename=x -enable-cxx-interop -Xcc -stdlib=libc++ | %FileCheck %s
2+
3+
// Clang driver on Windows doesn't support -stdlib=libc++
4+
// XFAIL: OS=windows-msvc
5+
6+
// CHECK: extension FakeNamespace {
7+
// CHECK: static func foo(_ x: Int32)
8+
// CHECK: }

test/ScanDependencies/module_deps.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ import SubE
122122
// CHECK-NEXT: "-frontend"
123123
// CHECK-NEXT: "-only-use-extra-clang-opts"
124124
// CHECK-NEXT: "-Xcc"
125-
// CHECK-NEXT: "clang"
125+
// CHECK-NEXT: "BUILD_DIR/bin/clang"
126126
// CHECK: "-fsystem-module",
127127
// CHECK-NEXT: "-emit-pcm",
128128
// CHECK-NEXT: "-module-name",

0 commit comments

Comments
 (0)