/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Tooling/ArgumentsAdjusters.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- ArgumentsAdjusters.cpp - Command line arguments adjuster -----------===// |
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 | | // This file contains definitions of classes which implement ArgumentsAdjuster |
10 | | // interface. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "clang/Tooling/ArgumentsAdjusters.h" |
15 | | #include "clang/Basic/LLVM.h" |
16 | | #include "llvm/ADT/STLExtras.h" |
17 | | #include "llvm/ADT/StringRef.h" |
18 | | #include <cstddef> |
19 | | #include <vector> |
20 | | |
21 | | namespace clang { |
22 | | namespace tooling { |
23 | | |
24 | 25.2k | static StringRef getDriverMode(const CommandLineArguments &Args) { |
25 | 166k | for (const auto &Arg : Args) { |
26 | 166k | StringRef ArgRef = Arg; |
27 | 166k | if (ArgRef.consume_front("--driver-mode=")) { |
28 | 13 | return ArgRef; |
29 | 13 | } |
30 | 166k | } |
31 | 25.2k | return StringRef(); |
32 | 25.2k | } |
33 | | |
34 | | /// Add -fsyntax-only option and drop options that triggers output generation. |
35 | 381 | ArgumentsAdjuster getClangSyntaxOnlyAdjuster() { |
36 | 437 | return [](const CommandLineArguments &Args, StringRef /*unused*/) { |
37 | 437 | CommandLineArguments AdjustedArgs; |
38 | 437 | bool HasSyntaxOnly = false; |
39 | 437 | constexpr llvm::StringRef OutputCommands[] = { |
40 | | // FIXME: Add other options that generate output. |
41 | 437 | "-save-temps", |
42 | 437 | "--save-temps", |
43 | 437 | }; |
44 | 1.54k | for (size_t i = 0, e = Args.size(); i < e; ++i1.10k ) { |
45 | 1.10k | StringRef Arg = Args[i]; |
46 | | // Skip output commands. |
47 | 2.20k | if (llvm::any_of(OutputCommands, [&Arg](llvm::StringRef OutputCommand) 1.10k { |
48 | 2.20k | return Arg.startswith(OutputCommand); |
49 | 2.20k | })) |
50 | 5 | continue; |
51 | | |
52 | 1.10k | if (!Arg.startswith("-fcolor-diagnostics") && |
53 | 1.10k | !Arg.startswith("-fdiagnostics-color")1.10k ) |
54 | 1.09k | AdjustedArgs.push_back(Args[i]); |
55 | | // If we strip a color option, make sure we strip any preceeding `-Xclang` |
56 | | // option as well. |
57 | | // FIXME: This should be added to most argument adjusters! |
58 | 3 | else if (!AdjustedArgs.empty() && AdjustedArgs.back() == "-Xclang"0 ) |
59 | 0 | AdjustedArgs.pop_back(); |
60 | | |
61 | 1.10k | if (Arg == "-fsyntax-only") |
62 | 107 | HasSyntaxOnly = true; |
63 | 1.10k | } |
64 | 437 | if (!HasSyntaxOnly) |
65 | 331 | AdjustedArgs = |
66 | 331 | getInsertArgumentAdjuster("-fsyntax-only")(AdjustedArgs, ""); |
67 | 437 | return AdjustedArgs; |
68 | 437 | }; |
69 | 381 | } |
70 | | |
71 | 377 | ArgumentsAdjuster getClangStripOutputAdjuster() { |
72 | 433 | return [](const CommandLineArguments &Args, StringRef /*unused*/) { |
73 | 433 | CommandLineArguments AdjustedArgs; |
74 | 1.53k | for (size_t i = 0, e = Args.size(); i < e; ++i1.09k ) { |
75 | 1.09k | StringRef Arg = Args[i]; |
76 | 1.09k | if (!Arg.startswith("-o")) |
77 | 1.09k | AdjustedArgs.push_back(Args[i]); |
78 | | |
79 | 1.09k | if (Arg == "-o") { |
80 | | // Output is specified as -o foo. Skip the next argument too. |
81 | 2 | ++i; |
82 | 2 | } |
83 | | // Else, the output is specified as -ofoo. Just do nothing. |
84 | 1.09k | } |
85 | 433 | return AdjustedArgs; |
86 | 433 | }; |
87 | 377 | } |
88 | | |
89 | 25.2k | ArgumentsAdjuster getClangStripDependencyFileAdjuster() { |
90 | 25.2k | return [](const CommandLineArguments &Args, StringRef /*unused*/) { |
91 | 25.2k | auto UsingClDriver = (getDriverMode(Args) == "cl"); |
92 | | |
93 | 25.2k | CommandLineArguments AdjustedArgs; |
94 | 191k | for (size_t i = 0, e = Args.size(); i < e; ++i166k ) { |
95 | 166k | StringRef Arg = Args[i]; |
96 | | |
97 | | // These flags take an argument: -MX foo. Skip the next argument also. |
98 | 166k | if (!UsingClDriver && (166k Arg == "-MF"166k || Arg == "-MT"166k || Arg == "-MQ"166k )) { |
99 | 2 | ++i; |
100 | 2 | continue; |
101 | 2 | } |
102 | | // When not using the cl driver mode, dependency file generation options |
103 | | // begin with -M. These include -MM, -MF, -MG, -MP, -MT, -MQ, -MD, and |
104 | | // -MMD. |
105 | 166k | if (!UsingClDriver && Arg.startswith("-M")166k ) |
106 | 3 | continue; |
107 | | // Under MSVC's cl driver mode, dependency file generation is controlled |
108 | | // using /showIncludes |
109 | 166k | if (Arg.startswith("/showIncludes") || Arg.startswith("-showIncludes")166k ) |
110 | 4 | continue; |
111 | | |
112 | 166k | AdjustedArgs.push_back(Args[i]); |
113 | 166k | } |
114 | 25.2k | return AdjustedArgs; |
115 | 25.2k | }; |
116 | 25.2k | } |
117 | | |
118 | | ArgumentsAdjuster getInsertArgumentAdjuster(const CommandLineArguments &Extra, |
119 | 973 | ArgumentInsertPosition Pos) { |
120 | 1.11k | return [Extra, Pos](const CommandLineArguments &Args, StringRef /*unused*/) { |
121 | 1.11k | CommandLineArguments Return(Args); |
122 | | |
123 | 1.11k | CommandLineArguments::iterator I; |
124 | 1.11k | if (Pos == ArgumentInsertPosition::END) { |
125 | 891 | I = std::find(Return.begin(), Return.end(), "--"); |
126 | 891 | } else { |
127 | 223 | I = Return.begin(); |
128 | 223 | ++I; // To leave the program name in place |
129 | 223 | } |
130 | | |
131 | 1.11k | Return.insert(I, Extra.begin(), Extra.end()); |
132 | 1.11k | return Return; |
133 | 1.11k | }; |
134 | 973 | } |
135 | | |
136 | | ArgumentsAdjuster getInsertArgumentAdjuster(const char *Extra, |
137 | 681 | ArgumentInsertPosition Pos) { |
138 | 681 | return getInsertArgumentAdjuster(CommandLineArguments(1, Extra), Pos); |
139 | 681 | } |
140 | | |
141 | | ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First, |
142 | 1.39k | ArgumentsAdjuster Second) { |
143 | 1.39k | if (!First) |
144 | 281 | return Second; |
145 | 1.11k | if (!Second) |
146 | 103 | return First; |
147 | 1.19k | return [First, Second](const CommandLineArguments &Args, StringRef File) 1.01k { |
148 | 1.19k | return Second(First(Args, File), File); |
149 | 1.19k | }; |
150 | 1.11k | } |
151 | | |
152 | 1 | ArgumentsAdjuster getStripPluginsAdjuster() { |
153 | 1 | return [](const CommandLineArguments &Args, StringRef /*unused*/) { |
154 | 1 | CommandLineArguments AdjustedArgs; |
155 | 4 | for (size_t I = 0, E = Args.size(); I != E; I++3 ) { |
156 | | // According to https://clang.llvm.org/docs/ClangPlugins.html |
157 | | // plugin arguments are in the form: |
158 | | // -Xclang {-load, -plugin, -plugin-arg-<plugin-name>, -add-plugin} |
159 | | // -Xclang <arbitrary-argument> |
160 | 3 | if (I + 4 < E && Args[I] == "-Xclang"2 && |
161 | 3 | (1 Args[I + 1] == "-load"1 || Args[I + 1] == "-plugin"1 || |
162 | 1 | llvm::StringRef(Args[I + 1]).startswith("-plugin-arg-") || |
163 | 1 | Args[I + 1] == "-add-plugin") && |
164 | 3 | Args[I + 2] == "-Xclang"1 ) { |
165 | 1 | I += 3; |
166 | 1 | continue; |
167 | 1 | } |
168 | 2 | AdjustedArgs.push_back(Args[I]); |
169 | 2 | } |
170 | 1 | return AdjustedArgs; |
171 | 1 | }; |
172 | 1 | } |
173 | | |
174 | | } // end namespace tooling |
175 | | } // end namespace clang |