brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.1 KiB · 6ba67f8 Raw
199 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains special accessors for analyzer configuration options10// 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(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(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(PadForDesc);56      continue;57    }58    FOut << C;59  }60}61 62ExplorationStrategyKind63AnalyzerOptions::getExplorationStrategy() const {64  auto K =65      llvm::StringSwitch<std::optional<ExplorationStrategyKind>>(66          ExplorationStrategy)67          .Case("dfs", ExplorationStrategyKind::DFS)68          .Case("bfs", ExplorationStrategyKind::BFS)69          .Case("unexplored_first", ExplorationStrategyKind::UnexploredFirst)70          .Case("unexplored_first_queue",71                ExplorationStrategyKind::UnexploredFirstQueue)72          .Case("unexplored_first_location_queue",73                ExplorationStrategyKind::UnexploredFirstLocationQueue)74          .Case("bfs_block_dfs_contents",75                ExplorationStrategyKind::BFSBlockDFSContents)76          .Default(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("none", CTUPhase1InliningKind::None)85               .Case("small", CTUPhase1InliningKind::Small)86               .Case("all", CTUPhase1InliningKind::All)87               .Default(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("none", IPAK_None)95               .Case("basic-inlining", IPAK_BasicInlining)96               .Case("inlining", IPAK_Inlining)97               .Case("dynamic", IPAK_DynamicDispatch)98               .Case("dynamic-bifurcate", IPAK_DynamicDispatchBifurcate)99               .Default(std::nullopt);100  assert(K && "IPA Mode is invalid.");101 102  return *K;103}104 105bool106AnalyzerOptions::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("constructors", CIMK_Constructors)114               .Case("destructors", CIMK_Destructors)115               .Case("methods", CIMK_MemberFunctions)116               .Case("none", CIMK_None)117               .Default(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((Twine(CheckerName) + ":" + OptionName).str());135    if (I != E)136      return StringRef(I->getValue());137    size_t Pos = CheckerName.rfind('.');138    if (Pos == StringRef::npos)139      break;140 141    CheckerName = CheckerName.substr(0, 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(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("true", true)164          .Case("false", false)165          .Default(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(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(0, 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(C->getName(), OptionName, SearchInParents);198}199