clang  10.0.0svn
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/StringRef.h"
17 #include <cstddef>
18 
19 namespace clang {
20 namespace tooling {
21 
22 /// Add -fsyntax-only option to the command line arguments.
24  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
25  CommandLineArguments AdjustedArgs;
26  bool HasSyntaxOnly = false;
27  for (size_t i = 0, e = Args.size(); i < e; ++i) {
28  StringRef Arg = Args[i];
29  // FIXME: Remove options that generate output.
30  if (!Arg.startswith("-fcolor-diagnostics") &&
31  !Arg.startswith("-fdiagnostics-color"))
32  AdjustedArgs.push_back(Args[i]);
33  if (Arg == "-fsyntax-only")
34  HasSyntaxOnly = true;
35  }
36  if (!HasSyntaxOnly)
37  AdjustedArgs.push_back("-fsyntax-only");
38  return AdjustedArgs;
39  };
40 }
41 
43  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
44  CommandLineArguments AdjustedArgs;
45  for (size_t i = 0, e = Args.size(); i < e; ++i) {
46  StringRef Arg = Args[i];
47  if (!Arg.startswith("-o"))
48  AdjustedArgs.push_back(Args[i]);
49 
50  if (Arg == "-o") {
51  // Output is specified as -o foo. Skip the next argument too.
52  ++i;
53  }
54  // Else, the output is specified as -ofoo. Just do nothing.
55  }
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 == "--serialize-diagnostics") {
66  // Skip the diagnostic output argument.
67  ++i;
68  continue;
69  }
70  AdjustedArgs.push_back(Args[i]);
71  }
72  return AdjustedArgs;
73  };
74 }
75 
77  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
78  CommandLineArguments AdjustedArgs;
79  for (size_t i = 0, e = Args.size(); i < e; ++i) {
80  StringRef Arg = Args[i];
81  // All dependency-file options begin with -M. These include -MM,
82  // -MF, -MG, -MP, -MT, -MQ, -MD, and -MMD.
83  if (!Arg.startswith("-M")) {
84  AdjustedArgs.push_back(Args[i]);
85  continue;
86  }
87 
88  if (Arg == "-MF" || Arg == "-MT" || Arg == "-MQ")
89  // These flags take an argument: -MX foo. Skip the next argument also.
90  ++i;
91  }
92  return AdjustedArgs;
93  };
94 }
95 
98  return [Extra, Pos](const CommandLineArguments &Args, StringRef /*unused*/) {
99  CommandLineArguments Return(Args);
100 
101  CommandLineArguments::iterator I;
102  if (Pos == ArgumentInsertPosition::END) {
103  I = Return.end();
104  } else {
105  I = Return.begin();
106  ++I; // To leave the program name in place
107  }
108 
109  Return.insert(I, Extra.begin(), Extra.end());
110  return Return;
111  };
112 }
113 
116  return getInsertArgumentAdjuster(CommandLineArguments(1, Extra), Pos);
117 }
118 
120  ArgumentsAdjuster Second) {
121  if (!First)
122  return Second;
123  if (!Second)
124  return First;
125  return [First, Second](const CommandLineArguments &Args, StringRef File) {
126  return Second(First(Args, File), File);
127  };
128 }
129 
131  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
132  CommandLineArguments AdjustedArgs;
133  for (size_t I = 0, E = Args.size(); I != E; I++) {
134  // According to https://clang.llvm.org/docs/ClangPlugins.html
135  // plugin arguments are in the form:
136  // -Xclang {-load, -plugin, -plugin-arg-<plugin-name>, -add-plugin}
137  // -Xclang <arbitrary-argument>
138  if (I + 4 < E && Args[I] == "-Xclang" &&
139  (Args[I + 1] == "-load" || Args[I + 1] == "-plugin" ||
140  llvm::StringRef(Args[I + 1]).startswith("-plugin-arg-") ||
141  Args[I + 1] == "-add-plugin") &&
142  Args[I + 2] == "-Xclang") {
143  I += 3;
144  continue;
145  }
146  AdjustedArgs.push_back(Args[I]);
147  }
148  return AdjustedArgs;
149  };
150 }
151 
152 } // end namespace tooling
153 } // 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.