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. 10 // 11 //===----------------------------------------------------------------------===// 12 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/Driver/Compilation.h" 18 #include "clang/Driver/Driver.h" 19 #include "llvm/ADT/ArrayRef.h" 20 #include "llvm/MC/TargetRegistry.h" 21 #include "llvm/Support/TargetSelect.h" 22 #include "llvm/Support/VirtualFileSystem.h" 23 #include "llvm/Support/raw_ostream.h" 24 #include "gtest/gtest.h" 25 using namespace clang; 26 using namespace clang::driver; 27 28 namespace { 29 30 TEST(ToolChainTest, VFSGCCInstallation) { 31 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 32 33 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 34 struct TestDiagnosticConsumer : public DiagnosticConsumer {}; 35 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem( 36 new llvm::vfs::InMemoryFileSystem); 37 38 const char *EmptyFiles[] = { 39 "foo.cpp", 40 "/bin/clang", 41 "/usr/lib/gcc/arm-linux-gnueabi/4.6.1/crtbegin.o", 42 "/usr/lib/gcc/arm-linux-gnueabi/4.6.1/crtend.o", 43 "/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtbegin.o", 44 "/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtend.o", 45 "/usr/lib/arm-linux-gnueabi/crt1.o", 46 "/usr/lib/arm-linux-gnueabi/crti.o", 47 "/usr/lib/arm-linux-gnueabi/crtn.o", 48 "/usr/lib/arm-linux-gnueabihf/crt1.o", 49 "/usr/lib/arm-linux-gnueabihf/crti.o", 50 "/usr/lib/arm-linux-gnueabihf/crtn.o", 51 "/usr/include/arm-linux-gnueabi/.keep", 52 "/usr/include/arm-linux-gnueabihf/.keep", 53 "/lib/arm-linux-gnueabi/.keep", 54 "/lib/arm-linux-gnueabihf/.keep", 55 56 "/sysroot/usr/lib/gcc/arm-linux-gnueabi/4.5.1/crtbegin.o", 57 "/sysroot/usr/lib/gcc/arm-linux-gnueabi/4.5.1/crtend.o", 58 "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3/crtbegin.o", 59 "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3/crtend.o", 60 "/sysroot/usr/lib/arm-linux-gnueabi/crt1.o", 61 "/sysroot/usr/lib/arm-linux-gnueabi/crti.o", 62 "/sysroot/usr/lib/arm-linux-gnueabi/crtn.o", 63 "/sysroot/usr/lib/arm-linux-gnueabihf/crt1.o", 64 "/sysroot/usr/lib/arm-linux-gnueabihf/crti.o", 65 "/sysroot/usr/lib/arm-linux-gnueabihf/crtn.o", 66 "/sysroot/usr/include/arm-linux-gnueabi/.keep", 67 "/sysroot/usr/include/arm-linux-gnueabihf/.keep", 68 "/sysroot/lib/arm-linux-gnueabi/.keep", 69 "/sysroot/lib/arm-linux-gnueabihf/.keep", 70 }; 71 72 for (const char *Path : EmptyFiles) 73 InMemoryFileSystem->addFile(Path, 0, 74 llvm::MemoryBuffer::getMemBuffer("\n")); 75 76 { 77 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); 78 Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags, 79 "clang LLVM compiler", InMemoryFileSystem); 80 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation( 81 {"-fsyntax-only", "--gcc-toolchain=", "--sysroot=", "foo.cpp"})); 82 ASSERT_TRUE(C); 83 std::string S; 84 { 85 llvm::raw_string_ostream OS(S); 86 C->getDefaultToolChain().printVerboseInfo(OS); 87 } 88 if (is_style_windows(llvm::sys::path::Style::native)) 89 std::replace(S.begin(), S.end(), '\\', '/'); 90 EXPECT_EQ( 91 "Found candidate GCC installation: " 92 "/usr/lib/gcc/arm-linux-gnueabihf/4.6.3\n" 93 "Selected GCC installation: /usr/lib/gcc/arm-linux-gnueabihf/4.6.3\n" 94 "Candidate multilib: .;@m32\n" 95 "Selected multilib: .;@m32\n", 96 S); 97 } 98 99 { 100 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); 101 Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags, 102 "clang LLVM compiler", InMemoryFileSystem); 103 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation( 104 {"-fsyntax-only", "--gcc-toolchain=", "--sysroot=/sysroot", 105 "foo.cpp"})); 106 ASSERT_TRUE(C); 107 std::string S; 108 { 109 llvm::raw_string_ostream OS(S); 110 C->getDefaultToolChain().printVerboseInfo(OS); 111 } 112 if (is_style_windows(llvm::sys::path::Style::native)) 113 std::replace(S.begin(), S.end(), '\\', '/'); 114 // Test that 4.5.3 from --sysroot is not overridden by 4.6.3 (larger 115 // version) from /usr. 116 EXPECT_EQ("Found candidate GCC installation: " 117 "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3\n" 118 "Selected GCC installation: " 119 "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3\n" 120 "Candidate multilib: .;@m32\n" 121 "Selected multilib: .;@m32\n", 122 S); 123 } 124 } 125 126 TEST(ToolChainTest, VFSGCCInstallationRelativeDir) { 127 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 128 129 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 130 struct TestDiagnosticConsumer : public DiagnosticConsumer {}; 131 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); 132 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem( 133 new llvm::vfs::InMemoryFileSystem); 134 Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags, 135 "clang LLVM compiler", InMemoryFileSystem); 136 137 const char *EmptyFiles[] = { 138 "foo.cpp", "/home/test/lib/gcc/arm-linux-gnueabi/4.6.1/crtbegin.o", 139 "/home/test/include/arm-linux-gnueabi/.keep"}; 140 141 for (const char *Path : EmptyFiles) 142 InMemoryFileSystem->addFile(Path, 0, 143 llvm::MemoryBuffer::getMemBuffer("\n")); 144 145 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation( 146 {"-fsyntax-only", "--gcc-toolchain=", "foo.cpp"})); 147 EXPECT_TRUE(C); 148 149 std::string S; 150 { 151 llvm::raw_string_ostream OS(S); 152 C->getDefaultToolChain().printVerboseInfo(OS); 153 } 154 if (is_style_windows(llvm::sys::path::Style::native)) 155 std::replace(S.begin(), S.end(), '\\', '/'); 156 EXPECT_EQ("Found candidate GCC installation: " 157 "/home/test/bin/../lib/gcc/arm-linux-gnueabi/4.6.1\n" 158 "Selected GCC installation: " 159 "/home/test/bin/../lib/gcc/arm-linux-gnueabi/4.6.1\n" 160 "Candidate multilib: .;@m32\n" 161 "Selected multilib: .;@m32\n", 162 S); 163 } 164 165 TEST(ToolChainTest, DefaultDriverMode) { 166 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 167 168 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 169 struct TestDiagnosticConsumer : public DiagnosticConsumer {}; 170 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); 171 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem( 172 new llvm::vfs::InMemoryFileSystem); 173 174 Driver CCDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags, 175 "clang LLVM compiler", InMemoryFileSystem); 176 CCDriver.setCheckInputsExist(false); 177 Driver CXXDriver("/home/test/bin/clang++", "arm-linux-gnueabi", Diags, 178 "clang LLVM compiler", InMemoryFileSystem); 179 CXXDriver.setCheckInputsExist(false); 180 Driver CLDriver("/home/test/bin/clang-cl", "arm-linux-gnueabi", Diags, 181 "clang LLVM compiler", InMemoryFileSystem); 182 CLDriver.setCheckInputsExist(false); 183 184 std::unique_ptr<Compilation> CC(CCDriver.BuildCompilation( 185 { "/home/test/bin/clang", "foo.cpp"})); 186 std::unique_ptr<Compilation> CXX(CXXDriver.BuildCompilation( 187 { "/home/test/bin/clang++", "foo.cpp"})); 188 std::unique_ptr<Compilation> CL(CLDriver.BuildCompilation( 189 { "/home/test/bin/clang-cl", "foo.cpp"})); 190 191 EXPECT_TRUE(CC); 192 EXPECT_TRUE(CXX); 193 EXPECT_TRUE(CL); 194 EXPECT_TRUE(CCDriver.CCCIsCC()); 195 EXPECT_TRUE(CXXDriver.CCCIsCXX()); 196 EXPECT_TRUE(CLDriver.IsCLMode()); 197 } 198 TEST(ToolChainTest, InvalidArgument) { 199 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 200 struct TestDiagnosticConsumer : public DiagnosticConsumer {}; 201 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 202 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); 203 Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags); 204 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation( 205 {"-fsyntax-only", "-fan-unknown-option", "foo.cpp"})); 206 EXPECT_TRUE(C); 207 EXPECT_TRUE(C->containsError()); 208 } 209 210 TEST(ToolChainTest, ParsedClangName) { 211 ParsedClangName Empty; 212 EXPECT_TRUE(Empty.TargetPrefix.empty()); 213 EXPECT_TRUE(Empty.ModeSuffix.empty()); 214 EXPECT_TRUE(Empty.DriverMode == nullptr); 215 EXPECT_FALSE(Empty.TargetIsValid); 216 217 ParsedClangName DriverOnly("clang", nullptr); 218 EXPECT_TRUE(DriverOnly.TargetPrefix.empty()); 219 EXPECT_TRUE(DriverOnly.ModeSuffix == "clang"); 220 EXPECT_TRUE(DriverOnly.DriverMode == nullptr); 221 EXPECT_FALSE(DriverOnly.TargetIsValid); 222 223 ParsedClangName DriverOnly2("clang++", "--driver-mode=g++"); 224 EXPECT_TRUE(DriverOnly2.TargetPrefix.empty()); 225 EXPECT_TRUE(DriverOnly2.ModeSuffix == "clang++"); 226 EXPECT_STREQ(DriverOnly2.DriverMode, "--driver-mode=g++"); 227 EXPECT_FALSE(DriverOnly2.TargetIsValid); 228 229 ParsedClangName TargetAndMode("i386", "clang-g++", "--driver-mode=g++", true); 230 EXPECT_TRUE(TargetAndMode.TargetPrefix == "i386"); 231 EXPECT_TRUE(TargetAndMode.ModeSuffix == "clang-g++"); 232 EXPECT_STREQ(TargetAndMode.DriverMode, "--driver-mode=g++"); 233 EXPECT_TRUE(TargetAndMode.TargetIsValid); 234 } 235 236 TEST(ToolChainTest, GetTargetAndMode) { 237 llvm::InitializeAllTargets(); 238 std::string IgnoredError; 239 if (!llvm::TargetRegistry::lookupTarget("x86_64", IgnoredError)) 240 return; 241 242 ParsedClangName Res = ToolChain::getTargetAndModeFromProgramName("clang"); 243 EXPECT_TRUE(Res.TargetPrefix.empty()); 244 EXPECT_TRUE(Res.ModeSuffix == "clang"); 245 EXPECT_TRUE(Res.DriverMode == nullptr); 246 EXPECT_FALSE(Res.TargetIsValid); 247 248 Res = ToolChain::getTargetAndModeFromProgramName("clang++"); 249 EXPECT_TRUE(Res.TargetPrefix.empty()); 250 EXPECT_TRUE(Res.ModeSuffix == "clang++"); 251 EXPECT_STREQ(Res.DriverMode, "--driver-mode=g++"); 252 EXPECT_FALSE(Res.TargetIsValid); 253 254 Res = ToolChain::getTargetAndModeFromProgramName("clang++6.0"); 255 EXPECT_TRUE(Res.TargetPrefix.empty()); 256 EXPECT_TRUE(Res.ModeSuffix == "clang++"); 257 EXPECT_STREQ(Res.DriverMode, "--driver-mode=g++"); 258 EXPECT_FALSE(Res.TargetIsValid); 259 260 Res = ToolChain::getTargetAndModeFromProgramName("clang++-release"); 261 EXPECT_TRUE(Res.TargetPrefix.empty()); 262 EXPECT_TRUE(Res.ModeSuffix == "clang++"); 263 EXPECT_STREQ(Res.DriverMode, "--driver-mode=g++"); 264 EXPECT_FALSE(Res.TargetIsValid); 265 266 Res = ToolChain::getTargetAndModeFromProgramName("x86_64-clang++"); 267 EXPECT_TRUE(Res.TargetPrefix == "x86_64"); 268 EXPECT_TRUE(Res.ModeSuffix == "clang++"); 269 EXPECT_STREQ(Res.DriverMode, "--driver-mode=g++"); 270 EXPECT_TRUE(Res.TargetIsValid); 271 272 Res = ToolChain::getTargetAndModeFromProgramName( 273 "x86_64-linux-gnu-clang-c++"); 274 EXPECT_TRUE(Res.TargetPrefix == "x86_64-linux-gnu"); 275 EXPECT_TRUE(Res.ModeSuffix == "clang-c++"); 276 EXPECT_STREQ(Res.DriverMode, "--driver-mode=g++"); 277 EXPECT_TRUE(Res.TargetIsValid); 278 279 Res = ToolChain::getTargetAndModeFromProgramName( 280 "x86_64-linux-gnu-clang-c++-tot"); 281 EXPECT_TRUE(Res.TargetPrefix == "x86_64-linux-gnu"); 282 EXPECT_TRUE(Res.ModeSuffix == "clang-c++"); 283 EXPECT_STREQ(Res.DriverMode, "--driver-mode=g++"); 284 EXPECT_TRUE(Res.TargetIsValid); 285 286 Res = ToolChain::getTargetAndModeFromProgramName("qqq"); 287 EXPECT_TRUE(Res.TargetPrefix.empty()); 288 EXPECT_TRUE(Res.ModeSuffix.empty()); 289 EXPECT_TRUE(Res.DriverMode == nullptr); 290 EXPECT_FALSE(Res.TargetIsValid); 291 292 Res = ToolChain::getTargetAndModeFromProgramName("x86_64-qqq"); 293 EXPECT_TRUE(Res.TargetPrefix.empty()); 294 EXPECT_TRUE(Res.ModeSuffix.empty()); 295 EXPECT_TRUE(Res.DriverMode == nullptr); 296 EXPECT_FALSE(Res.TargetIsValid); 297 298 Res = ToolChain::getTargetAndModeFromProgramName("qqq-clang-cl"); 299 EXPECT_TRUE(Res.TargetPrefix == "qqq"); 300 EXPECT_TRUE(Res.ModeSuffix == "clang-cl"); 301 EXPECT_STREQ(Res.DriverMode, "--driver-mode=cl"); 302 EXPECT_FALSE(Res.TargetIsValid); 303 304 Res = ToolChain::getTargetAndModeFromProgramName("clang-dxc"); 305 EXPECT_TRUE(Res.TargetPrefix.empty()); 306 EXPECT_TRUE(Res.ModeSuffix == "clang-dxc"); 307 EXPECT_STREQ(Res.DriverMode, "--driver-mode=dxc"); 308 EXPECT_FALSE(Res.TargetIsValid); 309 } 310 311 TEST(ToolChainTest, CommandOutput) { 312 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 313 314 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 315 struct TestDiagnosticConsumer : public DiagnosticConsumer {}; 316 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); 317 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem( 318 new llvm::vfs::InMemoryFileSystem); 319 320 Driver CCDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags, 321 "clang LLVM compiler", InMemoryFileSystem); 322 CCDriver.setCheckInputsExist(false); 323 std::unique_ptr<Compilation> CC( 324 CCDriver.BuildCompilation({"/home/test/bin/clang", "foo.cpp"})); 325 const JobList &Jobs = CC->getJobs(); 326 327 const auto &CmdCompile = Jobs.getJobs().front(); 328 const auto &InFile = CmdCompile->getInputInfos().front().getFilename(); 329 EXPECT_STREQ(InFile, "foo.cpp"); 330 auto ObjFile = CmdCompile->getOutputFilenames().front(); 331 EXPECT_TRUE(StringRef(ObjFile).endswith(".o")); 332 333 const auto &CmdLink = Jobs.getJobs().back(); 334 const auto LinkInFile = CmdLink->getInputInfos().front().getFilename(); 335 EXPECT_EQ(ObjFile, LinkInFile); 336 auto ExeFile = CmdLink->getOutputFilenames().front(); 337 EXPECT_EQ("a.out", ExeFile); 338 } 339 340 TEST(ToolChainTest, PostCallback) { 341 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 342 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 343 struct TestDiagnosticConsumer : public DiagnosticConsumer {}; 344 DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); 345 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem( 346 new llvm::vfs::InMemoryFileSystem); 347 348 // The executable path must not exist. 349 Driver CCDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags, 350 "clang LLVM compiler", InMemoryFileSystem); 351 CCDriver.setCheckInputsExist(false); 352 std::unique_ptr<Compilation> CC( 353 CCDriver.BuildCompilation({"/home/test/bin/clang", "foo.cpp"})); 354 bool CallbackHasCalled = false; 355 CC->setPostCallback( 356 [&](const Command &C, int Ret) { CallbackHasCalled = true; }); 357 const JobList &Jobs = CC->getJobs(); 358 auto &CmdCompile = Jobs.getJobs().front(); 359 const Command *FailingCmd = nullptr; 360 CC->ExecuteCommand(*CmdCompile, FailingCmd); 361 EXPECT_TRUE(CallbackHasCalled); 362 } 363 364 TEST(GetDriverMode, PrefersLastDriverMode) { 365 static constexpr const char *Args[] = {"clang-cl", "--driver-mode=foo", 366 "--driver-mode=bar", "foo.cpp"}; 367 EXPECT_EQ(getDriverMode(Args[0], llvm::makeArrayRef(Args).slice(1)), "bar"); 368 } 369 370 TEST(DxcModeTest, TargetProfileValidation) { 371 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 372 struct SimpleDiagnosticConsumer : public DiagnosticConsumer { 373 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 374 const Diagnostic &Info) override { 375 if (DiagLevel == DiagnosticsEngine::Level::Error) { 376 Errors.emplace_back(); 377 Info.FormatDiagnostic(Errors.back()); 378 Errors.back() += '\0'; 379 } else { 380 Msgs.emplace_back(); 381 Info.FormatDiagnostic(Msgs.back()); 382 Msgs.back() += '\0'; 383 } 384 } 385 void clear() override { 386 Msgs.clear(); 387 Errors.clear(); 388 DiagnosticConsumer::clear(); 389 } 390 std::vector<SmallString<32>> Msgs; 391 std::vector<SmallString<32>> Errors; 392 }; 393 394 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem( 395 new llvm::vfs::InMemoryFileSystem); 396 397 InMemoryFileSystem->addFile("foo.hlsl", 0, 398 llvm::MemoryBuffer::getMemBuffer("\n")); 399 400 auto *DiagConsumer = new SimpleDiagnosticConsumer; 401 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 402 DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer); 403 Driver TheDriver("/bin/clang", "", Diags, "", InMemoryFileSystem); 404 std::unique_ptr<Compilation> C( 405 TheDriver.BuildCompilation({"clang", "--driver-mode=dxc", "foo.hlsl"})); 406 EXPECT_TRUE(C); 407 EXPECT_TRUE(!C->containsError()); 408 409 auto &TC = C->getDefaultToolChain(); 410 bool ContainsError = false; 411 auto Args = TheDriver.ParseArgStrings({"-Tvs_6_0"}, false, ContainsError); 412 EXPECT_FALSE(ContainsError); 413 auto Triple = TC.ComputeEffectiveClangTriple(Args); 414 EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.0-vertex"); 415 EXPECT_EQ(Diags.getNumErrors(), 0u); 416 417 Args = TheDriver.ParseArgStrings({"-Ths_6_1"}, false, ContainsError); 418 EXPECT_FALSE(ContainsError); 419 Triple = TC.ComputeEffectiveClangTriple(Args); 420 EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.1-hull"); 421 EXPECT_EQ(Diags.getNumErrors(), 0u); 422 423 Args = TheDriver.ParseArgStrings({"-Tds_6_2"}, false, ContainsError); 424 EXPECT_FALSE(ContainsError); 425 Triple = TC.ComputeEffectiveClangTriple(Args); 426 EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.2-domain"); 427 EXPECT_EQ(Diags.getNumErrors(), 0u); 428 429 Args = TheDriver.ParseArgStrings({"-Tds_6_2"}, false, ContainsError); 430 EXPECT_FALSE(ContainsError); 431 Triple = TC.ComputeEffectiveClangTriple(Args); 432 EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.2-domain"); 433 EXPECT_EQ(Diags.getNumErrors(), 0u); 434 435 Args = TheDriver.ParseArgStrings({"-Tgs_6_3"}, false, ContainsError); 436 EXPECT_FALSE(ContainsError); 437 Triple = TC.ComputeEffectiveClangTriple(Args); 438 EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.3-geometry"); 439 EXPECT_EQ(Diags.getNumErrors(), 0u); 440 441 Args = TheDriver.ParseArgStrings({"-Tps_6_4"}, false, ContainsError); 442 EXPECT_FALSE(ContainsError); 443 Triple = TC.ComputeEffectiveClangTriple(Args); 444 EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.4-pixel"); 445 EXPECT_EQ(Diags.getNumErrors(), 0u); 446 447 Args = TheDriver.ParseArgStrings({"-Tcs_6_5"}, false, ContainsError); 448 EXPECT_FALSE(ContainsError); 449 Triple = TC.ComputeEffectiveClangTriple(Args); 450 EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.5-compute"); 451 EXPECT_EQ(Diags.getNumErrors(), 0u); 452 453 Args = TheDriver.ParseArgStrings({"-Tms_6_6"}, false, ContainsError); 454 EXPECT_FALSE(ContainsError); 455 Triple = TC.ComputeEffectiveClangTriple(Args); 456 EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.6-mesh"); 457 EXPECT_EQ(Diags.getNumErrors(), 0u); 458 459 Args = TheDriver.ParseArgStrings({"-Tas_6_7"}, false, ContainsError); 460 EXPECT_FALSE(ContainsError); 461 Triple = TC.ComputeEffectiveClangTriple(Args); 462 EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.7-amplification"); 463 EXPECT_EQ(Diags.getNumErrors(), 0u); 464 465 Args = TheDriver.ParseArgStrings({"-Tlib_6_x"}, false, ContainsError); 466 EXPECT_FALSE(ContainsError); 467 Triple = TC.ComputeEffectiveClangTriple(Args); 468 EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.15-library"); 469 EXPECT_EQ(Diags.getNumErrors(), 0u); 470 471 // Invalid tests. 472 Args = TheDriver.ParseArgStrings({"-Tpss_6_1"}, false, ContainsError); 473 EXPECT_FALSE(ContainsError); 474 Triple = TC.ComputeEffectiveClangTriple(Args); 475 EXPECT_STREQ(Triple.c_str(), "unknown-unknown-shadermodel"); 476 EXPECT_EQ(Diags.getNumErrors(), 1u); 477 EXPECT_STREQ(DiagConsumer->Errors.back().data(), "invalid profile : pss_6_1"); 478 Diags.Clear(); 479 DiagConsumer->clear(); 480 481 Args = TheDriver.ParseArgStrings({"-Tps_6_x"}, false, ContainsError); 482 EXPECT_FALSE(ContainsError); 483 Triple = TC.ComputeEffectiveClangTriple(Args); 484 EXPECT_STREQ(Triple.c_str(), "unknown-unknown-shadermodel"); 485 EXPECT_EQ(Diags.getNumErrors(), 2u); 486 EXPECT_STREQ(DiagConsumer->Errors.back().data(), "invalid profile : ps_6_x"); 487 Diags.Clear(); 488 DiagConsumer->clear(); 489 490 Args = TheDriver.ParseArgStrings({"-Tlib_6_1"}, false, ContainsError); 491 EXPECT_FALSE(ContainsError); 492 Triple = TC.ComputeEffectiveClangTriple(Args); 493 EXPECT_STREQ(Triple.c_str(), "unknown-unknown-shadermodel"); 494 EXPECT_EQ(Diags.getNumErrors(), 3u); 495 EXPECT_STREQ(DiagConsumer->Errors.back().data(), "invalid profile : lib_6_1"); 496 Diags.Clear(); 497 DiagConsumer->clear(); 498 499 Args = TheDriver.ParseArgStrings({"-Tfoo"}, false, ContainsError); 500 EXPECT_FALSE(ContainsError); 501 Triple = TC.ComputeEffectiveClangTriple(Args); 502 EXPECT_STREQ(Triple.c_str(), "unknown-unknown-shadermodel"); 503 EXPECT_EQ(Diags.getNumErrors(), 4u); 504 EXPECT_STREQ(DiagConsumer->Errors.back().data(), "invalid profile : foo"); 505 Diags.Clear(); 506 DiagConsumer->clear(); 507 } 508 509 } // end anonymous namespace. 510