clang  11.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 
21 namespace clang {
22 namespace tooling {
23 
24 /// Add -fsyntax-only option and drop options that triggers output generation.
26  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
27  CommandLineArguments AdjustedArgs;
28  bool HasSyntaxOnly = false;
29  constexpr llvm::StringRef OutputCommands[] = {
30  // FIXME: Add other options that generate output.
31  "-save-temps",
32  "--save-temps",
33  };
34  for (size_t i = 0, e = Args.size(); i < e; ++i) {
35  StringRef Arg = Args[i];
36  // Skip output commands.
37  if (llvm::any_of(OutputCommands, [&Arg](llvm::StringRef OutputCommand) {
38  return Arg.startswith(OutputCommand);
39  }))
40  continue;
41 
42  if (!Arg.startswith("-fcolor-diagnostics") &&
43  !Arg.startswith("-fdiagnostics-color"))
44  AdjustedArgs.push_back(Args[i]);
45  // If we strip a color option, make sure we strip any preceeding `-Xclang`
46  // option as well.
47  // FIXME: This should be added to most argument adjusters!
48  else if (!AdjustedArgs.empty() && AdjustedArgs.back() == "-Xclang")
49  AdjustedArgs.pop_back();
50 
51  if (Arg == "-fsyntax-only")
52  HasSyntaxOnly = true;
53  }
54  if (!HasSyntaxOnly)
55  AdjustedArgs.push_back("-fsyntax-only");
56  return AdjustedArgs;
57  };
58 }
59 
61  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
62  CommandLineArguments AdjustedArgs;
63  for (size_t i = 0, e = Args.size(); i < e; ++i) {
64  StringRef Arg = Args[i];
65  if (!Arg.startswith("-o"))
66  AdjustedArgs.push_back(Args[i]);
67 
68  if (Arg == "-o") {
69  // Output is specified as -o foo. Skip the next argument too.
70  ++i;
71  }
72  // Else, the output is specified as -ofoo. Just do nothing.
73  }
74  return AdjustedArgs;
75  };
76 }
77 
79  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
80  CommandLineArguments AdjustedArgs;
81  for (size_t i = 0, e = Args.size(); i < e; ++i) {
82  StringRef Arg = Args[i];
83  if (Arg == "--serialize-diagnostics") {
84  // Skip the diagnostic output argument.
85  ++i;
86  continue;
87  }
88  AdjustedArgs.push_back(Args[i]);
89  }
90  return AdjustedArgs;
91  };
92 }
93 
95  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
96  CommandLineArguments AdjustedArgs;
97  for (size_t i = 0, e = Args.size(); i < e; ++i) {
98  StringRef Arg = Args[i];
99  // All dependency-file options begin with -M. These include -MM,
100  // -MF, -MG, -MP, -MT, -MQ, -MD, and -MMD.
101  if (!Arg.startswith("-M") && !Arg.startswith("/showIncludes") &&
102  !Arg.startswith("-showIncludes")) {
103  AdjustedArgs.push_back(Args[i]);
104  continue;
105  }
106 
107  if (Arg == "-MF" || Arg == "-MT" || Arg == "-MQ")
108  // These flags take an argument: -MX foo. Skip the next argument also.
109  ++i;
110  }
111  return AdjustedArgs;
112  };
113 }
114 
117  return [Extra, Pos](const CommandLineArguments &Args, StringRef /*unused*/) {
118  CommandLineArguments Return(Args);
119 
120  CommandLineArguments::iterator I;
121  if (Pos == ArgumentInsertPosition::END) {
122  I = Return.end();
123  } else {
124  I = Return.begin();
125  ++I; // To leave the program name in place
126  }
127 
128  Return.insert(I, Extra.begin(), Extra.end());
129  return Return;
130  };
131 }
132 
135  return getInsertArgumentAdjuster(CommandLineArguments(1, Extra), Pos);
136 }
137 
139  ArgumentsAdjuster Second) {
140  if (!First)
141  return Second;
142  if (!Second)
143  return First;
144  return [First, Second](const CommandLineArguments &Args, StringRef File) {
145  return Second(First(Args, File), File);
146  };
147 }
148 
150  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
151  CommandLineArguments AdjustedArgs;
152  for (size_t I = 0, E = Args.size(); I != E; I++) {
153  // According to https://clang.llvm.org/docs/ClangPlugins.html
154  // plugin arguments are in the form:
155  // -Xclang {-load, -plugin, -plugin-arg-<plugin-name>, -add-plugin}
156  // -Xclang <arbitrary-argument>
157  if (I + 4 < E && Args[I] == "-Xclang" &&
158  (Args[I + 1] == "-load" || Args[I + 1] == "-plugin" ||
159  llvm::StringRef(Args[I + 1]).startswith("-plugin-arg-") ||
160  Args[I + 1] == "-add-plugin") &&
161  Args[I + 2] == "-Xclang") {
162  I += 3;
163  continue;
164  }
165  AdjustedArgs.push_back(Args[I]);
166  }
167  return AdjustedArgs;
168  };
169 }
170 
171 } // end namespace tooling
172 } // end namespace clang
std::vector< std::string > CommandLineArguments
A sequence of command line arguments.
ArgumentsAdjuster getInsertArgumentAdjuster(const CommandLineArguments &Extra, ArgumentInsertPosition Pos)
Gets an argument adjuster which inserts Extra arguments in the specified position.
ArgumentsAdjuster getClangStripDependencyFileAdjuster()
Gets an argument adjuster which removes dependency-file related command line arguments.
ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First, ArgumentsAdjuster Second)
Gets an argument adjuster which adjusts the arguments in sequence with the First adjuster and then wi...
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
ArgumentsAdjuster getClangStripOutputAdjuster()
Gets an argument adjuster which removes output-related command line arguments.
std::function< CommandLineArguments(const CommandLineArguments &, StringRef Filename)> ArgumentsAdjuster
A prototype of a command line adjuster.
Dataflow Directional Tag Classes.
ArgumentsAdjuster getClangSyntaxOnlyAdjuster()
Gets an argument adjuster that converts input command line arguments to the "syntax check only" varia...
ArgumentsAdjuster getClangStripSerializeDiagnosticAdjuster()
Gets an argument adjuster which removes command line arguments related to diagnostic serialization...
ArgumentsAdjuster getStripPluginsAdjuster()
Gets an argument adjuster which strips plugin related command line arguments.