Coverage Report

Created: 2020-09-19 12:23

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