Coverage Report

Created: 2020-02-25 14:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/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
void AnalyzerOptions::printFormattedEntry(
34
    llvm::raw_ostream &Out,
35
    std::pair<StringRef, StringRef> EntryDescPair,
36
1.10k
    size_t InitialPad, size_t EntryWidth, size_t MinLineWidth) {
37
1.10k
38
1.10k
  llvm::formatted_raw_ostream FOut(Out);
39
1.10k
40
1.10k
  const size_t PadForDesc = InitialPad + EntryWidth;
41
1.10k
42
1.10k
  FOut.PadToColumn(InitialPad) << EntryDescPair.first;
43
1.10k
  // If the buffer's length is greater then PadForDesc, print a newline.
44
1.10k
  if (FOut.getColumn() > PadForDesc)
45
0
    FOut << '\n';
46
1.10k
47
1.10k
  FOut.PadToColumn(PadForDesc);
48
1.10k
49
1.10k
  if (MinLineWidth == 0) {
50
884
    FOut << EntryDescPair.second;
51
884
    return;
52
884
  }
53
220
54
29.7k
  
for (char C : EntryDescPair.second)220
{
55
29.7k
    if (FOut.getColumn() > MinLineWidth && 
C == ' '0
) {
56
0
      FOut << '\n';
57
0
      FOut.PadToColumn(PadForDesc);
58
0
      continue;
59
0
    }
60
29.7k
    FOut << C;
61
29.7k
  }
62
220
}
63
64
ExplorationStrategyKind
65
12.6k
AnalyzerOptions::getExplorationStrategy() const {
66
12.6k
  auto K =
67
12.6k
    llvm::StringSwitch<llvm::Optional<ExplorationStrategyKind>>(
68
12.6k
                                                            ExplorationStrategy)
69
12.6k
          .Case("dfs", ExplorationStrategyKind::DFS)
70
12.6k
          .Case("bfs", ExplorationStrategyKind::BFS)
71
12.6k
          .Case("unexplored_first",
72
12.6k
                ExplorationStrategyKind::UnexploredFirst)
73
12.6k
          .Case("unexplored_first_queue",
74
12.6k
                ExplorationStrategyKind::UnexploredFirstQueue)
75
12.6k
          .Case("unexplored_first_location_queue",
76
12.6k
                ExplorationStrategyKind::UnexploredFirstLocationQueue)
77
12.6k
          .Case("bfs_block_dfs_contents",
78
12.6k
                ExplorationStrategyKind::BFSBlockDFSContents)
79
12.6k
          .Default(None);
80
12.6k
  assert(K.hasValue() && "User mode is invalid.");
81
12.6k
  return K.getValue();
82
12.6k
}
83
84
239k
IPAKind AnalyzerOptions::getIPAMode() const {
85
239k
  auto K = llvm::StringSwitch<llvm::Optional<IPAKind>>(IPAMode)
86
239k
          .Case("none", IPAK_None)
87
239k
          .Case("basic-inlining", IPAK_BasicInlining)
88
239k
          .Case("inlining", IPAK_Inlining)
89
239k
          .Case("dynamic", IPAK_DynamicDispatch)
90
239k
          .Case("dynamic-bifurcate", IPAK_DynamicDispatchBifurcate)
91
239k
          .Default(None);
92
239k
  assert(K.hasValue() && "IPA Mode is invalid.");
93
239k
94
239k
  return K.getValue();
95
239k
}
96
97
bool
98
AnalyzerOptions::mayInlineCXXMemberFunction(
99
41.7k
                                          CXXInlineableMemberKind Param) const {
100
41.7k
  if (getIPAMode() < IPAK_Inlining)
101
0
    return false;
102
41.7k
103
41.7k
  auto K =
104
41.7k
    llvm::StringSwitch<llvm::Optional<CXXInlineableMemberKind>>(
105
41.7k
                                                          CXXMemberInliningMode)
106
41.7k
    .Case("constructors", CIMK_Constructors)
107
41.7k
    .Case("destructors", CIMK_Destructors)
108
41.7k
    .Case("methods", CIMK_MemberFunctions)
109
41.7k
    .Case("none", CIMK_None)
110
41.7k
    .Default(None);
111
41.7k
112
41.7k
  assert(K.hasValue() && "Invalid c++ member function inlining mode.");
113
41.7k
114
41.7k
  return *K >= Param;
115
41.7k
}
116
117
StringRef AnalyzerOptions::getCheckerStringOption(StringRef CheckerName,
118
                                                  StringRef OptionName,
119
1.04k
                                                  bool SearchInParents) const {
120
1.04k
  assert(!CheckerName.empty() &&
121
1.04k
         "Empty checker name! Make sure the checker object (including it's "
122
1.04k
         "bases!) if fully initialized before calling this function!");
123
1.04k
124
1.04k
  ConfigTable::const_iterator E = Config.end();
125
1.14k
  do {
126
1.14k
    ConfigTable::const_iterator I =
127
1.14k
        Config.find((Twine(CheckerName) + ":" + OptionName).str());
128
1.14k
    if (I != E)
129
1.04k
      return StringRef(I->getValue());
130
102
    size_t Pos = CheckerName.rfind('.');
131
102
    if (Pos == StringRef::npos)
132
0
      break;
133
102
134
102
    CheckerName = CheckerName.substr(0, Pos);
135
102
  } while (!CheckerName.empty() && SearchInParents);
136
1.04k
137
1.04k
  
llvm_unreachable0
("Unknown checker option! Did you call getChecker*Option "
138
1.04k
                   "with incorrect parameters? User input must've been "
139
1.04k
                   "verified by CheckerRegistry.");
140
1.04k
141
1.04k
  
return ""0
;
142
1.04k
}
143
144
StringRef AnalyzerOptions::getCheckerStringOption(const ento::CheckerBase *C,
145
                                                  StringRef OptionName,
146
123
                                                  bool SearchInParents) const {
147
123
  return getCheckerStringOption(
148
123
                           C->getTagDescription(), OptionName, SearchInParents);
149
123
}
150
151
bool AnalyzerOptions::getCheckerBooleanOption(StringRef CheckerName,
152
                                              StringRef OptionName,
153
883
                                              bool SearchInParents) const {
154
883
  auto Ret = llvm::StringSwitch<llvm::Optional<bool>>(
155
883
      getCheckerStringOption(CheckerName, OptionName,
156
883
                             SearchInParents))
157
883
      .Case("true", true)
158
883
      .Case("false", false)
159
883
      .Default(None);
160
883
161
883
  assert(Ret &&
162
883
         "This option should be either 'true' or 'false', and should've been "
163
883
         "validated by CheckerRegistry!");
164
883
165
883
  return *Ret;
166
883
}
167
168
bool AnalyzerOptions::getCheckerBooleanOption(const ento::CheckerBase *C,
169
                                              StringRef OptionName,
170
869
                                              bool SearchInParents) const {
171
869
  return getCheckerBooleanOption(
172
869
             C->getTagDescription(), OptionName, SearchInParents);
173
869
}
174
175
int AnalyzerOptions::getCheckerIntegerOption(StringRef CheckerName,
176
                                             StringRef OptionName,
177
40
                                             bool SearchInParents) const {
178
40
  int Ret = 0;
179
40
  bool HasFailed = getCheckerStringOption(CheckerName, OptionName,
180
40
                                          SearchInParents)
181
40
                     .getAsInteger(0, Ret);
182
40
  assert(!HasFailed &&
183
40
         "This option should be numeric, and should've been validated by "
184
40
         "CheckerRegistry!");
185
40
  (void)HasFailed;
186
40
  return Ret;
187
40
}
188
189
int AnalyzerOptions::getCheckerIntegerOption(const ento::CheckerBase *C,
190
                                             StringRef OptionName,
191
40
                                             bool SearchInParents) const {
192
40
  return getCheckerIntegerOption(
193
40
                           C->getTagDescription(), OptionName, SearchInParents);
194
40
}