clang 19.0.0git
ArgumentsAdjusters.cpp
Go to the documentation of this file.
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
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
21namespace clang {
22namespace tooling {
23
24static StringRef getDriverMode(const CommandLineArguments &Args) {
25 for (const auto &Arg : Args) {
26 StringRef ArgRef = Arg;
27 if (ArgRef.consume_front("--driver-mode=")) {
28 return ArgRef;
29 }
30 }
31 return StringRef();
32}
33
34/// Add -fsyntax-only option and drop options that triggers output generation.
36 return [](const CommandLineArguments &Args, StringRef /*unused*/) {
37 CommandLineArguments AdjustedArgs;
38 bool HasSyntaxOnly = false;
39 constexpr llvm::StringRef OutputCommands[] = {
40 // FIXME: Add other options that generate output.
41 "-save-temps",
42 "--save-temps",
43 };
44 for (size_t i = 0, e = Args.size(); i < e; ++i) {
45 StringRef Arg = Args[i];
46 // Skip output commands.
47 if (llvm::any_of(OutputCommands, [&Arg](llvm::StringRef OutputCommand) {
48 return Arg.starts_with(OutputCommand);
49 }))
50 continue;
51
52 if (!Arg.starts_with("-fcolor-diagnostics") &&
53 !Arg.starts_with("-fdiagnostics-color"))
54 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 else if (!AdjustedArgs.empty() && AdjustedArgs.back() == "-Xclang")
59 AdjustedArgs.pop_back();
60
61 if (Arg == "-fsyntax-only")
62 HasSyntaxOnly = true;
63 }
64 if (!HasSyntaxOnly)
65 AdjustedArgs =
66 getInsertArgumentAdjuster("-fsyntax-only")(AdjustedArgs, "");
67 return AdjustedArgs;
68 };
69}
70
72 return [](const CommandLineArguments &Args, StringRef /*unused*/) {
73 CommandLineArguments AdjustedArgs;
74 for (size_t i = 0, e = Args.size(); i < e; ++i) {
75 StringRef Arg = Args[i];
76 if (!Arg.starts_with("-o"))
77 AdjustedArgs.push_back(Args[i]);
78
79 if (Arg == "-o") {
80 // Output is specified as -o foo. Skip the next argument too.
81 ++i;
82 }
83 // Else, the output is specified as -ofoo. Just do nothing.
84 }
85 return AdjustedArgs;
86 };
87}
88
90 return [](const CommandLineArguments &Args, StringRef /*unused*/) {
91 auto UsingClDriver = (getDriverMode(Args) == "cl");
92
93 CommandLineArguments AdjustedArgs;
94 for (size_t i = 0, e = Args.size(); i < e; ++i) {
95 StringRef Arg = Args[i];
96
97 // These flags take an argument: -MX foo. Skip the next argument also.
98 if (!UsingClDriver && (Arg == "-MF" || Arg == "-MT" || Arg == "-MQ")) {
99 ++i;
100 continue;
101 }
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 if (!UsingClDriver && Arg.starts_with("-M"))
106 continue;
107 // Under MSVC's cl driver mode, dependency file generation is controlled
108 // using /showIncludes
109 if (Arg.starts_with("/showIncludes") || Arg.starts_with("-showIncludes"))
110 continue;
111
112 AdjustedArgs.push_back(Args[i]);
113 }
114 return AdjustedArgs;
115 };
116}
117
120 return [Extra, Pos](const CommandLineArguments &Args, StringRef /*unused*/) {
121 CommandLineArguments Return(Args);
122
123 CommandLineArguments::iterator I;
124 if (Pos == ArgumentInsertPosition::END) {
125 I = llvm::find(Return, "--");
126 } else {
127 I = Return.begin();
128 ++I; // To leave the program name in place
129 }
130
131 Return.insert(I, Extra.begin(), Extra.end());
132 return Return;
133 };
134}
135
138 return getInsertArgumentAdjuster(CommandLineArguments(1, Extra), Pos);
139}
140
142 ArgumentsAdjuster Second) {
143 if (!First)
144 return Second;
145 if (!Second)
146 return First;
147 return [First, Second](const CommandLineArguments &Args, StringRef File) {
148 return Second(First(Args, File), File);
149 };
150}
151
153 return [](const CommandLineArguments &Args, StringRef /*unused*/) {
154 CommandLineArguments AdjustedArgs;
155 for (size_t I = 0, E = Args.size(); I != E; I++) {
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 if (I + 4 < E && Args[I] == "-Xclang" &&
161 (Args[I + 1] == "-load" || Args[I + 1] == "-plugin" ||
162 llvm::StringRef(Args[I + 1]).starts_with("-plugin-arg-") ||
163 Args[I + 1] == "-add-plugin") &&
164 Args[I + 2] == "-Xclang") {
165 I += 3;
166 continue;
167 }
168 AdjustedArgs.push_back(Args[I]);
169 }
170 return AdjustedArgs;
171 };
172}
173
174} // end namespace tooling
175} // end namespace clang
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static StringRef getDriverMode(const CommandLineArguments &Args)
std::vector< std::string > CommandLineArguments
A sequence of command line arguments.
ArgumentsAdjuster getClangSyntaxOnlyAdjuster()
Gets an argument adjuster that converts input command line arguments to the "syntax check only" varia...
ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First, ArgumentsAdjuster Second)
Gets an argument adjuster which adjusts the arguments in sequence with the First adjuster and then wi...
ArgumentsAdjuster getStripPluginsAdjuster()
Gets an argument adjuster which strips plugin related command line arguments.
ArgumentsAdjuster getClangStripDependencyFileAdjuster()
Gets an argument adjuster which removes dependency-file related command line arguments.
std::function< CommandLineArguments(const CommandLineArguments &, StringRef Filename)> ArgumentsAdjuster
A prototype of a command line adjuster.
ArgumentsAdjuster getInsertArgumentAdjuster(const CommandLineArguments &Extra, ArgumentInsertPosition Pos)
Gets an argument adjuster which inserts Extra arguments in the specified position.
ArgumentsAdjuster getClangStripOutputAdjuster()
Gets an argument adjuster which removes output-related command line arguments.
The JSON file list parser is used to communicate input to InstallAPI.