Coverage Report

Created: 2020-09-19 12:23

/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
22.0k
static StringRef getDriverMode(const CommandLineArguments &Args) {
25
148k
  for (const auto &Arg : Args) {
26
148k
    StringRef ArgRef = Arg;
27
148k
    if (ArgRef.consume_front("--driver-mode=")) {
28
12
      return ArgRef;
29
12
    }
30
148k
  }
31
22.0k
  return StringRef();
32
22.0k
}
33
34
/// Add -fsyntax-only option and drop options that triggers output generation.
35
429
ArgumentsAdjuster getClangSyntaxOnlyAdjuster() {
36
380
  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
37
380
    CommandLineArguments AdjustedArgs;
38
380
    bool HasSyntaxOnly = false;
39
380
    constexpr llvm::StringRef OutputCommands[] = {
40
        // FIXME: Add other options that generate output.
41
380
        "-save-temps",
42
380
        "--save-temps",
43
380
    };
44
1.28k
    for (size_t i = 0, e = Args.size(); i < e; 
++i908
) {
45
908
      StringRef Arg = Args[i];
46
      // Skip output commands.
47
1.81k
      if (
llvm::any_of(OutputCommands, [&Arg](llvm::StringRef OutputCommand) 908
{
48
1.81k
            return Arg.startswith(OutputCommand);
49
1.81k
          }))
50
4
        continue;
51
904
52
904
      if (!Arg.startswith("-fcolor-diagnostics") &&
53
904
          !Arg.startswith("-fdiagnostics-color"))
54
903
        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
1
      else if (!AdjustedArgs.empty() && 
AdjustedArgs.back() == "-Xclang"0
)
59
0
        AdjustedArgs.pop_back();
60
904
61
904
      if (Arg == "-fsyntax-only")
62
105
        HasSyntaxOnly = true;
63
904
    }
64
380
    if (!HasSyntaxOnly)
65
275
      AdjustedArgs.push_back("-fsyntax-only");
66
380
    return AdjustedArgs;
67
380
  };
68
429
}
69
70
466
ArgumentsAdjuster getClangStripOutputAdjuster() {
71
414
  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
72
414
    CommandLineArguments AdjustedArgs;
73
1.46k
    for (size_t i = 0, e = Args.size(); i < e; 
++i1.04k
) {
74
1.04k
      StringRef Arg = Args[i];
75
1.04k
      if (!Arg.startswith("-o"))
76
1.04k
        AdjustedArgs.push_back(Args[i]);
77
1.04k
78
1.04k
      if (Arg == "-o") {
79
        // Output is specified as -o foo. Skip the next argument too.
80
1
        ++i;
81
1
      }
82
      // Else, the output is specified as -ofoo. Just do nothing.
83
1.04k
    }
84
414
    return AdjustedArgs;
85
414
  };
86
466
}
87
88
27
ArgumentsAdjuster getClangStripSerializeDiagnosticAdjuster() {
89
65
  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
90
65
    CommandLineArguments AdjustedArgs;
91
1.23k
    for (size_t i = 0, e = Args.size(); i < e; 
++i1.16k
) {
92
1.16k
      StringRef Arg = Args[i];
93
1.16k
      if (Arg == "--serialize-diagnostics") {
94
        // Skip the diagnostic output argument.
95
1
        ++i;
96
1
        continue;
97
1
      }
98
1.16k
      AdjustedArgs.push_back(Args[i]);
99
1.16k
    }
100
65
    return AdjustedArgs;
101
65
  };
102
27
}
103
104
22.1k
ArgumentsAdjuster getClangStripDependencyFileAdjuster() {
105
22.0k
  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
106
22.0k
    auto UsingClDriver = (getDriverMode(Args) == "cl");
107
22.0k
108
22.0k
    CommandLineArguments AdjustedArgs;
109
171k
    for (size_t i = 0, e = Args.size(); i < e; 
++i148k
) {
110
148k
      StringRef Arg = Args[i];
111
148k
112
      // These flags take an argument: -MX foo. Skip the next argument also.
113
148k
      if (!UsingClDriver && 
(148k
Arg == "-MF"148k
||
Arg == "-MT"148k
||
Arg == "-MQ"148k
)) {
114
2
        ++i;
115
2
        continue;
116
2
      }
117
      // When not using the cl driver mode, dependency file generation options
118
      // begin with -M. These include -MM, -MF, -MG, -MP, -MT, -MQ, -MD, and
119
      // -MMD.
120
148k
      if (!UsingClDriver && 
Arg.startswith("-M")148k
)
121
3
        continue;
122
      // Under MSVC's cl driver mode, dependency file generation is controlled
123
      // using /showIncludes
124
148k
      if (Arg.startswith("/showIncludes") || 
Arg.startswith("-showIncludes")148k
)
125
4
        continue;
126
148k
127
148k
      AdjustedArgs.push_back(Args[i]);
128
148k
    }
129
22.0k
    return AdjustedArgs;
130
22.0k
  };
131
22.1k
}
132
133
ArgumentsAdjuster getInsertArgumentAdjuster(const CommandLineArguments &Extra,
134
305
                                            ArgumentInsertPosition Pos) {
135
432
  return [Extra, Pos](const CommandLineArguments &Args, StringRef /*unused*/) {
136
432
    CommandLineArguments Return(Args);
137
432
138
432
    CommandLineArguments::iterator I;
139
432
    if (Pos == ArgumentInsertPosition::END) {
140
197
      I = Return.end();
141
235
    } else {
142
235
      I = Return.begin();
143
235
      ++I; // To leave the program name in place
144
235
    }
145
432
146
432
    Return.insert(I, Extra.begin(), Extra.end());
147
432
    return Return;
148
432
  };
149
305
}
150
151
ArgumentsAdjuster getInsertArgumentAdjuster(const char *Extra,
152
37
                                            ArgumentInsertPosition Pos) {
153
37
  return getInsertArgumentAdjuster(CommandLineArguments(1, Extra), Pos);
154
37
}
155
156
ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First,
157
1.63k
                                   ArgumentsAdjuster Second) {
158
1.63k
  if (!First)
159
369
    return Second;
160
1.26k
  if (!Second)
161
102
    return First;
162
1.16k
  return [First, Second](const CommandLineArguments &Args, StringRef File) {
163
1.12k
    return Second(First(Args, File), File);
164
1.12k
  };
165
1.16k
}
166
167
1
ArgumentsAdjuster getStripPluginsAdjuster() {
168
1
  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
169
1
    CommandLineArguments AdjustedArgs;
170
4
    for (size_t I = 0, E = Args.size(); I != E; 
I++3
) {
171
      // According to https://clang.llvm.org/docs/ClangPlugins.html
172
      // plugin arguments are in the form:
173
      // -Xclang {-load, -plugin, -plugin-arg-<plugin-name>, -add-plugin}
174
      // -Xclang <arbitrary-argument>
175
3
      if (I + 4 < E && 
Args[I] == "-Xclang"2
&&
176
1
          (Args[I + 1] == "-load" || Args[I + 1] == "-plugin" ||
177
1
           llvm::StringRef(Args[I + 1]).startswith("-plugin-arg-") ||
178
1
           Args[I + 1] == "-add-plugin") &&
179
1
          Args[I + 2] == "-Xclang") {
180
1
        I += 3;
181
1
        continue;
182
1
      }
183
2
      AdjustedArgs.push_back(Args[I]);
184
2
    }
185
1
    return AdjustedArgs;
186
1
  };
187
1
}
188
189
} // end namespace tooling
190
} // end namespace clang