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

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp