[clang][Darwin] Remove legacy framework search path logic in the frontend (#138234)
Move the Darwin framework search path logic from InitHeaderSearch::AddDefaultIncludePaths to DarwinClang::AddClangSystemIncludeArgs. Add a new -internal-iframework cc1 argument to support the tool chain adding these paths. Now that the tool chain is adding search paths via cc1 flag, they're only added if they exist, so the Preprocessor/cuda-macos-includes.cu test is no longer relevant. Change Driver/driverkit-path.c and Driver/darwin-subframeworks.c to do -### style testing similar to the darwin-header-search and darwin-embedded-search-paths tests. Rename darwin-subframeworks.c to darwin-framework-search-paths.c and have it test all framework search paths, not just SubFrameworks. Add a unit test to validate that the myriad of search path flags result in the expected search path list. Fixes https://github.com/llvm/llvm-project/issues/75638
This commit is contained in:
@@ -8452,6 +8452,11 @@ def objc_isystem : Separate<["-"], "objc-isystem">,
|
||||
def objcxx_isystem : Separate<["-"], "objcxx-isystem">,
|
||||
MetaVarName<"<directory>">,
|
||||
HelpText<"Add directory to the ObjC++ SYSTEM include search path">;
|
||||
def internal_iframework : Separate<["-"], "internal-iframework">,
|
||||
MetaVarName<"<directory>">,
|
||||
HelpText<"Add directory to the internal system framework search path; these "
|
||||
"are assumed to not be user-provided and are used to model system "
|
||||
"and standard frameworks' paths.">;
|
||||
def internal_isystem : Separate<["-"], "internal-isystem">,
|
||||
MetaVarName<"<directory>">,
|
||||
HelpText<"Add directory to the internal system include search path; these "
|
||||
|
||||
@@ -226,6 +226,9 @@ protected:
|
||||
|
||||
/// \name Utilities for implementing subclasses.
|
||||
///@{
|
||||
static void addSystemFrameworkInclude(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args,
|
||||
const Twine &Path);
|
||||
static void addSystemInclude(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args,
|
||||
const Twine &Path);
|
||||
@@ -236,6 +239,9 @@ protected:
|
||||
addExternCSystemIncludeIfExists(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args,
|
||||
const Twine &Path);
|
||||
static void addSystemFrameworkIncludes(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args,
|
||||
ArrayRef<StringRef> Paths);
|
||||
static void addSystemIncludes(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args,
|
||||
ArrayRef<StringRef> Paths);
|
||||
|
||||
@@ -67,14 +67,15 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum,
|
||||
return true;
|
||||
|
||||
// Some include flags shouldn't be skipped if we have a crash VFS
|
||||
IsInclude = llvm::StringSwitch<bool>(Flag)
|
||||
.Cases("-include", "-header-include-file", true)
|
||||
.Cases("-idirafter", "-internal-isystem", "-iwithprefix", true)
|
||||
.Cases("-internal-externc-isystem", "-iprefix", true)
|
||||
.Cases("-iwithprefixbefore", "-isystem", "-iquote", true)
|
||||
.Cases("-isysroot", "-I", "-F", "-resource-dir", true)
|
||||
.Cases("-iframework", "-include-pch", true)
|
||||
.Default(false);
|
||||
IsInclude =
|
||||
llvm::StringSwitch<bool>(Flag)
|
||||
.Cases("-include", "-header-include-file", true)
|
||||
.Cases("-idirafter", "-internal-isystem", "-iwithprefix", true)
|
||||
.Cases("-internal-externc-isystem", "-iprefix", true)
|
||||
.Cases("-iwithprefixbefore", "-isystem", "-iquote", true)
|
||||
.Cases("-isysroot", "-I", "-F", "-resource-dir", true)
|
||||
.Cases("-internal-iframework", "-iframework", "-include-pch", true)
|
||||
.Default(false);
|
||||
if (IsInclude)
|
||||
return !HaveCrashVFS;
|
||||
|
||||
|
||||
@@ -1366,10 +1366,17 @@ ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
|
||||
return *cxxStdlibType;
|
||||
}
|
||||
|
||||
/// Utility function to add a system framework directory to CC1 arguments.
|
||||
void ToolChain::addSystemFrameworkInclude(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args,
|
||||
const Twine &Path) {
|
||||
CC1Args.push_back("-internal-iframework");
|
||||
CC1Args.push_back(DriverArgs.MakeArgString(Path));
|
||||
}
|
||||
|
||||
/// Utility function to add a system include directory to CC1 arguments.
|
||||
/*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args,
|
||||
const Twine &Path) {
|
||||
void ToolChain::addSystemInclude(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args, const Twine &Path) {
|
||||
CC1Args.push_back("-internal-isystem");
|
||||
CC1Args.push_back(DriverArgs.MakeArgString(Path));
|
||||
}
|
||||
@@ -1382,9 +1389,9 @@ ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
|
||||
/// "C" semantics. These semantics are *ignored* by and large today, but its
|
||||
/// important to preserve the preprocessor changes resulting from the
|
||||
/// classification.
|
||||
/*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args,
|
||||
const Twine &Path) {
|
||||
void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args,
|
||||
const Twine &Path) {
|
||||
CC1Args.push_back("-internal-externc-isystem");
|
||||
CC1Args.push_back(DriverArgs.MakeArgString(Path));
|
||||
}
|
||||
@@ -1396,19 +1403,28 @@ void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs,
|
||||
addExternCSystemInclude(DriverArgs, CC1Args, Path);
|
||||
}
|
||||
|
||||
/// Utility function to add a list of system framework directories to CC1.
|
||||
void ToolChain::addSystemFrameworkIncludes(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args,
|
||||
ArrayRef<StringRef> Paths) {
|
||||
for (const auto &Path : Paths) {
|
||||
CC1Args.push_back("-internal-iframework");
|
||||
CC1Args.push_back(DriverArgs.MakeArgString(Path));
|
||||
}
|
||||
}
|
||||
|
||||
/// Utility function to add a list of system include directories to CC1.
|
||||
/*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args,
|
||||
ArrayRef<StringRef> Paths) {
|
||||
void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args,
|
||||
ArrayRef<StringRef> Paths) {
|
||||
for (const auto &Path : Paths) {
|
||||
CC1Args.push_back("-internal-isystem");
|
||||
CC1Args.push_back(DriverArgs.MakeArgString(Path));
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/ std::string ToolChain::concat(StringRef Path, const Twine &A,
|
||||
const Twine &B, const Twine &C,
|
||||
const Twine &D) {
|
||||
std::string ToolChain::concat(StringRef Path, const Twine &A, const Twine &B,
|
||||
const Twine &C, const Twine &D) {
|
||||
SmallString<128> Result(Path);
|
||||
llvm::sys::path::append(Result, llvm::sys::path::Style::posix, A, B, C, D);
|
||||
return std::string(Result);
|
||||
|
||||
@@ -2577,6 +2577,27 @@ void AppleMachO::AddClangSystemIncludeArgs(
|
||||
}
|
||||
}
|
||||
|
||||
void DarwinClang::AddClangSystemIncludeArgs(
|
||||
const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const {
|
||||
AppleMachO::AddClangSystemIncludeArgs(DriverArgs, CC1Args);
|
||||
|
||||
if (DriverArgs.hasArg(options::OPT_nostdinc) ||
|
||||
DriverArgs.hasArg(options::OPT_nostdlibinc))
|
||||
return;
|
||||
|
||||
llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);
|
||||
|
||||
// Add <sysroot>/System/Library/Frameworks
|
||||
// Add <sysroot>/System/Library/SubFrameworks
|
||||
// Add <sysroot>/Library/Frameworks
|
||||
SmallString<128> P1(Sysroot), P2(Sysroot), P3(Sysroot);
|
||||
llvm::sys::path::append(P1, "System", "Library", "Frameworks");
|
||||
llvm::sys::path::append(P2, "System", "Library", "SubFrameworks");
|
||||
llvm::sys::path::append(P3, "Library", "Frameworks");
|
||||
addSystemFrameworkIncludes(DriverArgs, CC1Args, {P1, P2, P3});
|
||||
}
|
||||
|
||||
bool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args,
|
||||
llvm::SmallString<128> Base,
|
||||
|
||||
@@ -647,6 +647,10 @@ public:
|
||||
/// @name Apple ToolChain Implementation
|
||||
/// {
|
||||
|
||||
void
|
||||
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const override;
|
||||
|
||||
RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
|
||||
|
||||
void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
|
||||
|
||||
@@ -3373,6 +3373,8 @@ static void GenerateHeaderSearchArgs(const HeaderSearchOptions &Opts,
|
||||
: OPT_internal_externc_isystem;
|
||||
GenerateArg(Consumer, Opt, It->Path);
|
||||
}
|
||||
for (; It < End && Matches(*It, {frontend::System}, true, true); ++It)
|
||||
GenerateArg(Consumer, OPT_internal_iframework, It->Path);
|
||||
|
||||
assert(It == End && "Unhandled HeaderSearchOption::Entry.");
|
||||
|
||||
@@ -3505,6 +3507,8 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
|
||||
Group = frontend::ExternCSystem;
|
||||
Opts.AddPath(A->getValue(), Group, false, true);
|
||||
}
|
||||
for (const auto *A : Args.filtered(OPT_internal_iframework))
|
||||
Opts.AddPath(A->getValue(), frontend::System, true, true);
|
||||
|
||||
// Add the path prefixes which are implicitly treated as being system headers.
|
||||
for (const auto *A :
|
||||
|
||||
@@ -321,6 +321,9 @@ bool InitHeaderSearch::ShouldAddDefaultIncludePaths(
|
||||
break;
|
||||
}
|
||||
|
||||
if (triple.isOSDarwin())
|
||||
return false;
|
||||
|
||||
return true; // Everything else uses AddDefaultIncludePaths().
|
||||
}
|
||||
|
||||
@@ -335,22 +338,6 @@ void InitHeaderSearch::AddDefaultIncludePaths(
|
||||
if (!ShouldAddDefaultIncludePaths(triple))
|
||||
return;
|
||||
|
||||
// NOTE: some additional header search logic is handled in the driver for
|
||||
// Darwin.
|
||||
if (triple.isOSDarwin()) {
|
||||
if (HSOpts.UseStandardSystemIncludes) {
|
||||
// Add the default framework include paths on Darwin.
|
||||
if (triple.isDriverKit()) {
|
||||
AddPath("/System/DriverKit/System/Library/Frameworks", System, true);
|
||||
} else {
|
||||
AddPath("/System/Library/Frameworks", System, true);
|
||||
AddPath("/System/Library/SubFrameworks", System, true);
|
||||
AddPath("/Library/Frameworks", System, true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Lang.CPlusPlus && !Lang.AsmPreprocessor &&
|
||||
HSOpts.UseStandardCXXIncludes && HSOpts.UseStandardSystemIncludes) {
|
||||
if (HSOpts.UseLibcxx) {
|
||||
|
||||
23
clang/test/Driver/darwin-framework-search-paths.c
Normal file
23
clang/test/Driver/darwin-framework-search-paths.c
Normal file
@@ -0,0 +1,23 @@
|
||||
// UNSUPPORTED: system-windows
|
||||
// Windows is unsupported because we use the Unix path separator `/` in the test.
|
||||
|
||||
// RUN: %clang %s -target arm64-apple-macosx15.1 -isysroot %S/Inputs/MacOSX15.1.sdk -c %s -### 2>&1 \
|
||||
// RUN: | FileCheck -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s
|
||||
//
|
||||
// CHECK: "-cc1"
|
||||
// CHECK: "-resource-dir" "[[RESOURCE_DIR:[^"]*]]"
|
||||
// CHECK-SAME: "-internal-iframework" "[[SDKROOT]]/System/Library/Frameworks"
|
||||
// CHECK-SAME: "-internal-iframework" "[[SDKROOT]]/System/Library/SubFrameworks"
|
||||
// CHECK-SAME: "-internal-iframework" "[[SDKROOT]]/Library/Frameworks"
|
||||
|
||||
// Verify that -nostdlibinc and -nostdinc removes the default search paths.
|
||||
//
|
||||
// RUN: %clang %s -target arm64-apple-macosx15.1 -isysroot %S/Inputs/MacOSX15.1.sdk -nostdinc -c %s -### 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-NOSTD -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s
|
||||
//
|
||||
// RUN: %clang %s -target arm64-apple-macosx15.1 -isysroot %S/Inputs/MacOSX15.1.sdk -nostdlibinc -c %s -### 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-NOSTD -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s
|
||||
//
|
||||
// CHECK-NOSTD: "-cc1"
|
||||
// CHECK-NOSTD: "-resource-dir" "[[RESOURCE_DIR:[^"]*]]"
|
||||
// CHECK-NOSTD-NOT: "-internal-iframework"
|
||||
@@ -1,18 +0,0 @@
|
||||
// UNSUPPORTED: system-windows
|
||||
// Windows is unsupported because we use the Unix path separator `\`.
|
||||
|
||||
// Add default directories before running clang to check default
|
||||
// search paths.
|
||||
// RUN: rm -rf %t && mkdir -p %t
|
||||
// RUN: cp -R %S/Inputs/MacOSX15.1.sdk %t/
|
||||
// RUN: mkdir -p %t/MacOSX15.1.sdk/System/Library/Frameworks
|
||||
// RUN: mkdir -p %t/MacOSX15.1.sdk/System/Library/SubFrameworks
|
||||
// RUN: mkdir -p %t/MacOSX15.1.sdk/usr/include
|
||||
|
||||
// RUN: %clang %s -target arm64-apple-darwin13.0 -isysroot %t/MacOSX15.1.sdk -E -v 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: -isysroot [[PATH:[^ ]*/MacOSX15.1.sdk]]
|
||||
// CHECK: #include <...> search starts here:
|
||||
// CHECK: [[PATH]]/usr/include
|
||||
// CHECK: [[PATH]]/System/Library/Frameworks (framework directory)
|
||||
// CHECK: [[PATH]]/System/Library/SubFrameworks (framework directory)
|
||||
@@ -21,13 +21,15 @@ int main() { return 0; }
|
||||
// LD64-NEW: "-isysroot" "[[PATH:[^"]*]]Inputs/DriverKit19.0.sdk"
|
||||
// LD64-NEW-NOT: "-L[[PATH]]Inputs/DriverKit19.0.sdk/System/DriverKit/usr/lib"
|
||||
// LD64-NEW-NOT: "-F[[PATH]]Inputs/DriverKit19.0.sdk/System/DriverKit/System/Library/Frameworks"
|
||||
// LD64-NEW-NOT: "-F[[PATH]]Inputs/DriverKit19.0.sdk/System/DriverKit/System/Library/SubFrameworks"
|
||||
|
||||
|
||||
// RUN: %clang %s -target x86_64-apple-driverkit19.0 -isysroot %S/Inputs/DriverKit19.0.sdk -E -v -x c++ 2>&1 | FileCheck %s --check-prefix=INC
|
||||
// RUN: %clang %s -target x86_64-apple-driverkit19.0 -isysroot %S/Inputs/DriverKit19.0.sdk -x c++ -### 2>&1 \
|
||||
// RUN: | FileCheck %s -DSDKROOT=%S/Inputs/DriverKit19.0.sdk --check-prefix=INC
|
||||
//
|
||||
// INC: -isysroot [[PATH:[^ ]*/Inputs/DriverKit19.0.sdk]]
|
||||
// INC-LABEL: #include <...> search starts here:
|
||||
// INC: [[PATH]]/System/DriverKit/usr/local/include
|
||||
// INC: /lib{{(64)?}}/clang/{{[^/ ]+}}/include
|
||||
// INC: [[PATH]]/System/DriverKit/usr/include
|
||||
// INC: [[PATH]]/System/DriverKit/System/Library/Frameworks (framework directory)
|
||||
// INC: "-isysroot" "[[SDKROOT]]"
|
||||
// INC: "-internal-isystem" "[[SDKROOT]]/System/DriverKit/usr/local/include"
|
||||
// INC: "-internal-isystem" "{{.+}}/lib{{(64)?}}/clang/{{[^/ ]+}}/include"
|
||||
// INC: "-internal-externc-isystem" "[[SDKROOT]]/System/DriverKit/usr/include"
|
||||
// INC: "-internal-iframework" "[[SDKROOT]]/System/DriverKit/System/Library/Frameworks"
|
||||
// INC: "-internal-iframework" "[[SDKROOT]]/System/DriverKit/System/Library/SubFrameworks"
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
// RUN: %clang -cc1 -fcuda-is-device -isysroot /var/empty \
|
||||
// RUN: -triple nvptx-nvidia-cuda -aux-triple i386-apple-macosx \
|
||||
// RUN: -E -fcuda-is-device -v -o /dev/null -x cuda %s 2>&1 | FileCheck %s
|
||||
|
||||
// RUN: %clang -cc1 -isysroot /var/empty \
|
||||
// RUN: -triple i386-apple-macosx -aux-triple nvptx-nvidia-cuda \
|
||||
// RUN: -E -fcuda-is-device -v -o /dev/null -x cuda %s 2>&1 | FileCheck %s
|
||||
|
||||
// Check that when we do CUDA host and device compiles on MacOS, we check for
|
||||
// includes in /System/Library/Frameworks and /Library/Frameworks.
|
||||
|
||||
// CHECK-DAG: ignoring nonexistent directory "/var/empty/System/Library/Frameworks"
|
||||
// CHECK-DAG: ignoring nonexistent directory "/var/empty/Library/Frameworks"
|
||||
@@ -10,6 +10,7 @@ add_clang_unittest(FrontendTests
|
||||
PCHPreambleTest.cpp
|
||||
ReparseWorkingDirTest.cpp
|
||||
OutputStreamTest.cpp
|
||||
SearchPathTest.cpp
|
||||
TextDiagnosticTest.cpp
|
||||
UtilsTest.cpp
|
||||
CLANG_LIBS
|
||||
|
||||
157
clang/unittests/Frontend/SearchPathTest.cpp
Normal file
157
clang/unittests/Frontend/SearchPathTest.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
//====-- unittests/Frontend/SearchPathTest.cpp - FrontendAction tests -----===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/DiagnosticIDs.h"
|
||||
#include "clang/Basic/DiagnosticOptions.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/Basic/FileSystemOptions.h"
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Lex/HeaderSearch.h"
|
||||
#include "clang/Lex/HeaderSearchOptions.h"
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Option/Option.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/VirtualFileSystem.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
namespace {
|
||||
|
||||
class SearchPathTest : public ::testing::Test {
|
||||
protected:
|
||||
SearchPathTest()
|
||||
: Diags(new DiagnosticIDs(), new DiagnosticOptions,
|
||||
new IgnoringDiagConsumer()),
|
||||
VFS(new llvm::vfs::InMemoryFileSystem),
|
||||
FileMgr(FileSystemOptions(), VFS), SourceMgr(Diags, FileMgr),
|
||||
Invocation(std::make_unique<CompilerInvocation>()) {}
|
||||
|
||||
DiagnosticsEngine Diags;
|
||||
IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS;
|
||||
FileManager FileMgr;
|
||||
SourceManager SourceMgr;
|
||||
std::unique_ptr<CompilerInvocation> Invocation;
|
||||
|
||||
void addDirectories(ArrayRef<StringRef> Dirs) {
|
||||
for (StringRef Dir : Dirs) {
|
||||
VFS->addFile(Dir, 0, llvm::MemoryBuffer::getMemBuffer(""),
|
||||
/*User=*/std::nullopt, /*Group=*/std::nullopt,
|
||||
llvm::sys::fs::file_type::directory_file);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<HeaderSearch>
|
||||
makeHeaderSearchFromCC1Args(llvm::opt::ArgStringList Args) {
|
||||
CompilerInvocation::CreateFromArgs(*Invocation, Args, Diags);
|
||||
HeaderSearchOptions HSOpts = Invocation->getHeaderSearchOpts();
|
||||
LangOptions LangOpts = Invocation->getLangOpts();
|
||||
TargetInfo *Target =
|
||||
TargetInfo::CreateTargetInfo(Diags, Invocation->getTargetOpts());
|
||||
auto HeaderInfo = std::make_unique<HeaderSearch>(HSOpts, SourceMgr, Diags,
|
||||
LangOpts, Target);
|
||||
ApplyHeaderSearchOptions(*HeaderInfo, HSOpts, LangOpts,
|
||||
Target->getTriple());
|
||||
return HeaderInfo;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(SearchPathTest, SearchPathOrder) {
|
||||
addDirectories({"One", "Two", "Three", "Four", "Five", "Six", "Seven",
|
||||
"Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen",
|
||||
"Fourteen", "Fifteen", "Sixteen", "Seventeen"});
|
||||
llvm::opt::ArgStringList Args = {
|
||||
// Make sure to use a triple and language that don't automatically add any
|
||||
// search paths.
|
||||
"-triple", "arm64-apple-darwin24.4.0", "-x", "c",
|
||||
|
||||
// clang-format off
|
||||
"-internal-isystem", "One",
|
||||
"-iwithsysroot", "Two",
|
||||
"-c-isystem", "Three",
|
||||
"-IFour",
|
||||
"-idirafter", "Five",
|
||||
"-internal-externc-isystem", "Six",
|
||||
"-iwithprefix", "Seven",
|
||||
"-FEight",
|
||||
"-idirafter", "Nine",
|
||||
"-iframeworkwithsysroot", "Ten",
|
||||
"-internal-iframework", "Eleven",
|
||||
"-iframework", "Twelve",
|
||||
"-iwithprefixbefore", "Thirteen",
|
||||
"-internal-isystem", "Fourteen",
|
||||
"-isystem", "Fifteen",
|
||||
"-ISixteen",
|
||||
"-iwithsysroot", "Seventeen",
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
// The search path arguments get categorized by IncludeDirGroup, but
|
||||
// ultimately are sorted with some groups mixed together and some flags sorted
|
||||
// very specifically within their group. The conceptual groups below don't
|
||||
// exactly correspond to IncludeDirGroup.
|
||||
const std::vector<StringRef> expected = {
|
||||
// User paths: -I and -F mixed together, -iwithprefixbefore.
|
||||
/*-I*/ "Four",
|
||||
/*-F*/ "Eight",
|
||||
/*-I*/ "Sixteen",
|
||||
/*-iwithprefixbefore*/ "Thirteen",
|
||||
|
||||
// System paths: -isystem and -iwithsysroot, -iframework,
|
||||
// -iframeworkwithsysroot, one of {-c-isystem, -cxx-isystem,
|
||||
// -objc-isystem, -objcxx-isystem}
|
||||
/*-iwithsysroot*/ "Two",
|
||||
/*-isystem*/ "Fifteen",
|
||||
/*-iwithsysroot*/ "Seventeen",
|
||||
/*-iframework*/ "Twelve",
|
||||
/*-iframeworkwithsysroot*/ "Ten",
|
||||
/*-c-isystem*/ "Three",
|
||||
|
||||
// Internal paths: -internal-isystem and -internal-externc-isystem,
|
||||
// -internal-iframework
|
||||
/*-internal-isystem*/ "One",
|
||||
/*-internal-externc-isystem*/ "Six",
|
||||
/*-internal-isystem*/ "Fourteen",
|
||||
/*-internal-iframework*/ "Eleven",
|
||||
|
||||
// After paths: -iwithprefix, -idirafter
|
||||
/*-iwithprefix*/ "Seven",
|
||||
/*-idirafter*/ "Five",
|
||||
/*-idirafter*/ "Nine",
|
||||
};
|
||||
|
||||
auto HeaderInfo = makeHeaderSearchFromCC1Args(Args);
|
||||
ConstSearchDirRange SearchDirs(HeaderInfo->angled_dir_begin(),
|
||||
HeaderInfo->search_dir_end());
|
||||
for (auto SearchPaths : zip_longest(SearchDirs, expected)) {
|
||||
auto ActualDirectory = std::get<0>(SearchPaths);
|
||||
EXPECT_TRUE(ActualDirectory.has_value());
|
||||
auto ExpectedPath = std::get<1>(SearchPaths);
|
||||
EXPECT_TRUE(ExpectedPath.has_value());
|
||||
if (ActualDirectory && ExpectedPath) {
|
||||
EXPECT_EQ(ActualDirectory->getName(), *ExpectedPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace clang
|
||||
Reference in New Issue
Block a user