Coverage Report

Created: 2021-09-21 08:58

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