Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- AnalyzerOptions.cpp - Analysis Engine Options ----------------------===//
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 special accessors for analyzer configuration options
10
// with string representations.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
15
#include "clang/StaticAnalyzer/Core/Checker.h"
16
#include "llvm/ADT/SmallString.h"
17
#include "llvm/ADT/StringSwitch.h"
18
#include "llvm/ADT/StringRef.h"
19
#include "llvm/ADT/Twine.h"
20
#include "llvm/Support/ErrorHandling.h"
21
#include "llvm/Support/FileSystem.h"
22
#include "llvm/Support/FormattedStream.h"
23
#include "llvm/Support/raw_ostream.h"
24
#include <cassert>
25
#include <cstddef>
26
#include <utility>
27
#include <vector>
28
29
using namespace clang;
30
using namespace ento;
31
using namespace llvm;
32
33
std::vector<StringRef>
34
2
AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental /* = false */) {
35
2
  static const StringRef StaticAnalyzerChecks[] = {
36
2
#define GET_CHECKERS
37
2
#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN)                 \
38
328
  FULLNAME,
39
2
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
40
2
#undef CHECKER
41
2
#undef GET_CHECKERS
42
2
  };
43
2
  std::vector<StringRef> Result;
44
328
  for (StringRef CheckName : StaticAnalyzerChecks) {
45
328
    if (!CheckName.startswith("debug.") &&
46
328
        
(292
IncludeExperimental292
||
!CheckName.startswith("alpha.")146
))
47
248
      Result.push_back(CheckName);
48
328
  }
49
2
  return Result;
50
2
}
51
52
void AnalyzerOptions::printFormattedEntry(
53
    llvm::raw_ostream &Out,
54
    std::pair<StringRef, StringRef> EntryDescPair,
55
858
    size_t InitialPad, size_t EntryWidth, size_t MinLineWidth) {
56
858
57
858
  llvm::formatted_raw_ostream FOut(Out);
58
858
59
858
  const size_t PadForDesc = InitialPad + EntryWidth;
60
858
61
858
  FOut.PadToColumn(InitialPad) << EntryDescPair.first;
62
858
  // If the buffer's length is greater then PadForDesc, print a newline.
63
858
  if (FOut.getColumn() > PadForDesc)
64
0
    FOut << '\n';
65
858
66
858
  FOut.PadToColumn(PadForDesc);
67
858
68
858
  if (MinLineWidth == 0) {
69
656
    FOut << EntryDescPair.second;
70
656
    return;
71
656
  }
72
202
73
28.9k
  
for (char C : EntryDescPair.second)202
{
74
28.9k
    if (FOut.getColumn() > MinLineWidth && 
C == ' '0
) {
75
0
      FOut << '\n';
76
0
      FOut.PadToColumn(PadForDesc);
77
0
      continue;
78
0
    }
79
28.9k
    FOut << C;
80
28.9k
  }
81
202
}
82
83
ExplorationStrategyKind
84
10.8k
AnalyzerOptions::getExplorationStrategy() const {
85
10.8k
  auto K =
86
10.8k
    llvm::StringSwitch<llvm::Optional<ExplorationStrategyKind>>(
87
10.8k
                                                            ExplorationStrategy)
88
10.8k
          .Case("dfs", ExplorationStrategyKind::DFS)
89
10.8k
          .Case("bfs", ExplorationStrategyKind::BFS)
90
10.8k
          .Case("unexplored_first",
91
10.8k
                ExplorationStrategyKind::UnexploredFirst)
92
10.8k
          .Case("unexplored_first_queue",
93
10.8k
                ExplorationStrategyKind::UnexploredFirstQueue)
94
10.8k
          .Case("unexplored_first_location_queue",
95
10.8k
                ExplorationStrategyKind::UnexploredFirstLocationQueue)
96
10.8k
          .Case("bfs_block_dfs_contents",
97
10.8k
                ExplorationStrategyKind::BFSBlockDFSContents)
98
10.8k
          .Default(None);
99
10.8k
  assert(K.hasValue() && "User mode is invalid.");
100
10.8k
  return K.getValue();
101
10.8k
}
102
103
124k
IPAKind AnalyzerOptions::getIPAMode() const {
104
124k
  auto K = llvm::StringSwitch<llvm::Optional<IPAKind>>(IPAMode)
105
124k
          .Case("none", IPAK_None)
106
124k
          .Case("basic-inlining", IPAK_BasicInlining)
107
124k
          .Case("inlining", IPAK_Inlining)
108
124k
          .Case("dynamic", IPAK_DynamicDispatch)
109
124k
          .Case("dynamic-bifurcate", IPAK_DynamicDispatchBifurcate)
110
124k
          .Default(None);
111
124k
  assert(K.hasValue() && "IPA Mode is invalid.");
112
124k
113
124k
  return K.getValue();
114
124k
}
115
116
bool
117
AnalyzerOptions::mayInlineCXXMemberFunction(
118
14.1k
                                          CXXInlineableMemberKind Param) const {
119
14.1k
  if (getIPAMode() < IPAK_Inlining)
120
0
    return false;
121
14.1k
122
14.1k
  auto K =
123
14.1k
    llvm::StringSwitch<llvm::Optional<CXXInlineableMemberKind>>(
124
14.1k
                                                          CXXMemberInliningMode)
125
14.1k
    .Case("constructors", CIMK_Constructors)
126
14.1k
    .Case("destructors", CIMK_Destructors)
127
14.1k
    .Case("methods", CIMK_MemberFunctions)
128
14.1k
    .Case("none", CIMK_None)
129
14.1k
    .Default(None);
130
14.1k
131
14.1k
  assert(K.hasValue() && "Invalid c++ member function inlining mode.");
132
14.1k
133
14.1k
  return *K >= Param;
134
14.1k
}
135
136
StringRef AnalyzerOptions::getCheckerStringOption(StringRef CheckerName,
137
                                                  StringRef OptionName,
138
804
                                                  bool SearchInParents) const {
139
804
  assert(!CheckerName.empty() &&
140
804
         "Empty checker name! Make sure the checker object (including it's "
141
804
         "bases!) if fully initialized before calling this function!");
142
804
143
804
  ConfigTable::const_iterator E = Config.end();
144
878
  do {
145
878
    ConfigTable::const_iterator I =
146
878
        Config.find((Twine(CheckerName) + ":" + OptionName).str());
147
878
    if (I != E)
148
804
      return StringRef(I->getValue());
149
74
    size_t Pos = CheckerName.rfind('.');
150
74
    if (Pos == StringRef::npos)
151
0
      break;
152
74
153
74
    CheckerName = CheckerName.substr(0, Pos);
154
74
  } while (!CheckerName.empty() && SearchInParents);
155
804
156
804
  
llvm_unreachable0
("Unknown checker option! Did you call getChecker*Option "
157
804
                   "with incorrect parameters? User input must've been "
158
804
                   "verified by CheckerRegistry.");
159
804
160
804
  
return ""0
;
161
804
}
162
163
StringRef AnalyzerOptions::getCheckerStringOption(const ento::CheckerBase *C,
164
                                                  StringRef OptionName,
165
89
                                                  bool SearchInParents) const {
166
89
  return getCheckerStringOption(
167
89
                           C->getTagDescription(), OptionName, SearchInParents);
168
89
}
169
170
bool AnalyzerOptions::getCheckerBooleanOption(StringRef CheckerName,
171
                                              StringRef OptionName,
172
674
                                              bool SearchInParents) const {
173
674
  auto Ret = llvm::StringSwitch<llvm::Optional<bool>>(
174
674
      getCheckerStringOption(CheckerName, OptionName,
175
674
                             SearchInParents))
176
674
      .Case("true", true)
177
674
      .Case("false", false)
178
674
      .Default(None);
179
674
180
674
  assert(Ret &&
181
674
         "This option should be either 'true' or 'false', and should've been "
182
674
         "validated by CheckerRegistry!");
183
674
184
674
  return *Ret;
185
674
}
186
187
bool AnalyzerOptions::getCheckerBooleanOption(const ento::CheckerBase *C,
188
                                              StringRef OptionName,
189
674
                                              bool SearchInParents) const {
190
674
  return getCheckerBooleanOption(
191
674
             C->getTagDescription(), OptionName, SearchInParents);
192
674
}
193
194
int AnalyzerOptions::getCheckerIntegerOption(StringRef CheckerName,
195
                                             StringRef OptionName,
196
40
                                             bool SearchInParents) const {
197
40
  int Ret = 0;
198
40
  bool HasFailed = getCheckerStringOption(CheckerName, OptionName,
199
40
                                          SearchInParents)
200
40
                     .getAsInteger(0, Ret);
201
40
  assert(!HasFailed &&
202
40
         "This option should be numeric, and should've been validated by "
203
40
         "CheckerRegistry!");
204
40
  (void)HasFailed;
205
40
  return Ret;
206
40
}
207
208
int AnalyzerOptions::getCheckerIntegerOption(const ento::CheckerBase *C,
209
                                             StringRef OptionName,
210
40
                                             bool SearchInParents) const {
211
40
  return getCheckerIntegerOption(
212
40
                           C->getTagDescription(), OptionName, SearchInParents);
213
40
}