[RISCV] Add missing SiFive P400 scheduling model test for divisions. NFC
[llvm-project.git] / clang / unittests / Driver / ToolChainTest.cpp
blob0787e7d2d33391e7ff56f0533a4ddec8bc038663
1 //===- unittests/Driver/ToolChainTest.cpp --- ToolChain tests -------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Unit tests for ToolChains.
11 //===----------------------------------------------------------------------===//
13 #include "clang/Driver/ToolChain.h"
14 #include "clang/Basic/DiagnosticIDs.h"
15 #include "clang/Basic/DiagnosticOptions.h"
16 #include "clang/Basic/LLVM.h"
17 #include "clang/Basic/TargetInfo.h"
18 #include "clang/Basic/TargetOptions.h"
19 #include "clang/Driver/Compilation.h"
20 #include "clang/Driver/Driver.h"
21 #include "clang/Frontend/CompilerInstance.h"
22 #include "llvm/ADT/ArrayRef.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/MC/TargetRegistry.h"
25 #include "llvm/Support/TargetSelect.h"
26 #include "llvm/Support/VirtualFileSystem.h"
27 #include "llvm/Support/raw_ostream.h"
28 #include "gmock/gmock.h"
29 #include "gtest/gtest.h"
30 #include <memory>
32 #include "SimpleDiagnosticConsumer.h"
34 using namespace clang;
35 using namespace clang::driver;
37 namespace {
39 TEST(ToolChainTest, VFSGCCInstallation) {
40 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
42 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
43 struct TestDiagnosticConsumer : public DiagnosticConsumer {};
44 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
45 new llvm::vfs::InMemoryFileSystem);
47 const char *EmptyFiles[] = {
48 "foo.cpp",
49 "/bin/clang",
50 "/usr/lib/gcc/arm-linux-gnueabi/4.6.1/crtbegin.o",
51 "/usr/lib/gcc/arm-linux-gnueabi/4.6.1/crtend.o",
52 "/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtbegin.o",
53 "/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtend.o",
54 "/usr/lib/arm-linux-gnueabi/crt1.o",
55 "/usr/lib/arm-linux-gnueabi/crti.o",
56 "/usr/lib/arm-linux-gnueabi/crtn.o",
57 "/usr/lib/arm-linux-gnueabihf/crt1.o",
58 "/usr/lib/arm-linux-gnueabihf/crti.o",
59 "/usr/lib/arm-linux-gnueabihf/crtn.o",
60 "/usr/include/arm-linux-gnueabi/.keep",
61 "/usr/include/arm-linux-gnueabihf/.keep",
62 "/lib/arm-linux-gnueabi/.keep",
63 "/lib/arm-linux-gnueabihf/.keep",
65 "/sysroot/usr/lib/gcc/arm-linux-gnueabi/4.5.1/crtbegin.o",
66 "/sysroot/usr/lib/gcc/arm-linux-gnueabi/4.5.1/crtend.o",
67 "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3/crtbegin.o",
68 "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3/crtend.o",
69 "/sysroot/usr/lib/arm-linux-gnueabi/crt1.o",
70 "/sysroot/usr/lib/arm-linux-gnueabi/crti.o",
71 "/sysroot/usr/lib/arm-linux-gnueabi/crtn.o",
72 "/sysroot/usr/lib/arm-linux-gnueabihf/crt1.o",
73 "/sysroot/usr/lib/arm-linux-gnueabihf/crti.o",
74 "/sysroot/usr/lib/arm-linux-gnueabihf/crtn.o",
75 "/sysroot/usr/include/arm-linux-gnueabi/.keep",
76 "/sysroot/usr/include/arm-linux-gnueabihf/.keep",
77 "/sysroot/lib/arm-linux-gnueabi/.keep",
78 "/sysroot/lib/arm-linux-gnueabihf/.keep",
81 for (const char *Path : EmptyFiles)
82 InMemoryFileSystem->addFile(Path, 0,
83 llvm::MemoryBuffer::getMemBuffer("\n"));
86 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
87 Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags,
88 "clang LLVM compiler", InMemoryFileSystem);
89 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
90 {"-fsyntax-only", "--gcc-toolchain=", "--sysroot=", "foo.cpp"}));
91 ASSERT_TRUE(C);
92 std::string S;
94 llvm::raw_string_ostream OS(S);
95 C->getDefaultToolChain().printVerboseInfo(OS);
97 if (is_style_windows(llvm::sys::path::Style::native))
98 std::replace(S.begin(), S.end(), '\\', '/');
99 EXPECT_EQ(
100 "Found candidate GCC installation: "
101 "/usr/lib/gcc/arm-linux-gnueabihf/4.6.3\n"
102 "Selected GCC installation: /usr/lib/gcc/arm-linux-gnueabihf/4.6.3\n"
103 "Candidate multilib: .;@m32\n"
104 "Selected multilib: .;@m32\n",
109 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
110 Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags,
111 "clang LLVM compiler", InMemoryFileSystem);
112 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
113 {"-fsyntax-only", "--gcc-toolchain=", "--sysroot=/sysroot",
114 "foo.cpp"}));
115 ASSERT_TRUE(C);
116 std::string S;
118 llvm::raw_string_ostream OS(S);
119 C->getDefaultToolChain().printVerboseInfo(OS);
121 if (is_style_windows(llvm::sys::path::Style::native))
122 std::replace(S.begin(), S.end(), '\\', '/');
123 // Test that 4.5.3 from --sysroot is not overridden by 4.6.3 (larger
124 // version) from /usr.
125 EXPECT_EQ("Found candidate GCC installation: "
126 "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3\n"
127 "Selected GCC installation: "
128 "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3\n"
129 "Candidate multilib: .;@m32\n"
130 "Selected multilib: .;@m32\n",
135 TEST(ToolChainTest, VFSGCCInstallationRelativeDir) {
136 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
138 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
139 struct TestDiagnosticConsumer : public DiagnosticConsumer {};
140 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
141 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
142 new llvm::vfs::InMemoryFileSystem);
143 Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
144 "clang LLVM compiler", InMemoryFileSystem);
146 const char *EmptyFiles[] = {
147 "foo.cpp", "/home/test/lib/gcc/arm-linux-gnueabi/4.6.1/crtbegin.o",
148 "/home/test/include/arm-linux-gnueabi/.keep"};
150 for (const char *Path : EmptyFiles)
151 InMemoryFileSystem->addFile(Path, 0,
152 llvm::MemoryBuffer::getMemBuffer("\n"));
154 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
155 {"-fsyntax-only", "--gcc-toolchain=", "foo.cpp"}));
156 EXPECT_TRUE(C);
158 std::string S;
160 llvm::raw_string_ostream OS(S);
161 C->getDefaultToolChain().printVerboseInfo(OS);
163 if (is_style_windows(llvm::sys::path::Style::native))
164 std::replace(S.begin(), S.end(), '\\', '/');
165 EXPECT_EQ("Found candidate GCC installation: "
166 "/home/test/bin/../lib/gcc/arm-linux-gnueabi/4.6.1\n"
167 "Selected GCC installation: "
168 "/home/test/bin/../lib/gcc/arm-linux-gnueabi/4.6.1\n"
169 "Candidate multilib: .;@m32\n"
170 "Selected multilib: .;@m32\n",
174 TEST(ToolChainTest, VFSSolarisMultiGCCInstallation) {
175 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
177 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
178 struct TestDiagnosticConsumer : public DiagnosticConsumer {};
179 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
180 new llvm::vfs::InMemoryFileSystem);
182 const char *EmptyFiles[] = {
183 // Sort entries so the latest version doesn't come first.
184 "/usr/gcc/7/lib/gcc/sparcv9-sun-solaris2.11/7.5.0/32/crtbegin.o",
185 "/usr/gcc/7/lib/gcc/sparcv9-sun-solaris2.11/7.5.0/crtbegin.o",
186 "/usr/gcc/7/lib/gcc/x86_64-pc-solaris2.11/7.5.0/32/crtbegin.o",
187 "/usr/gcc/7/lib/gcc/x86_64-pc-solaris2.11/7.5.0/crtbegin.o",
188 "/usr/gcc/11/lib/gcc/sparcv9-sun-solaris2.11/11.4.0/crtbegin.o",
189 "/usr/gcc/11/lib/gcc/sparcv9-sun-solaris2.11/11.4.0/sparcv8plus/crtbegin.o",
190 "/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0/32/crtbegin.o",
191 "/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0/crtbegin.o",
192 "/usr/gcc/4.7/lib/gcc/i386-pc-solaris2.11/4.7.3/amd64/crtbegin.o",
193 "/usr/gcc/4.7/lib/gcc/i386-pc-solaris2.11/4.7.3/crtbegin.o",
194 "/usr/gcc/4.7/lib/gcc/sparc-sun-solaris2.11/4.7.3/crtbegin.o",
195 "/usr/gcc/4.7/lib/gcc/sparc-sun-solaris2.11/4.7.3/sparcv9/crtbegin.o",
198 for (const char *Path : EmptyFiles)
199 InMemoryFileSystem->addFile(Path, 0,
200 llvm::MemoryBuffer::getMemBuffer("\n"));
203 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
204 Driver TheDriver("/bin/clang", "i386-pc-solaris2.11", Diags,
205 "clang LLVM compiler", InMemoryFileSystem);
206 std::unique_ptr<Compilation> C(
207 TheDriver.BuildCompilation({"-v", "--gcc-toolchain=", "--sysroot="}));
208 ASSERT_TRUE(C);
209 std::string S;
211 llvm::raw_string_ostream OS(S);
212 C->getDefaultToolChain().printVerboseInfo(OS);
214 if (is_style_windows(llvm::sys::path::Style::native))
215 std::replace(S.begin(), S.end(), '\\', '/');
216 EXPECT_EQ("Found candidate GCC installation: "
217 "/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0\n"
218 "Selected GCC installation: "
219 "/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0\n"
220 "Candidate multilib: .;@m64\n"
221 "Candidate multilib: 32;@m32\n"
222 "Selected multilib: 32;@m32\n",
227 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
228 Driver TheDriver("/bin/clang", "amd64-pc-solaris2.11", Diags,
229 "clang LLVM compiler", InMemoryFileSystem);
230 std::unique_ptr<Compilation> C(
231 TheDriver.BuildCompilation({"-v", "--gcc-toolchain=", "--sysroot="}));
232 ASSERT_TRUE(C);
233 std::string S;
235 llvm::raw_string_ostream OS(S);
236 C->getDefaultToolChain().printVerboseInfo(OS);
238 if (is_style_windows(llvm::sys::path::Style::native))
239 std::replace(S.begin(), S.end(), '\\', '/');
240 EXPECT_EQ("Found candidate GCC installation: "
241 "/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0\n"
242 "Selected GCC installation: "
243 "/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0\n"
244 "Candidate multilib: .;@m64\n"
245 "Candidate multilib: 32;@m32\n"
246 "Selected multilib: .;@m64\n",
251 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
252 Driver TheDriver("/bin/clang", "x86_64-pc-solaris2.11", Diags,
253 "clang LLVM compiler", InMemoryFileSystem);
254 std::unique_ptr<Compilation> C(
255 TheDriver.BuildCompilation({"-v", "--gcc-toolchain=", "--sysroot="}));
256 ASSERT_TRUE(C);
257 std::string S;
259 llvm::raw_string_ostream OS(S);
260 C->getDefaultToolChain().printVerboseInfo(OS);
262 if (is_style_windows(llvm::sys::path::Style::native))
263 std::replace(S.begin(), S.end(), '\\', '/');
264 EXPECT_EQ("Found candidate GCC installation: "
265 "/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0\n"
266 "Selected GCC installation: "
267 "/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0\n"
268 "Candidate multilib: .;@m64\n"
269 "Candidate multilib: 32;@m32\n"
270 "Selected multilib: .;@m64\n",
275 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
276 Driver TheDriver("/bin/clang", "sparc-sun-solaris2.11", Diags,
277 "clang LLVM compiler", InMemoryFileSystem);
278 std::unique_ptr<Compilation> C(
279 TheDriver.BuildCompilation({"-v", "--gcc-toolchain=", "--sysroot="}));
280 ASSERT_TRUE(C);
281 std::string S;
283 llvm::raw_string_ostream OS(S);
284 C->getDefaultToolChain().printVerboseInfo(OS);
286 if (is_style_windows(llvm::sys::path::Style::native))
287 std::replace(S.begin(), S.end(), '\\', '/');
288 EXPECT_EQ("Found candidate GCC installation: "
289 "/usr/gcc/11/lib/gcc/sparcv9-sun-solaris2.11/11.4.0\n"
290 "Selected GCC installation: "
291 "/usr/gcc/11/lib/gcc/sparcv9-sun-solaris2.11/11.4.0\n"
292 "Candidate multilib: .;@m64\n"
293 "Candidate multilib: sparcv8plus;@m32\n"
294 "Selected multilib: sparcv8plus;@m32\n",
298 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
299 Driver TheDriver("/bin/clang", "sparcv9-sun-solaris2.11", Diags,
300 "clang LLVM compiler", InMemoryFileSystem);
301 std::unique_ptr<Compilation> C(
302 TheDriver.BuildCompilation({"-v", "--gcc-toolchain=", "--sysroot="}));
303 ASSERT_TRUE(C);
304 std::string S;
306 llvm::raw_string_ostream OS(S);
307 C->getDefaultToolChain().printVerboseInfo(OS);
309 if (is_style_windows(llvm::sys::path::Style::native))
310 std::replace(S.begin(), S.end(), '\\', '/');
311 EXPECT_EQ("Found candidate GCC installation: "
312 "/usr/gcc/11/lib/gcc/sparcv9-sun-solaris2.11/11.4.0\n"
313 "Selected GCC installation: "
314 "/usr/gcc/11/lib/gcc/sparcv9-sun-solaris2.11/11.4.0\n"
315 "Candidate multilib: .;@m64\n"
316 "Candidate multilib: sparcv8plus;@m32\n"
317 "Selected multilib: .;@m64\n",
322 MATCHER_P(jobHasArgs, Substr, "") {
323 const driver::Command &C = arg;
324 std::string Args = "";
325 llvm::ListSeparator Sep(" ");
326 for (const char *Arg : C.getArguments()) {
327 Args += Sep;
328 Args += Arg;
330 if (is_style_windows(llvm::sys::path::Style::native))
331 std::replace(Args.begin(), Args.end(), '\\', '/');
332 if (llvm::StringRef(Args).contains(Substr))
333 return true;
334 *result_listener << "whose args are '" << Args << "'";
335 return false;
338 TEST(ToolChainTest, VFSGnuLibcxxPathNoSysroot) {
339 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
341 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
342 struct TestDiagnosticConsumer : public DiagnosticConsumer {};
343 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
344 new llvm::vfs::InMemoryFileSystem);
346 const char *EmptyFiles[] = {
347 "foo.cpp",
348 "/bin/clang",
349 "/usr/include/c++/v1/cstdio",
352 for (const char *Path : EmptyFiles)
353 InMemoryFileSystem->addFile(Path, 0,
354 llvm::MemoryBuffer::getMemBuffer("\n"));
357 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
358 Driver TheDriver("/bin/clang", "x86_64-unknown-linux-gnu", Diags,
359 "clang LLVM compiler", InMemoryFileSystem);
360 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
361 {"/bin/clang", "-fsyntax-only", "-stdlib=libc++",
362 "--sysroot=", "foo.cpp"}));
363 ASSERT_TRUE(C);
364 EXPECT_THAT(C->getJobs(), testing::ElementsAre(jobHasArgs(
365 "-internal-isystem /usr/include/c++/v1")));
369 TEST(ToolChainTest, DefaultDriverMode) {
370 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
372 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
373 struct TestDiagnosticConsumer : public DiagnosticConsumer {};
374 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
375 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
376 new llvm::vfs::InMemoryFileSystem);
378 Driver CCDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
379 "clang LLVM compiler", InMemoryFileSystem);
380 CCDriver.setCheckInputsExist(false);
381 Driver CXXDriver("/home/test/bin/clang++", "arm-linux-gnueabi", Diags,
382 "clang LLVM compiler", InMemoryFileSystem);
383 CXXDriver.setCheckInputsExist(false);
384 Driver CLDriver("/home/test/bin/clang-cl", "arm-linux-gnueabi", Diags,
385 "clang LLVM compiler", InMemoryFileSystem);
386 CLDriver.setCheckInputsExist(false);
388 std::unique_ptr<Compilation> CC(CCDriver.BuildCompilation(
389 { "/home/test/bin/clang", "foo.cpp"}));
390 std::unique_ptr<Compilation> CXX(CXXDriver.BuildCompilation(
391 { "/home/test/bin/clang++", "foo.cpp"}));
392 std::unique_ptr<Compilation> CL(CLDriver.BuildCompilation(
393 { "/home/test/bin/clang-cl", "foo.cpp"}));
395 EXPECT_TRUE(CC);
396 EXPECT_TRUE(CXX);
397 EXPECT_TRUE(CL);
398 EXPECT_TRUE(CCDriver.CCCIsCC());
399 EXPECT_TRUE(CXXDriver.CCCIsCXX());
400 EXPECT_TRUE(CLDriver.IsCLMode());
402 TEST(ToolChainTest, InvalidArgument) {
403 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
404 struct TestDiagnosticConsumer : public DiagnosticConsumer {};
405 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
406 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
407 Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags);
408 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
409 {"-fsyntax-only", "-fan-unknown-option", "foo.cpp"}));
410 EXPECT_TRUE(C);
411 EXPECT_TRUE(C->containsError());
414 TEST(ToolChainTest, ParsedClangName) {
415 ParsedClangName Empty;
416 EXPECT_TRUE(Empty.TargetPrefix.empty());
417 EXPECT_TRUE(Empty.ModeSuffix.empty());
418 EXPECT_TRUE(Empty.DriverMode == nullptr);
419 EXPECT_FALSE(Empty.TargetIsValid);
421 ParsedClangName DriverOnly("clang", nullptr);
422 EXPECT_TRUE(DriverOnly.TargetPrefix.empty());
423 EXPECT_TRUE(DriverOnly.ModeSuffix == "clang");
424 EXPECT_TRUE(DriverOnly.DriverMode == nullptr);
425 EXPECT_FALSE(DriverOnly.TargetIsValid);
427 ParsedClangName DriverOnly2("clang++", "--driver-mode=g++");
428 EXPECT_TRUE(DriverOnly2.TargetPrefix.empty());
429 EXPECT_TRUE(DriverOnly2.ModeSuffix == "clang++");
430 EXPECT_STREQ(DriverOnly2.DriverMode, "--driver-mode=g++");
431 EXPECT_FALSE(DriverOnly2.TargetIsValid);
433 ParsedClangName TargetAndMode("i386", "clang-g++", "--driver-mode=g++", true);
434 EXPECT_TRUE(TargetAndMode.TargetPrefix == "i386");
435 EXPECT_TRUE(TargetAndMode.ModeSuffix == "clang-g++");
436 EXPECT_STREQ(TargetAndMode.DriverMode, "--driver-mode=g++");
437 EXPECT_TRUE(TargetAndMode.TargetIsValid);
440 TEST(ToolChainTest, GetTargetAndMode) {
441 llvm::InitializeAllTargets();
442 std::string IgnoredError;
443 if (!llvm::TargetRegistry::lookupTarget("x86_64", IgnoredError))
444 GTEST_SKIP();
446 ParsedClangName Res = ToolChain::getTargetAndModeFromProgramName("clang");
447 EXPECT_TRUE(Res.TargetPrefix.empty());
448 EXPECT_TRUE(Res.ModeSuffix == "clang");
449 EXPECT_TRUE(Res.DriverMode == nullptr);
450 EXPECT_FALSE(Res.TargetIsValid);
452 Res = ToolChain::getTargetAndModeFromProgramName("clang++");
453 EXPECT_TRUE(Res.TargetPrefix.empty());
454 EXPECT_TRUE(Res.ModeSuffix == "clang++");
455 EXPECT_STREQ(Res.DriverMode, "--driver-mode=g++");
456 EXPECT_FALSE(Res.TargetIsValid);
458 Res = ToolChain::getTargetAndModeFromProgramName("clang++6.0");
459 EXPECT_TRUE(Res.TargetPrefix.empty());
460 EXPECT_TRUE(Res.ModeSuffix == "clang++");
461 EXPECT_STREQ(Res.DriverMode, "--driver-mode=g++");
462 EXPECT_FALSE(Res.TargetIsValid);
464 Res = ToolChain::getTargetAndModeFromProgramName("clang++-release");
465 EXPECT_TRUE(Res.TargetPrefix.empty());
466 EXPECT_TRUE(Res.ModeSuffix == "clang++");
467 EXPECT_STREQ(Res.DriverMode, "--driver-mode=g++");
468 EXPECT_FALSE(Res.TargetIsValid);
470 Res = ToolChain::getTargetAndModeFromProgramName("x86_64-clang++");
471 EXPECT_TRUE(Res.TargetPrefix == "x86_64");
472 EXPECT_TRUE(Res.ModeSuffix == "clang++");
473 EXPECT_STREQ(Res.DriverMode, "--driver-mode=g++");
474 EXPECT_TRUE(Res.TargetIsValid);
476 Res = ToolChain::getTargetAndModeFromProgramName(
477 "x86_64-linux-gnu-clang-c++");
478 EXPECT_TRUE(Res.TargetPrefix == "x86_64-linux-gnu");
479 EXPECT_TRUE(Res.ModeSuffix == "clang-c++");
480 EXPECT_STREQ(Res.DriverMode, "--driver-mode=g++");
481 EXPECT_TRUE(Res.TargetIsValid);
483 Res = ToolChain::getTargetAndModeFromProgramName(
484 "x86_64-linux-gnu-clang-c++-tot");
485 EXPECT_TRUE(Res.TargetPrefix == "x86_64-linux-gnu");
486 EXPECT_TRUE(Res.ModeSuffix == "clang-c++");
487 EXPECT_STREQ(Res.DriverMode, "--driver-mode=g++");
488 EXPECT_TRUE(Res.TargetIsValid);
490 Res = ToolChain::getTargetAndModeFromProgramName("qqq");
491 EXPECT_TRUE(Res.TargetPrefix.empty());
492 EXPECT_TRUE(Res.ModeSuffix.empty());
493 EXPECT_TRUE(Res.DriverMode == nullptr);
494 EXPECT_FALSE(Res.TargetIsValid);
496 Res = ToolChain::getTargetAndModeFromProgramName("x86_64-qqq");
497 EXPECT_TRUE(Res.TargetPrefix.empty());
498 EXPECT_TRUE(Res.ModeSuffix.empty());
499 EXPECT_TRUE(Res.DriverMode == nullptr);
500 EXPECT_FALSE(Res.TargetIsValid);
502 Res = ToolChain::getTargetAndModeFromProgramName("qqq-clang-cl");
503 EXPECT_TRUE(Res.TargetPrefix == "qqq");
504 EXPECT_TRUE(Res.ModeSuffix == "clang-cl");
505 EXPECT_STREQ(Res.DriverMode, "--driver-mode=cl");
506 EXPECT_FALSE(Res.TargetIsValid);
508 Res = ToolChain::getTargetAndModeFromProgramName("clang-dxc");
509 EXPECT_TRUE(Res.TargetPrefix.empty());
510 EXPECT_TRUE(Res.ModeSuffix == "clang-dxc");
511 EXPECT_STREQ(Res.DriverMode, "--driver-mode=dxc");
512 EXPECT_FALSE(Res.TargetIsValid);
515 TEST(ToolChainTest, CommandOutput) {
516 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
518 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
519 struct TestDiagnosticConsumer : public DiagnosticConsumer {};
520 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
521 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
522 new llvm::vfs::InMemoryFileSystem);
524 Driver CCDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
525 "clang LLVM compiler", InMemoryFileSystem);
526 CCDriver.setCheckInputsExist(false);
527 std::unique_ptr<Compilation> CC(
528 CCDriver.BuildCompilation({"/home/test/bin/clang", "foo.cpp"}));
529 const JobList &Jobs = CC->getJobs();
531 const auto &CmdCompile = Jobs.getJobs().front();
532 const auto &InFile = CmdCompile->getInputInfos().front().getFilename();
533 EXPECT_STREQ(InFile, "foo.cpp");
534 auto ObjFile = CmdCompile->getOutputFilenames().front();
535 EXPECT_TRUE(StringRef(ObjFile).ends_with(".o"));
537 const auto &CmdLink = Jobs.getJobs().back();
538 const auto LinkInFile = CmdLink->getInputInfos().front().getFilename();
539 EXPECT_EQ(ObjFile, LinkInFile);
540 auto ExeFile = CmdLink->getOutputFilenames().front();
541 EXPECT_EQ("a.out", ExeFile);
544 TEST(ToolChainTest, PostCallback) {
545 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
546 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
547 struct TestDiagnosticConsumer : public DiagnosticConsumer {};
548 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
549 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
550 new llvm::vfs::InMemoryFileSystem);
552 // The executable path must not exist.
553 Driver CCDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
554 "clang LLVM compiler", InMemoryFileSystem);
555 CCDriver.setCheckInputsExist(false);
556 std::unique_ptr<Compilation> CC(
557 CCDriver.BuildCompilation({"/home/test/bin/clang", "foo.cpp"}));
558 bool CallbackHasCalled = false;
559 CC->setPostCallback(
560 [&](const Command &C, int Ret) { CallbackHasCalled = true; });
561 const JobList &Jobs = CC->getJobs();
562 auto &CmdCompile = Jobs.getJobs().front();
563 const Command *FailingCmd = nullptr;
564 CC->ExecuteCommand(*CmdCompile, FailingCmd);
565 EXPECT_TRUE(CallbackHasCalled);
568 TEST(CompilerInvocation, SplitSwarfSingleCrash) {
569 static constexpr const char *Args[] = {
570 "clang", "--target=arm-linux-gnueabi",
571 "-gdwarf-4", "-gsplit-dwarf=single",
572 "-c", "foo.cpp"};
573 CreateInvocationOptions CIOpts;
574 std::unique_ptr<CompilerInvocation> CI = createInvocation(Args, CIOpts);
575 EXPECT_TRUE(CI); // no-crash
578 TEST(ToolChainTest, UEFICallingConventionTest) {
579 clang::CompilerInstance compiler;
580 compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());
582 std::string TrStr = "x86_64-unknown-uefi";
583 llvm::Triple Tr(TrStr);
584 Tr.setOS(llvm::Triple::OSType::UEFI);
585 Tr.setVendor(llvm::Triple::VendorType::UnknownVendor);
586 Tr.setEnvironment(llvm::Triple::EnvironmentType::UnknownEnvironment);
587 Tr.setArch(llvm::Triple::ArchType::x86_64);
589 compiler.getTargetOpts().Triple = Tr.getTriple();
590 compiler.setTarget(clang::TargetInfo::CreateTargetInfo(
591 compiler.getDiagnostics(),
592 std::make_shared<clang::TargetOptions>(compiler.getTargetOpts())));
594 EXPECT_EQ(compiler.getTarget().getCallingConvKind(true),
595 TargetInfo::CallingConvKind::CCK_MicrosoftWin64);
598 TEST(GetDriverMode, PrefersLastDriverMode) {
599 static constexpr const char *Args[] = {"clang-cl", "--driver-mode=foo",
600 "--driver-mode=bar", "foo.cpp"};
601 EXPECT_EQ(getDriverMode(Args[0], llvm::ArrayRef(Args).slice(1)), "bar");
604 struct SimpleDiagnosticConsumer : public DiagnosticConsumer {
605 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
606 const Diagnostic &Info) override {
607 if (DiagLevel == DiagnosticsEngine::Level::Error) {
608 Errors.emplace_back();
609 Info.FormatDiagnostic(Errors.back());
610 } else {
611 Msgs.emplace_back();
612 Info.FormatDiagnostic(Msgs.back());
615 void clear() override {
616 Msgs.clear();
617 Errors.clear();
618 DiagnosticConsumer::clear();
620 std::vector<SmallString<32>> Msgs;
621 std::vector<SmallString<32>> Errors;
624 TEST(ToolChainTest, ConfigFileSearch) {
625 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
626 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
627 struct TestDiagnosticConsumer : public DiagnosticConsumer {};
628 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
629 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS(
630 new llvm::vfs::InMemoryFileSystem);
632 #ifdef _WIN32
633 const char *TestRoot = "C:\\";
634 #else
635 const char *TestRoot = "/";
636 #endif
637 FS->setCurrentWorkingDirectory(TestRoot);
639 FS->addFile(
640 "/opt/sdk/root.cfg", 0,
641 llvm::MemoryBuffer::getMemBuffer("--sysroot=/opt/sdk/platform0\n"));
642 FS->addFile(
643 "/home/test/sdk/root.cfg", 0,
644 llvm::MemoryBuffer::getMemBuffer("--sysroot=/opt/sdk/platform1\n"));
645 FS->addFile(
646 "/home/test/bin/root.cfg", 0,
647 llvm::MemoryBuffer::getMemBuffer("--sysroot=/opt/sdk/platform2\n"));
650 Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
651 "clang LLVM compiler", FS);
652 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
653 {"/home/test/bin/clang", "--config", "root.cfg",
654 "--config-system-dir=/opt/sdk", "--config-user-dir=/home/test/sdk"}));
655 ASSERT_TRUE(C);
656 ASSERT_FALSE(C->containsError());
657 EXPECT_EQ("/opt/sdk/platform1", TheDriver.SysRoot);
660 Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
661 "clang LLVM compiler", FS);
662 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
663 {"/home/test/bin/clang", "--config", "root.cfg",
664 "--config-system-dir=/opt/sdk", "--config-user-dir="}));
665 ASSERT_TRUE(C);
666 ASSERT_FALSE(C->containsError());
667 EXPECT_EQ("/opt/sdk/platform0", TheDriver.SysRoot);
670 Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
671 "clang LLVM compiler", FS);
672 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
673 {"/home/test/bin/clang", "--config", "root.cfg",
674 "--config-system-dir=", "--config-user-dir="}));
675 ASSERT_TRUE(C);
676 ASSERT_FALSE(C->containsError());
677 EXPECT_EQ("/opt/sdk/platform2", TheDriver.SysRoot);
681 struct FileSystemWithError : public llvm::vfs::FileSystem {
682 llvm::ErrorOr<llvm::vfs::Status> status(const Twine &Path) override {
683 return std::make_error_code(std::errc::no_such_file_or_directory);
685 llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
686 openFileForRead(const Twine &Path) override {
687 return std::make_error_code(std::errc::permission_denied);
689 llvm::vfs::directory_iterator dir_begin(const Twine &Dir,
690 std::error_code &EC) override {
691 return llvm::vfs::directory_iterator();
693 std::error_code setCurrentWorkingDirectory(const Twine &Path) override {
694 return std::make_error_code(std::errc::permission_denied);
696 llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
697 return std::make_error_code(std::errc::permission_denied);
701 TEST(ToolChainTest, ConfigFileError) {
702 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
703 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
704 std::unique_ptr<SimpleDiagnosticConsumer> DiagConsumer(
705 new SimpleDiagnosticConsumer());
706 DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer.get(), false);
707 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS(new FileSystemWithError);
709 Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
710 "clang LLVM compiler", FS);
711 std::unique_ptr<Compilation> C(
712 TheDriver.BuildCompilation({"/home/test/bin/clang", "--no-default-config",
713 "--config", "./root.cfg", "--version"}));
714 ASSERT_TRUE(C);
715 ASSERT_TRUE(C->containsError());
716 EXPECT_EQ(1U, Diags.getNumErrors());
717 EXPECT_STREQ("configuration file './root.cfg' cannot be opened: cannot get "
718 "absolute path",
719 DiagConsumer->Errors[0].c_str());
722 TEST(ToolChainTest, BadConfigFile) {
723 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
724 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
725 std::unique_ptr<SimpleDiagnosticConsumer> DiagConsumer(
726 new SimpleDiagnosticConsumer());
727 DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer.get(), false);
728 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS(
729 new llvm::vfs::InMemoryFileSystem);
731 #ifdef _WIN32
732 const char *TestRoot = "C:\\";
733 #define FILENAME "C:/opt/root.cfg"
734 #define DIRNAME "C:/opt"
735 #else
736 const char *TestRoot = "/";
737 #define FILENAME "/opt/root.cfg"
738 #define DIRNAME "/opt"
739 #endif
740 // UTF-16 string must be aligned on 2-byte boundary. Strings and char arrays
741 // do not provide necessary alignment, so copy constant string into properly
742 // allocated memory in heap.
743 llvm::BumpPtrAllocator Alloc;
744 char *StrBuff = (char *)Alloc.Allocate(16, 4);
745 std::memset(StrBuff, 0, 16);
746 std::memcpy(StrBuff, "\xFF\xFE\x00\xD8\x00\x00", 6);
747 StringRef BadUTF(StrBuff, 6);
748 FS->setCurrentWorkingDirectory(TestRoot);
749 FS->addFile("/opt/root.cfg", 0, llvm::MemoryBuffer::getMemBuffer(BadUTF));
750 FS->addFile("/home/user/test.cfg", 0,
751 llvm::MemoryBuffer::getMemBuffer("@file.rsp"));
754 Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
755 "clang LLVM compiler", FS);
756 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
757 {"/home/test/bin/clang", "--config", "/opt/root.cfg", "--version"}));
758 ASSERT_TRUE(C);
759 ASSERT_TRUE(C->containsError());
760 EXPECT_EQ(1U, DiagConsumer->Errors.size());
761 EXPECT_STREQ("cannot read configuration file '" FILENAME
762 "': Could not convert UTF16 to UTF8",
763 DiagConsumer->Errors[0].c_str());
765 DiagConsumer->clear();
767 Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
768 "clang LLVM compiler", FS);
769 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
770 {"/home/test/bin/clang", "--config", "/opt", "--version"}));
771 ASSERT_TRUE(C);
772 ASSERT_TRUE(C->containsError());
773 EXPECT_EQ(1U, DiagConsumer->Errors.size());
774 EXPECT_STREQ("configuration file '" DIRNAME
775 "' cannot be opened: not a regular file",
776 DiagConsumer->Errors[0].c_str());
778 DiagConsumer->clear();
780 Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
781 "clang LLVM compiler", FS);
782 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
783 {"/home/test/bin/clang", "--config", "root",
784 "--config-system-dir=", "--config-user-dir=", "--version"}));
785 ASSERT_TRUE(C);
786 ASSERT_TRUE(C->containsError());
787 EXPECT_EQ(1U, DiagConsumer->Errors.size());
788 EXPECT_STREQ("configuration file 'root' cannot be found",
789 DiagConsumer->Errors[0].c_str());
792 #undef FILENAME
793 #undef DIRNAME
796 TEST(ToolChainTest, ConfigInexistentInclude) {
797 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
798 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
799 std::unique_ptr<SimpleDiagnosticConsumer> DiagConsumer(
800 new SimpleDiagnosticConsumer());
801 DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer.get(), false);
802 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS(
803 new llvm::vfs::InMemoryFileSystem);
805 #ifdef _WIN32
806 const char *TestRoot = "C:\\";
807 #define USERCONFIG "C:\\home\\user\\test.cfg"
808 #define UNEXISTENT "C:\\home\\user\\file.rsp"
809 #else
810 const char *TestRoot = "/";
811 #define USERCONFIG "/home/user/test.cfg"
812 #define UNEXISTENT "/home/user/file.rsp"
813 #endif
814 FS->setCurrentWorkingDirectory(TestRoot);
815 FS->addFile("/home/user/test.cfg", 0,
816 llvm::MemoryBuffer::getMemBuffer("@file.rsp"));
819 Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
820 "clang LLVM compiler", FS);
821 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
822 {"/home/test/bin/clang", "--config", "test.cfg",
823 "--config-system-dir=", "--config-user-dir=/home/user", "--version"}));
824 ASSERT_TRUE(C);
825 ASSERT_TRUE(C->containsError());
826 EXPECT_EQ(1U, DiagConsumer->Errors.size());
827 EXPECT_STRCASEEQ("cannot read configuration file '" USERCONFIG
828 "': cannot not open file '" UNEXISTENT
829 "': no such file or directory",
830 DiagConsumer->Errors[0].c_str());
833 #undef USERCONFIG
834 #undef UNEXISTENT
837 TEST(ToolChainTest, ConfigRecursiveInclude) {
838 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
839 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
840 std::unique_ptr<SimpleDiagnosticConsumer> DiagConsumer(
841 new SimpleDiagnosticConsumer());
842 DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer.get(), false);
843 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS(
844 new llvm::vfs::InMemoryFileSystem);
846 #ifdef _WIN32
847 const char *TestRoot = "C:\\";
848 #define USERCONFIG "C:\\home\\user\\test.cfg"
849 #define INCLUDED1 "C:\\home\\user\\file1.cfg"
850 #else
851 const char *TestRoot = "/";
852 #define USERCONFIG "/home/user/test.cfg"
853 #define INCLUDED1 "/home/user/file1.cfg"
854 #endif
855 FS->setCurrentWorkingDirectory(TestRoot);
856 FS->addFile("/home/user/test.cfg", 0,
857 llvm::MemoryBuffer::getMemBuffer("@file1.cfg"));
858 FS->addFile("/home/user/file1.cfg", 0,
859 llvm::MemoryBuffer::getMemBuffer("@file2.cfg"));
860 FS->addFile("/home/user/file2.cfg", 0,
861 llvm::MemoryBuffer::getMemBuffer("@file3.cfg"));
862 FS->addFile("/home/user/file3.cfg", 0,
863 llvm::MemoryBuffer::getMemBuffer("@file1.cfg"));
866 Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
867 "clang LLVM compiler", FS);
868 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
869 {"/home/test/bin/clang", "--config", "test.cfg",
870 "--config-system-dir=", "--config-user-dir=/home/user", "--version"}));
871 ASSERT_TRUE(C);
872 ASSERT_TRUE(C->containsError());
873 EXPECT_EQ(1U, DiagConsumer->Errors.size());
874 EXPECT_STREQ("cannot read configuration file '" USERCONFIG
875 "': recursive expansion of: '" INCLUDED1 "'",
876 DiagConsumer->Errors[0].c_str());
879 #undef USERCONFIG
880 #undef INCLUDED1
883 TEST(ToolChainTest, NestedConfigFile) {
884 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
885 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
886 struct TestDiagnosticConsumer : public DiagnosticConsumer {};
887 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
888 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS(
889 new llvm::vfs::InMemoryFileSystem);
891 #ifdef _WIN32
892 const char *TestRoot = "C:\\";
893 #else
894 const char *TestRoot = "/";
895 #endif
896 FS->setCurrentWorkingDirectory(TestRoot);
898 FS->addFile("/opt/sdk/root.cfg", 0,
899 llvm::MemoryBuffer::getMemBuffer("--config=platform.cfg\n"));
900 FS->addFile("/opt/sdk/platform.cfg", 0,
901 llvm::MemoryBuffer::getMemBuffer("--sysroot=/platform-sys\n"));
902 FS->addFile("/home/test/bin/platform.cfg", 0,
903 llvm::MemoryBuffer::getMemBuffer("--sysroot=/platform-bin\n"));
905 SmallString<128> ClangExecutable("/home/test/bin/clang");
906 FS->makeAbsolute(ClangExecutable);
908 // User file is absent - use system definitions.
910 Driver TheDriver(ClangExecutable, "arm-linux-gnueabi", Diags,
911 "clang LLVM compiler", FS);
912 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
913 {"/home/test/bin/clang", "--config", "root.cfg",
914 "--config-system-dir=/opt/sdk", "--config-user-dir=/home/test/sdk"}));
915 ASSERT_TRUE(C);
916 ASSERT_FALSE(C->containsError());
917 EXPECT_EQ("/platform-sys", TheDriver.SysRoot);
920 // User file overrides system definitions.
921 FS->addFile("/home/test/sdk/platform.cfg", 0,
922 llvm::MemoryBuffer::getMemBuffer("--sysroot=/platform-user\n"));
924 Driver TheDriver(ClangExecutable, "arm-linux-gnueabi", Diags,
925 "clang LLVM compiler", FS);
926 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
927 {"/home/test/bin/clang", "--config", "root.cfg",
928 "--config-system-dir=/opt/sdk", "--config-user-dir=/home/test/sdk"}));
929 ASSERT_TRUE(C);
930 ASSERT_FALSE(C->containsError());
931 EXPECT_EQ("/platform-user", TheDriver.SysRoot);
935 } // end anonymous namespace.