clang 20.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 != "-c" && Arg != "-S" &&
53 !Arg.starts_with("-fcolor-diagnostics") &&
54 !Arg.starts_with("-fdiagnostics-color"))
55 AdjustedArgs.push_back(Args[i]);
56 // If we strip an option, make sure we strip any preceeding `-Xclang`
57 // option as well.
58 // FIXME: This should be added to most argument adjusters!
59 else if (!AdjustedArgs.empty() && AdjustedArgs.back() == "-Xclang")
60 AdjustedArgs.pop_back();
61
62 if (Arg == "-fsyntax-only")
63 HasSyntaxOnly = true;
64 }
65 if (!HasSyntaxOnly)
66 AdjustedArgs =
67 getInsertArgumentAdjuster("-fsyntax-only")(AdjustedArgs, "");
68 return AdjustedArgs;
69 };
70}
71
73 return [](const CommandLineArguments &Args, StringRef /*unused*/) {
74 CommandLineArguments AdjustedArgs;
75 for (size_t i = 0, e = Args.size(); i < e; ++i) {
76 StringRef Arg = Args[i];
77 if (!Arg.starts_with("-o"))
78 AdjustedArgs.push_back(Args[i]);
79
80 if (Arg == "-o") {
81 // Output is specified as -o foo. Skip the next argument too.
82 ++i;
83 }
84 // Else, the output is specified as -ofoo. Just do nothing.
85 }
86 return AdjustedArgs;
87 };
88}
89
91 return [](const CommandLineArguments &Args, StringRef /*unused*/) {
92 auto UsingClDriver = (getDriverMode(Args) == "cl");
93
94 CommandLineArguments AdjustedArgs;
95 for (size_t i = 0, e = Args.size(); i < e; ++i) {
96 StringRef Arg = Args[i];
97
98 // These flags take an argument: -MX foo. Skip the next argument also.
99 if (!UsingClDriver && (Arg == "-MF" || Arg == "-MT" || Arg == "-MQ")) {
100 ++i;
101 continue;
102 }
103 // When not using the cl driver mode, dependency file generation options
104 // begin with -M. These include -MM, -MF, -MG, -MP, -MT, -MQ, -MD, and
105 // -MMD.
106 if (!UsingClDriver && Arg.starts_with("-M"))
107 continue;
108 // Under MSVC's cl driver mode, dependency file generation is controlled
109 // using /showIncludes
110 if (Arg.starts_with("/showIncludes") || Arg.starts_with("-showIncludes"))
111 continue;
112
113 AdjustedArgs.push_back(Args[i]);
114 }
115 return AdjustedArgs;
116 };
117}
118
121 return [Extra, Pos](const CommandLineArguments &Args, StringRef /*unused*/) {
122 CommandLineArguments Return(Args);
123
124 CommandLineArguments::iterator I;
125 if (Pos == ArgumentInsertPosition::END) {
126 I = llvm::find(Return, "--");
127 } else {
128 I = Return.begin();
129 ++I; // To leave the program name in place
130 }
131
132 Return.insert(I, Extra.begin(), Extra.end());
133 return Return;
134 };
135}
136
139 return getInsertArgumentAdjuster(CommandLineArguments(1, Extra), Pos);
140}
141
143 ArgumentsAdjuster Second) {
144 if (!First)
145 return Second;
146 if (!Second)
147 return First;
148 return [First, Second](const CommandLineArguments &Args, StringRef File) {
149 return Second(First(Args, File), File);
150 };
151}
152
154 return [](const CommandLineArguments &Args, StringRef /*unused*/) {
155 CommandLineArguments AdjustedArgs;
156 for (size_t I = 0, E = Args.size(); I != E; I++) {
157 // According to https://clang.llvm.org/docs/ClangPlugins.html
158 // plugin arguments are in the form:
159 // -Xclang {-load, -plugin, -plugin-arg-<plugin-name>, -add-plugin}
160 // -Xclang <arbitrary-argument>
161 if (I + 4 < E && Args[I] == "-Xclang" &&
162 (Args[I + 1] == "-load" || Args[I + 1] == "-plugin" ||
163 llvm::StringRef(Args[I + 1]).starts_with("-plugin-arg-") ||
164 Args[I + 1] == "-add-plugin") &&
165 Args[I + 2] == "-Xclang") {
166 I += 3;
167 continue;
168 }
169 AdjustedArgs.push_back(Args[I]);
170 }
171 return AdjustedArgs;
172 };
173}
174
175} // end namespace tooling
176} // end namespace clang
Expr * E
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.