Coverage Report

Created: 2021-01-26 06:56

/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.7k
static StringRef getDriverMode(const CommandLineArguments &Args) {
25
153k
  for (const auto &Arg : Args) {
26
153k
    StringRef ArgRef = Arg;
27
153k
    if (ArgRef.consume_front("--driver-mode=")) {
28
12
      return ArgRef;
29
12
    }
30
153k
  }
31
22.7k
  return StringRef();
32
22.7k
}
33
34
/// Add -fsyntax-only option and drop options that triggers output generation.
35
448
ArgumentsAdjuster getClangSyntaxOnlyAdjuster() {
36
395
  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
37
395
    CommandLineArguments AdjustedArgs;
38
395
    bool HasSyntaxOnly = false;
39
395
    constexpr llvm::StringRef OutputCommands[] = {
40
        // FIXME: Add other options that generate output.
41
395
        "-save-temps",
42
395
        "--save-temps",
43
395
    };
44
1.33k
    for (size_t i = 0, e = Args.size(); i < e; 
++i939
) {
45
939
      StringRef Arg = Args[i];
46
      // Skip output commands.
47
1.87k
      if (
llvm::any_of(OutputCommands, [&Arg](llvm::StringRef OutputCommand) 939
{
48
1.87k
            return Arg.startswith(OutputCommand);
49
1.87k
          }))
50
4
        continue;
51
52
935
      if (!Arg.startswith("-fcolor-diagnostics") &&
53
935
          !Arg.startswith("-fdiagnostics-color"))
54
934
        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
61
935
      if (Arg == "-fsyntax-only")
62
105
        HasSyntaxOnly = true;
63
935
    }
64
395
    if (!HasSyntaxOnly)
65
290
      AdjustedArgs.push_back("-fsyntax-only");
66
395
    return AdjustedArgs;
67
395
  };
68
448
}
69
70
485
ArgumentsAdjuster getClangStripOutputAdjuster() {
71
430
  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
72
430
    CommandLineArguments AdjustedArgs;
73
1.50k
    for (size_t i = 0, e = Args.size(); i < e; 
++i1.07k
) {
74
1.07k
      StringRef Arg = Args[i];
75
1.07k
      if (!Arg.startswith("-o"))
76
1.07k
        AdjustedArgs.push_back(Args[i]);
77
78
1.07k
      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.07k
    }
84
430
    return AdjustedArgs;
85
430
  };
86
485
}
87
88
31
ArgumentsAdjuster getClangStripSerializeDiagnosticAdjuster() {
89
75
  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
90
75
    CommandLineArguments AdjustedArgs;
91
1.38k
    for (size_t i = 0, e = Args.size(); i < e; 
++i1.31k
) {
92
1.31k
      StringRef Arg = Args[i];
93
1.31k
      if (Arg == "--serialize-diagnostics") {
94
        // Skip the diagnostic output argument.
95
1
        ++i;
96
1
        continue;
97
1
      }
98
1.30k
      AdjustedArgs.push_back(Args[i]);
99
1.30k
    }
100
75
    return AdjustedArgs;
101
75
  };
102
31
}
103
104
22.8k
ArgumentsAdjuster getClangStripDependencyFileAdjuster() {
105
22.7k
  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
106
22.7k
    auto UsingClDriver = (getDriverMode(Args) == "cl");
107
108
22.7k
    CommandLineArguments AdjustedArgs;
109
176k
    for (size_t i = 0, e = Args.size(); i < e; 
++i153k
) {
110
153k
      StringRef Arg = Args[i];
111
112
      // These flags take an argument: -MX foo. Skip the next argument also.
113
153k
      if (!UsingClDriver && 
(153k
Arg == "-MF"153k
||
Arg == "-MT"153k
||
Arg == "-MQ"153k
)) {
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
153k
      if (!UsingClDriver && 
Arg.startswith("-M")153k
)
121
3
        continue;
122
      // Under MSVC's cl driver mode, dependency file generation is controlled
123
      // using /showIncludes
124
153k
      if (Arg.startswith("/showIncludes") || 
Arg.startswith("-showIncludes")153k
)
125
4
        continue;
126
127
153k
      AdjustedArgs.push_back(Args[i]);
128
153k
    }
129
22.7k
    return AdjustedArgs;
130
22.7k
  };
131
22.8k
}
132
133
ArgumentsAdjuster getInsertArgumentAdjuster(const CommandLineArguments &Extra,
134
321
                                            ArgumentInsertPosition Pos) {
135
464
  return [Extra, Pos](const CommandLineArguments &Args, StringRef /*unused*/) {
136
464
    CommandLineArguments Return(Args);
137
138
464
    CommandLineArguments::iterator I;
139
464
    if (Pos == ArgumentInsertPosition::END) {
140
213
      I = Return.end();
141
251
    } else {
142
251
      I = Return.begin();
143
251
      ++I; // To leave the program name in place
144
251
    }
145
146
464
    Return.insert(I, Extra.begin(), Extra.end());
147
464
    return Return;
148
464
  };
149
321
}
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.69k
                                   ArgumentsAdjuster Second) {
158
1.69k
  if (!First)
159
386
    return Second;
160
1.31k
  if (!Second)
161
103
    return First;
162
1.21k
  return [First, Second](const CommandLineArguments &Args, StringRef File) {
163
1.16k
    return Second(First(Args, File), File);
164
1.16k
  };
165
1.21k
}
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