1 //===-- CompilerTests.cpp -------------------------------------------------===// 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 #include "Compiler.h" 10 #include "TestTU.h" 11 #include "clang/Frontend/DependencyOutputOptions.h" 12 #include "clang/Frontend/FrontendOptions.h" 13 #include "clang/Lex/PreprocessorOptions.h" 14 #include "gmock/gmock.h" 15 #include "gtest/gtest.h" 16 17 namespace clang { 18 namespace clangd { 19 namespace { 20 21 using testing::IsEmpty; 22 23 TEST(BuildCompilerInvocation, DropsPCH) { 24 MockFS FS; 25 IgnoreDiagnostics Diags; 26 TestTU TU; 27 TU.AdditionalFiles["test.h.pch"] = ""; 28 29 TU.ExtraArgs = {"-include-pch", "test.h.pch"}; 30 EXPECT_THAT(buildCompilerInvocation(TU.inputs(FS), Diags) 31 ->getPreprocessorOpts() 32 .ImplicitPCHInclude, 33 IsEmpty()); 34 35 // Transparent include translation 36 TU.ExtraArgs = {"-include", "test.h"}; 37 EXPECT_THAT(buildCompilerInvocation(TU.inputs(FS), Diags) 38 ->getPreprocessorOpts() 39 .ImplicitPCHInclude, 40 IsEmpty()); 41 42 // CL mode parsing. 43 TU.AdditionalFiles["test.pch"] = ""; 44 TU.ExtraArgs = {"--driver-mode=cl"}; 45 TU.ExtraArgs.push_back("/Yutest.h"); 46 EXPECT_THAT(buildCompilerInvocation(TU.inputs(FS), Diags) 47 ->getPreprocessorOpts() 48 .ImplicitPCHInclude, 49 IsEmpty()); 50 EXPECT_THAT(buildCompilerInvocation(TU.inputs(FS), Diags) 51 ->getPreprocessorOpts() 52 .PCHThroughHeader, 53 IsEmpty()); 54 } 55 56 TEST(BuildCompilerInvocation, PragmaDebugCrash) { 57 TestTU TU = TestTU::withCode("#pragma clang __debug parser_crash"); 58 TU.build(); // no-crash 59 } 60 61 TEST(BuildCompilerInvocation, DropsShowIncludes) { 62 MockFS FS; 63 IgnoreDiagnostics Diags; 64 TestTU TU; 65 66 TU.ExtraArgs = {"-Xclang", "--show-includes"}; 67 EXPECT_THAT(buildCompilerInvocation(TU.inputs(FS), Diags) 68 ->getDependencyOutputOpts() 69 .ShowIncludesDest, 70 ShowIncludesDestination::None); 71 72 TU.ExtraArgs = {"/showIncludes", "--driver-mode=cl"}; 73 EXPECT_THAT(buildCompilerInvocation(TU.inputs(FS), Diags) 74 ->getDependencyOutputOpts() 75 .ShowIncludesDest, 76 ShowIncludesDestination::None); 77 78 TU.ExtraArgs = {"/showIncludes:user", "--driver-mode=cl"}; 79 EXPECT_THAT(buildCompilerInvocation(TU.inputs(FS), Diags) 80 ->getDependencyOutputOpts() 81 .ShowIncludesDest, 82 ShowIncludesDestination::None); 83 } 84 85 TEST(BuildCompilerInvocation, DropsPlugins) { 86 MockFS FS; 87 IgnoreDiagnostics Diags; 88 TestTU TU; 89 90 TU.ExtraArgs = {"-Xclang", "-load", 91 "-Xclang", "plugins.so", 92 "-Xclang", "-plugin", 93 "-Xclang", "my_plugin", 94 "-Xclang", "-plugin-arg-my_plugin", 95 "-Xclang", "foo=bar", 96 "-Xclang", "-add-plugin", 97 "-Xclang", "my_plugin2"}; 98 auto Opts = buildCompilerInvocation(TU.inputs(FS), Diags)->getFrontendOpts(); 99 EXPECT_THAT(Opts.Plugins, IsEmpty()); 100 EXPECT_THAT(Opts.PluginArgs, IsEmpty()); 101 EXPECT_THAT(Opts.AddPluginActions, IsEmpty()); 102 EXPECT_EQ(Opts.ProgramAction, frontend::ActionKind::ParseSyntaxOnly); 103 EXPECT_TRUE(Opts.ActionName.empty()); 104 } 105 106 TEST(BuildCompilerInvocation, EmptyArgs) { 107 MockFS FS; 108 IgnoreDiagnostics Diags; 109 TestTU TU; 110 auto Inputs = TU.inputs(FS); 111 Inputs.CompileCommand.CommandLine.clear(); 112 113 // No crash. 114 EXPECT_EQ(buildCompilerInvocation(Inputs, Diags), nullptr); 115 } 116 } // namespace 117 } // namespace clangd 118 } // namespace clang 119