[analyzer] Evaluate all non-checker config options before analysis

In earlier patches regarding AnalyzerOptions, a lot of effort went into
gathering all config options, and changing the interface so that potential
misuse can be eliminited.

Up until this point, AnalyzerOptions only evaluated an option when it was
querried. For example, if we had a "-no-false-positives" flag, AnalyzerOptions
would store an Optional field for it that would be None up until somewhere in
the code until the flag's getter function is called.

However, now that we're confident that we've gathered all configs, we can
evaluate off of them before analysis, so we can emit a error on invalid input
even if that prticular flag will not matter in that particular run of the
analyzer. Another very big benefit of this is that debug.ConfigDumper will now
show the value of all configs every single time.

Also, almost all options related class have a similar interface, so uniformity
is also a benefit.

The implementation for errors on invalid input will be commited shorty.

Differential Revision: https://reviews.llvm.org/D53692

llvm-svn: 348031
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index f511fdc..f90e930 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -181,6 +181,9 @@
   }
 }
 
+static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts,
+                                 DiagnosticsEngine &Diags);
+
 static void getAllNoBuiltinFuncValues(ArgList &Args,
                                       std::vector<std::string> &Funcs) {
   SmallVector<const char *, 8> Values;
@@ -343,6 +346,8 @@
     }
   }
 
+  parseAnalyzerConfigs(Opts, Diags);
+
   llvm::raw_string_ostream os(Opts.FullCompilerInvocation);
   for (unsigned i = 0; i < Args.getNumInputArgStrings(); ++i) {
     if (i != 0)
@@ -354,6 +359,64 @@
   return Success;
 }
 
+static StringRef getStringOption(AnalyzerOptions::ConfigTable &Config,
+                                 StringRef OptionName, StringRef DefaultVal) {
+  return Config.insert({OptionName, DefaultVal}).first->second;
+}
+
+static void initOption(AnalyzerOptions::ConfigTable &Config,
+                       StringRef &OptionField, StringRef Name,
+                       StringRef DefaultVal) {
+  OptionField = getStringOption(Config, Name, DefaultVal);
+}
+
+static void initOption(AnalyzerOptions::ConfigTable &Config,
+                       bool &OptionField, StringRef Name, bool DefaultVal) {
+  // FIXME: We should emit a warning here if the value is something other than
+  // "true", "false", or the empty string (meaning the default value),
+  // but the AnalyzerOptions doesn't have access to a diagnostic engine.
+  OptionField = llvm::StringSwitch<bool>(getStringOption(Config, Name,
+                                               (DefaultVal ? "true" : "false")))
+      .Case("true", true)
+      .Case("false", false)
+      .Default(DefaultVal);
+}
+
+static void initOption(AnalyzerOptions::ConfigTable &Config,
+                       unsigned &OptionField, StringRef Name,
+                       unsigned DefaultVal) {
+  OptionField = DefaultVal;
+  bool HasFailed = getStringOption(Config, Name, std::to_string(DefaultVal))
+                     .getAsInteger(10, OptionField);
+  assert(!HasFailed && "analyzer-config option should be numeric");
+  (void)HasFailed;
+}
+
+static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts,
+                                 DiagnosticsEngine &Diags) {
+  // TODO: Emit warnings for incorrect options.
+  // TODO: There's no need to store the entire configtable, it'd be plenty
+  // enough tostore checker options.
+
+#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)                \
+  initOption(AnOpts.Config, AnOpts.NAME, CMDFLAG, DEFAULT_VAL);                \
+
+#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC,        \
+                                           SHALLOW_VAL, DEEP_VAL)              \
+  switch (AnOpts.getUserMode()) {                                              \
+  case UMK_Shallow:                                                            \
+    initOption(AnOpts.Config, AnOpts.NAME, CMDFLAG, SHALLOW_VAL);              \
+    break;                                                                     \
+  case UMK_Deep:                                                               \
+    initOption(AnOpts.Config, AnOpts.NAME, CMDFLAG, DEEP_VAL);                 \
+    break;                                                                     \
+  }                                                                            \
+
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
+#undef ANALYZER_OPTION
+#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
+}
+
 static bool ParseMigratorArgs(MigratorOptions &Opts, ArgList &Args) {
   Opts.NoNSAllocReallocError = Args.hasArg(OPT_migrator_no_nsalloc_error);
   Opts.NoFinalizeRemoval = Args.hasArg(OPT_migrator_no_finalize_removal);
diff --git a/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp b/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
index 810a33e..60027f4 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
@@ -182,7 +182,9 @@
 
     llvm::errs() << "[config]\n";
     for (unsigned I = 0, E = Keys.size(); I != E; ++I)
-      llvm::errs() << Keys[I]->getKey() << " = " << Keys[I]->second << '\n';
+      llvm::errs() << Keys[I]->getKey() << " = "
+                   << (Keys[I]->second.empty() ? "\"\"" : Keys[I]->second)
+                   << '\n';
 
     llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n';
   }
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index c2b4e13..982c2f3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1094,7 +1094,7 @@
 
 void MallocChecker::checkPostStmt(const CXXNewExpr *NE,
                                   CheckerContext &C) const {
-  if (!C.getAnalysisManager().getAnalyzerOptions().mayInlineCXXAllocator())
+  if (!C.getAnalysisManager().getAnalyzerOptions().MayInlineCXXAllocator)
     processNewAllocation(NE, C, C.getSVal(NE));
 }
 
diff --git a/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp b/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp
index 5f45d26..7fb1c09 100644
--- a/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp
@@ -22,16 +22,21 @@
                                  AnalyzerOptions &Options,
                                  CodeInjector *injector)
     : AnaCtxMgr(
-          ASTCtx, Options.UnoptimizedCFG, Options.includeImplicitDtorsInCFG(),
-          /*AddInitializers=*/true, Options.includeTemporaryDtorsInCFG(),
-          Options.includeLifetimeInCFG(),
+          ASTCtx, Options.UnoptimizedCFG,
+          Options.ShouldIncludeImplicitDtorsInCFG,
+          /*AddInitializers=*/true,
+          Options.ShouldIncludeTemporaryDtorsInCFG,
+          Options.ShouldIncludeLifetimeInCFG,
           // Adding LoopExit elements to the CFG is a requirement for loop
           // unrolling.
-          Options.includeLoopExitInCFG() || Options.shouldUnrollLoops(),
-          Options.includeScopesInCFG(), Options.shouldSynthesizeBodies(),
-          Options.shouldConditionalizeStaticInitializers(),
-          /*addCXXNewAllocator=*/true, Options.includeRichConstructorsInCFG(),
-          Options.shouldElideConstructors(), injector),
+          Options.ShouldIncludeLoopExitInCFG ||
+            Options.ShouldUnrollLoops,
+          Options.ShouldIncludeScopesInCFG,
+          Options.ShouldSynthesizeBodies,
+          Options.ShouldConditionalizeStaticInitializers,
+          /*addCXXNewAllocator=*/true,
+          Options.ShouldIncludeRichConstructorsInCFG,
+          Options.ShouldElideConstructors, injector),
       Ctx(ASTCtx), Diags(diags), LangOpts(ASTCtx.getLangOpts()),
       PathConsumers(PDC), CreateStoreMgr(storemgr),
       CreateConstraintMgr(constraintmgr), CheckerMgr(checkerMgr),
diff --git a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
index 025deda..d9b63c2 100644
--- a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
+++ b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
@@ -49,28 +49,11 @@
   return Result;
 }
 
-UserModeKind AnalyzerOptions::getUserMode() {
-  if (!UserMode.hasValue()) {
-    UserMode = getStringOption("mode", "deep");
-  }
-
-  auto K = llvm::StringSwitch<llvm::Optional<UserModeKind>>(*UserMode)
-    .Case("shallow", UMK_Shallow)
-    .Case("deep", UMK_Deep)
-    .Default(None);
-  assert(UserMode.hasValue() && "User mode is invalid.");
-  return K.getValue();
-}
-
 ExplorationStrategyKind
-AnalyzerOptions::getExplorationStrategy() {
-  if (!ExplorationStrategy.hasValue()) {
-    ExplorationStrategy = getStringOption("exploration_strategy",
-                                            "unexplored_first_queue");
-  }
+AnalyzerOptions::getExplorationStrategy() const {
   auto K =
     llvm::StringSwitch<llvm::Optional<ExplorationStrategyKind>>(
-                                                           *ExplorationStrategy)
+                                                            ExplorationStrategy)
           .Case("dfs", ExplorationStrategyKind::DFS)
           .Case("bfs", ExplorationStrategyKind::BFS)
           .Case("unexplored_first",
@@ -86,18 +69,8 @@
   return K.getValue();
 }
 
-IPAKind AnalyzerOptions::getIPAMode() {
-  if (!IPAMode.hasValue()) {
-    switch (getUserMode()) {
-    case UMK_Shallow:
-      IPAMode = getStringOption("ipa", "inlining");
-      break;
-    case UMK_Deep:
-      IPAMode = getStringOption("ipa", "dynamic-bifurcate");
-      break;
-    }
-  }
-  auto K = llvm::StringSwitch<llvm::Optional<IPAKind>>(*IPAMode)
+IPAKind AnalyzerOptions::getIPAMode() const {
+  auto K = llvm::StringSwitch<llvm::Optional<IPAKind>>(IPAMode)
           .Case("none", IPAK_None)
           .Case("basic-inlining", IPAK_BasicInlining)
           .Case("inlining", IPAK_Inlining)
@@ -110,17 +83,14 @@
 }
 
 bool
-AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind Param) {
-  if (!CXXMemberInliningMode.hasValue()) {
-    CXXMemberInliningMode = getStringOption("c++-inlining", "destructors");
-  }
-
+AnalyzerOptions::mayInlineCXXMemberFunction(
+                                          CXXInlineableMemberKind Param) const {
   if (getIPAMode() < IPAK_Inlining)
     return false;
 
   auto K =
     llvm::StringSwitch<llvm::Optional<CXXInlineableMemberKind>>(
-                                                         *CXXMemberInliningMode)
+                                                          CXXMemberInliningMode)
     .Case("constructors", CIMK_Constructors)
     .Case("destructors", CIMK_Destructors)
     .Case("methods", CIMK_MemberFunctions)
@@ -132,50 +102,6 @@
   return *K >= Param;
 }
 
-StringRef AnalyzerOptions::getStringOption(StringRef OptionName,
-                                           StringRef DefaultVal) {
-  return Config.insert({OptionName, DefaultVal}).first->second;
-}
-
-static StringRef toString(bool B) { return (B ? "true" : "false"); }
-
-template <typename T>
-static StringRef toString(T) = delete;
-
-void AnalyzerOptions::initOption(Optional<StringRef> &V, StringRef Name,
-                                                         StringRef DefaultVal) {
-  if (V.hasValue())
-    return;
-
-  V = getStringOption(Name, DefaultVal);
-}
-
-void AnalyzerOptions::initOption(Optional<bool> &V, StringRef Name,
-                                                    bool DefaultVal) {
-  if (V.hasValue())
-    return;
-
-  // FIXME: We should emit a warning here if the value is something other than
-  // "true", "false", or the empty string (meaning the default value),
-  // but the AnalyzerOptions doesn't have access to a diagnostic engine.
-  V = llvm::StringSwitch<bool>(getStringOption(Name, toString(DefaultVal)))
-      .Case("true", true)
-      .Case("false", false)
-      .Default(DefaultVal);
-}
-
-void AnalyzerOptions::initOption(Optional<unsigned> &V, StringRef Name,
-                                                        unsigned DefaultVal) {
-  if (V.hasValue())
-    return;
-
-  V = DefaultVal;
-  bool HasFailed = getStringOption(Name, std::to_string(DefaultVal))
-                     .getAsInteger(10, *V);
-  assert(!HasFailed && "analyzer-config option should be numeric");
-  (void)HasFailed;
-}
-
 StringRef AnalyzerOptions::getCheckerStringOption(StringRef OptionName,
                                                   StringRef DefaultVal,
                                                   const CheckerBase *C,
@@ -210,7 +136,8 @@
   // but the AnalyzerOptions doesn't have access to a diagnostic engine.
   assert(C);
   return llvm::StringSwitch<bool>(
-      getCheckerStringOption(Name, toString(DefaultVal), C, SearchInParents))
+      getCheckerStringOption(Name, DefaultVal ? "true" : "false", C,
+                             SearchInParents))
       .Case("true", true)
       .Case("false", false)
       .Default(DefaultVal);
@@ -227,12 +154,3 @@
   (void)HasFailed;
   return Ret;
 }
-
-StringRef AnalyzerOptions::getCTUDir() {
-  if (!CTUDir.hasValue()) {
-    CTUDir = getStringOption("ctu-dir", "");
-    if (!llvm::sys::fs::is_directory(*CTUDir))
-      CTUDir = "";
-  }
-  return CTUDir.getValue();
-}
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
index 2b6bbeb..f84b6e6 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -1976,7 +1976,7 @@
 
   // Finally, prune the diagnostic path of uninteresting stuff.
   if (!PD->path.empty()) {
-    if (R->shouldPrunePath() && Opts.shouldPrunePaths()) {
+    if (R->shouldPrunePath() && Opts.ShouldPrunePaths) {
       bool stillHasNotes =
           removeUnneededCalls(PD->getMutablePieces(), R, LCM);
       assert(stillHasNotes);
@@ -2007,7 +2007,7 @@
     removeEdgesToDefaultInitializers(PD->getMutablePieces());
   }
 
-  if (GenerateDiagnostics && Opts.shouldDisplayMacroExpansions())
+  if (GenerateDiagnostics && Opts.ShouldDisplayMacroExpansions)
     CompactMacroExpandedPieces(PD->getMutablePieces(), SM);
 
   return PD;
@@ -2621,7 +2621,7 @@
         generateVisitorsDiagnostics(R, ErrorNode, BRC);
 
     if (R->isValid()) {
-      if (Opts.shouldCrosscheckWithZ3()) {
+      if (Opts.ShouldCrosscheckWithZ3) {
         // If crosscheck is enabled, remove all visitors, add the refutation
         // visitor and check again
         R->clearVisitors();
@@ -2963,7 +2963,7 @@
     }
 
     PathPieces &Pieces = PD->getMutablePieces();
-    if (getAnalyzerOptions().shouldDisplayNotesAsEvents()) {
+    if (getAnalyzerOptions().ShouldDisplayNotesAsEvents) {
       // For path diagnostic consumers that don't support extra notes,
       // we may optionally convert those to path notes.
       for (auto I = report->getNotes().rbegin(),
@@ -3100,7 +3100,7 @@
   // report location to the last piece in the main source file.
   AnalyzerOptions &Opts = getAnalyzerOptions();
   for (auto const &P : *Out)
-    if (Opts.shouldReportIssuesInMainSourceFile() && !Opts.AnalyzeAll)
+    if (Opts.ShouldReportIssuesInMainSourceFile && !Opts.AnalyzeAll)
       P.second->resetDiagnosticLocationToMainFile();
 
   return Out;
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 99069d8..da94b6e 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -676,8 +676,8 @@
         bool EnableNullFPSuppression, BugReport &BR,
         const SVal V) {
     AnalyzerOptions &Options = N->getState()->getAnalysisManager().options;
-    if (EnableNullFPSuppression && Options.shouldSuppressNullReturnPaths()
-          && V.getAs<Loc>())
+    if (EnableNullFPSuppression &&
+        Options.ShouldSuppressNullReturnPaths && V.getAs<Loc>())
       BR.addVisitor(llvm::make_unique<MacroNullReturnSuppressionVisitor>(
               R->getAs<SubRegion>(), V));
   }
@@ -808,7 +808,8 @@
     AnalyzerOptions &Options = State->getAnalysisManager().options;
 
     bool EnableNullFPSuppression = false;
-    if (InEnableNullFPSuppression && Options.shouldSuppressNullReturnPaths())
+    if (InEnableNullFPSuppression &&
+        Options.ShouldSuppressNullReturnPaths)
       if (Optional<Loc> RetLoc = RetVal.getAs<Loc>())
         EnableNullFPSuppression = State->isNull(*RetLoc).isConstrainedTrue();
 
@@ -877,7 +878,7 @@
         // future nodes. We want to emit a path note as well, in case
         // the report is resurrected as valid later on.
         if (EnableNullFPSuppression &&
-            Options.shouldAvoidSuppressingNullArgumentPaths())
+            Options.ShouldAvoidSuppressingNullArgumentPaths)
           Mode = MaybeUnsuppress;
 
         if (RetE->getType()->isObjCObjectPointerType()) {
@@ -925,7 +926,7 @@
   visitNodeMaybeUnsuppress(const ExplodedNode *N,
                            BugReporterContext &BRC, BugReport &BR) {
 #ifndef NDEBUG
-    assert(Options.shouldAvoidSuppressingNullArgumentPaths());
+    assert(Options.ShouldAvoidSuppressingNullArgumentPaths);
 #endif
 
     // Are we at the entry node for this call?
@@ -1378,7 +1379,7 @@
     : V(Value) {
   // Check if the visitor is disabled.
   AnalyzerOptions &Options = N->getState()->getAnalysisManager().options;
-  if (!Options.shouldSuppressInlinedDefensiveChecks())
+  if (!Options.ShouldSuppressInlinedDefensiveChecks)
     IsSatisfied = true;
 
   assert(N->getState()->isNull(V).isConstrainedTrue() &&
@@ -2219,7 +2220,7 @@
     // the user's fault, we currently don't report them very well, and
     // Note that this will not help for any other data structure libraries, like
     // TR1, Boost, or llvm/ADT.
-    if (Options.shouldSuppressFromCXXStandardLibrary()) {
+    if (Options.ShouldSuppressFromCXXStandardLibrary) {
       BR.markInvalid(getTag(), nullptr);
       return;
     } else {
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index e0759d1..6f90ea0 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -554,13 +554,14 @@
   AnalyzerOptions &Opts = Engine->getAnalysisManager().options;
 
   // Try to get CTU definition only if CTUDir is provided.
-  if (!Opts.naiveCTUEnabled())
+  if (!Opts.IsNaiveCTUEnabled)
     return {};
 
   cross_tu::CrossTranslationUnitContext &CTUCtx =
       *Engine->getCrossTranslationUnitContext();
   llvm::Expected<const FunctionDecl *> CTUDeclOrError =
-      CTUCtx.getCrossTUDefinition(FD, Opts.getCTUDir(), Opts.getCTUIndexName());
+      CTUCtx.getCrossTUDefinition(FD, Opts.CTUDir,
+                                  Opts.CTUIndexName);
 
   if (!CTUDeclOrError) {
     handleAllErrors(CTUDeclOrError.takeError(),
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 49ddf1a..fa5a619 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -193,7 +193,7 @@
       svalBuilder(StateMgr.getSValBuilder()), ObjCNoRet(mgr.getASTContext()),
       BR(mgr, *this),
       VisitedCallees(VisitedCalleesIn), HowToInline(HowToInlineIn) {
-  unsigned TrimInterval = mgr.options.getGraphTrimInterval();
+  unsigned TrimInterval = mgr.options.GraphTrimInterval;
   if (TrimInterval != 0) {
     // Enable eager node reclaimation when constructing the ExplodedGraph.
     G.enableNodeReclamation(TrimInterval);
@@ -746,7 +746,7 @@
   NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
   ProgramStateRef NewState = Pred->getState();
 
-  if(AMgr.options.shouldUnrollLoops())
+  if(AMgr.options.ShouldUnrollLoops)
     NewState = processLoopEnd(S, NewState);
 
   LoopExit PP(S, Pred->getLocationContext());
@@ -878,7 +878,7 @@
   // TODO: We're not evaluating allocators for all cases just yet as
   // we're not handling the return value correctly, which causes false
   // positives when the alpha.cplusplus.NewDeleteLeaks check is on.
-  if (Opts.mayInlineCXXAllocator())
+  if (Opts.MayInlineCXXAllocator)
     VisitCXXNewAllocatorCall(NE, Pred, Dst);
   else {
     NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
@@ -1093,7 +1093,7 @@
   // This is a fallback solution in case we didn't have a construction
   // context when we were constructing the temporary. Otherwise the map should
   // have been populated there.
-  if (!getAnalysisManager().options.includeTemporaryDtorsInCFG()) {
+  if (!getAnalysisManager().options.ShouldIncludeTemporaryDtorsInCFG) {
     // In case we don't have temporary destructors in the CFG, do not mark
     // the initialization - we would otherwise never clean it up.
     Dst = PreVisit;
@@ -1454,7 +1454,7 @@
       break;
 
     case Stmt::LambdaExprClass:
-      if (AMgr.options.shouldInlineLambdas()) {
+      if (AMgr.options.ShouldInlineLambdas) {
         Bldr.takeNodes(Pred);
         VisitLambdaExpr(cast<LambdaExpr>(S), Pred, Dst);
         Bldr.addNodes(Dst);
@@ -1483,7 +1483,7 @@
 
       Bldr.takeNodes(Pred);
 
-      if (AMgr.options.shouldEagerlyAssume() &&
+      if (AMgr.options.ShouldEagerlyAssume &&
           (B->isRelationalOp() || B->isEqualityOp())) {
         ExplodedNodeSet Tmp;
         VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
@@ -1747,7 +1747,7 @@
     case Stmt::UnaryOperatorClass: {
       Bldr.takeNodes(Pred);
       const auto *U = cast<UnaryOperator>(S);
-      if (AMgr.options.shouldEagerlyAssume() && (U->getOpcode() == UO_LNot)) {
+      if (AMgr.options.ShouldEagerlyAssume && (U->getOpcode() == UO_LNot)) {
         ExplodedNodeSet Tmp;
         VisitUnaryOperator(U, Pred, Tmp);
         evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U);
@@ -1848,7 +1848,7 @@
   PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
   // If we reach a loop which has a known bound (and meets
   // other constraints) then consider completely unrolling it.
-  if(AMgr.options.shouldUnrollLoops()) {
+  if(AMgr.options.ShouldUnrollLoops) {
     unsigned maxBlockVisitOnPath = AMgr.options.maxBlockVisitOnPath;
     const Stmt *Term = nodeBuilder.getContext().getBlock()->getTerminator();
     if (Term) {
@@ -1870,7 +1870,7 @@
   // maximum number of times, widen the loop.
   unsigned int BlockCount = nodeBuilder.getContext().blockCount();
   if (BlockCount == AMgr.options.maxBlockVisitOnPath - 1 &&
-      AMgr.options.shouldWidenLoops()) {
+      AMgr.options.ShouldWidenLoops) {
     const Stmt *Term = nodeBuilder.getContext().getBlock()->getTerminator();
     if (!(Term &&
           (isa<ForStmt>(Term) || isa<WhileStmt>(Term) || isa<DoStmt>(Term))))
@@ -2371,7 +2371,7 @@
     const auto *DeclRefEx = dyn_cast<DeclRefExpr>(Ex);
     Optional<std::pair<SVal, QualType>> VInfo;
 
-    if (AMgr.options.shouldInlineLambdas() && DeclRefEx &&
+    if (AMgr.options.ShouldInlineLambdas && DeclRefEx &&
         DeclRefEx->refersToEnclosingVariableOrCapture() && MD &&
         MD->getParent()->isLambda()) {
       // Lookup the field of the lambda.
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 01606d1..1f64976 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -159,7 +159,7 @@
       return std::make_pair(State, FieldVal);
     }
     case ConstructionContext::NewAllocatedObjectKind: {
-      if (AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) {
+      if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
         const auto *NECC = cast<NewAllocatedObjectConstructionContext>(CC);
         const auto *NE = NECC->getCXXNewExpr();
         SVal V = *getObjectUnderConstruction(State, NE, LCtx);
@@ -210,7 +210,7 @@
       llvm_unreachable("Unhandled return value construction context!");
     }
     case ConstructionContext::ElidedTemporaryObjectKind: {
-      assert(AMgr.getAnalyzerOptions().shouldElideConstructors());
+      assert(AMgr.getAnalyzerOptions().ShouldElideConstructors);
       const auto *TCC = cast<ElidedTemporaryObjectConstructionContext>(CC);
       const CXXBindTemporaryExpr *BTE = TCC->getCXXBindTemporaryExpr();
       const MaterializeTemporaryExpr *MTE = TCC->getMaterializedTemporaryExpr();
@@ -706,7 +706,7 @@
   ProgramStateRef State = Pred->getState();
 
   // Retrieve the stored operator new() return value.
-  if (AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) {
+  if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
     symVal = *getObjectUnderConstruction(State, CNE, LCtx);
     State = finishObjectConstruction(State, CNE, LCtx);
   }
@@ -726,7 +726,7 @@
   CallEventRef<CXXAllocatorCall> Call =
     CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
 
-  if (!AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) {
+  if (!AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
     // Invalidate placement args.
     // FIXME: Once we figure out how we want allocators to work,
     // we should be using the usual pre-/(default-)eval-/post-call checks here.
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 66cbeba..758195d 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -349,7 +349,7 @@
                                                         /*WasInlined=*/true);
     } else if (CE &&
                !(isa<CXXNewExpr>(CE) && // Called when visiting CXXNewExpr.
-                 AMgr.getAnalyzerOptions().mayInlineCXXAllocator())) {
+                 AMgr.getAnalyzerOptions().MayInlineCXXAllocator)) {
       getCheckerManager().runCheckersForPostStmt(Dst, DstPostCall, CE,
                                                  *this, /*WasInlined=*/true);
     } else {
@@ -386,7 +386,7 @@
       // Do not count the small functions when determining the stack depth.
       AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(DI);
       const CFG *CalleeCFG = CalleeADC->getCFG();
-      if (CalleeCFG->getNumBlockIDs() > AMgr.options.getAlwaysInlineSize())
+      if (CalleeCFG->getNumBlockIDs() > AMgr.options.AlwaysInlineSize)
         ++StackDepth;
     }
     LCtx = LCtx->getParent();
@@ -683,7 +683,7 @@
                                         : nullptr;
 
     if (CC && isa<NewAllocatedObjectConstructionContext>(CC) &&
-        !Opts.mayInlineCXXAllocator())
+        !Opts.MayInlineCXXAllocator)
       return CIP_DisallowedOnce;
 
     // FIXME: We don't handle constructors or destructors for arrays properly.
@@ -712,7 +712,7 @@
       // If we don't handle temporary destructors, we shouldn't inline
       // their constructors.
       if (CallOpts.IsTemporaryCtorOrDtor &&
-          !Opts.includeTemporaryDtorsInCFG())
+          !Opts.ShouldIncludeTemporaryDtorsInCFG)
         return CIP_DisallowedOnce;
 
       // If we did not find the correct this-region, it would be pointless
@@ -743,7 +743,8 @@
       return CIP_DisallowedOnce;
 
     // Allow disabling temporary destructor inlining with a separate option.
-    if (CallOpts.IsTemporaryCtorOrDtor && !Opts.mayInlineCXXTemporaryDtors())
+    if (CallOpts.IsTemporaryCtorOrDtor &&
+        !Opts.MayInlineCXXTemporaryDtors)
       return CIP_DisallowedOnce;
 
     // If we did not find the correct this-region, it would be pointless
@@ -754,13 +755,13 @@
     break;
   }
   case CE_CXXAllocator:
-    if (Opts.mayInlineCXXAllocator())
+    if (Opts.MayInlineCXXAllocator)
       break;
     // Do not inline allocators until we model deallocators.
     // This is unfortunate, but basically necessary for smart pointers and such.
     return CIP_DisallowedAlways;
   case CE_ObjCMessage:
-    if (!Opts.mayInlineObjCMethod())
+    if (!Opts.MayInlineObjCMethod)
       return CIP_DisallowedAlways;
     if (!(Opts.getIPAMode() == IPAK_DynamicDispatch ||
           Opts.getIPAMode() == IPAK_DynamicDispatchBifurcate))
@@ -844,19 +845,19 @@
   if (Ctx.getLangOpts().CPlusPlus) {
     if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeADC->getDecl())) {
       // Conditionally control the inlining of template functions.
-      if (!Opts.mayInlineTemplateFunctions())
+      if (!Opts.MayInlineTemplateFunctions)
         if (FD->getTemplatedKind() != FunctionDecl::TK_NonTemplate)
           return false;
 
       // Conditionally control the inlining of C++ standard library functions.
-      if (!Opts.mayInlineCXXStandardLibrary())
+      if (!Opts.MayInlineCXXStandardLibrary)
         if (Ctx.getSourceManager().isInSystemHeader(FD->getLocation()))
           if (AnalysisDeclContext::isInStdNamespace(FD))
             return false;
 
       // Conditionally control the inlining of methods on objects that look
       // like C++ containers.
-      if (!Opts.mayInlineCXXContainerMethods())
+      if (!Opts.MayInlineCXXContainerMethods)
         if (!AMgr.isInCodeFile(FD->getLocation()))
           if (isContainerMethod(Ctx, FD))
             return false;
@@ -865,7 +866,7 @@
       // We don't currently do a good job modeling shared_ptr because we can't
       // see the reference count, so treating as opaque is probably the best
       // idea.
-      if (!Opts.mayInlineCXXSharedPtrDtor())
+      if (!Opts.MayInlineCXXSharedPtrDtor)
         if (isCXXSharedPtrDtor(FD))
           return false;
     }
@@ -878,7 +879,7 @@
     return false;
 
   // Do not inline large functions.
-  if (CalleeCFG->getNumBlockIDs() > Opts.getMaxInlinableSize())
+  if (CalleeCFG->getNumBlockIDs() > Opts.MaxInlinableSize)
     return false;
 
   // It is possible that the live variables analysis cannot be
@@ -946,21 +947,21 @@
   unsigned StackDepth = 0;
   examineStackFrames(D, Pred->getLocationContext(), IsRecursive, StackDepth);
   if ((StackDepth >= Opts.InlineMaxStackDepth) &&
-      ((CalleeCFG->getNumBlockIDs() > Opts.getAlwaysInlineSize())
+      ((CalleeCFG->getNumBlockIDs() > Opts.AlwaysInlineSize)
        || IsRecursive))
     return false;
 
   // Do not inline large functions too many times.
   if ((Engine.FunctionSummaries->getNumTimesInlined(D) >
-       Opts.getMaxTimesInlineLarge()) &&
+       Opts.MaxTimesInlineLarge) &&
        CalleeCFG->getNumBlockIDs() >=
-       Opts.getMinCFGSizeTreatFunctionsAsLarge()) {
+       Opts.MinCFGSizeTreatFunctionsAsLarge) {
     NumReachedInlineCountMax++;
     return false;
   }
 
   if (HowToInline == Inline_Minimal &&
-      (CalleeCFG->getNumBlockIDs() > Opts.getAlwaysInlineSize()
+      (CalleeCFG->getNumBlockIDs() > Opts.AlwaysInlineSize
       || IsRecursive))
     return false;
 
diff --git a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index d5764a4..fc82f11 100644
--- a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -218,7 +218,7 @@
   int FD;
   SmallString<128> Model, ResultPath;
 
-  if (!AnalyzerOpts.shouldWriteStableReportFilename()) {
+  if (!AnalyzerOpts.ShouldWriteStableReportFilename) {
       llvm::sys::path::append(Model, Directory, "report-%%%%%%.html");
       if (std::error_code EC =
           llvm::sys::fs::make_absolute(Model)) {
diff --git a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index 6ce4242..f1fabdd 100644
--- a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -471,7 +471,7 @@
 
   o << "   </array>\n";
 
-  if (!AnOpts.shouldDisplayMacroExpansions())
+  if (!AnOpts.ShouldDisplayMacroExpansions)
     return;
 
   o << "   <key>macro_expansions</key>\n"
@@ -704,7 +704,7 @@
     EmitString(o << "  ", SM.getFileEntryForID(FID)->getName()) << '\n';
   o << " </array>\n";
 
-  if (llvm::AreStatisticsEnabled() && AnOpts.shouldSerializeStats()) {
+  if (llvm::AreStatisticsEnabled() && AnOpts.ShouldSerializeStats) {
     o << " <key>statistics</key>\n";
     std::string stats;
     llvm::raw_string_ostream os(stats);
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index 29b6058..f5eb9b5 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -350,7 +350,7 @@
     if (SubEngine *Eng = StateMgr.getOwningEngine()) {
       AnalyzerOptions &Options = Eng->getAnalysisManager().options;
       SmallStructLimit =
-        Options.getRegionStoreSmallStructLimit();
+        Options.RegionStoreSmallStructLimit;
     }
   }
 
diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
index 8c39b79..617c4ba 100644
--- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -385,7 +385,7 @@
   // instead of generating an Unknown value and propagate the taint info to it.
   const unsigned MaxComp = StateMgr.getOwningEngine()
                                ->getAnalysisManager()
-                               .options.getMaxSymbolComplexity();
+                               .options.MaxSymbolComplexity;
 
   if (symLHS && symRHS &&
       (symLHS->computeComplexity() + symRHS->computeComplexity()) <  MaxComp)
diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index 19d7125..2f6a0c8 100644
--- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -459,7 +459,7 @@
   // FIXME: After putting complexity threshold to the symbols we can always
   //        rearrange additive operations but rearrange comparisons only if
   //        option is set.
-  if(!Opts.shouldAggressivelySimplifyBinaryOperation())
+  if(!Opts.ShouldAggressivelySimplifyBinaryOperation)
     return None;
 
   SymbolRef LSym = Lhs.getAsSymbol();
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 4324ed2d..d87937d 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -204,7 +204,7 @@
         PP(CI.getPreprocessor()), OutDir(outdir), Opts(std::move(opts)),
         Plugins(plugins), Injector(injector), CTU(CI) {
     DigestAnalyzerOptions();
-    if (Opts->PrintStats || Opts->shouldSerializeStats()) {
+    if (Opts->PrintStats || Opts->ShouldSerializeStats) {
       AnalyzerTimers = llvm::make_unique<llvm::TimerGroup>(
           "analyzer", "Analyzer timers");
       TUTotalTimer = llvm::make_unique<llvm::Timer>(
@@ -739,7 +739,7 @@
 
   // Execute the worklist algorithm.
   Eng.ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D),
-                      Mgr->options.getMaxNodesPerTopLevelFunction());
+                      Mgr->options.MaxNodesPerTopLevelFunction);
 
   if (!Mgr->options.DumpExplodedGraphTo.empty())
     Eng.DumpGraph(Mgr->options.TrimGraph, Mgr->options.DumpExplodedGraphTo);
diff --git a/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp b/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp
index c0cf395e..b1927c8 100644
--- a/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp
@@ -48,7 +48,7 @@
   FileID mainFileID = SM.getMainFileID();
 
   AnalyzerOptionsRef analyzerOpts = CI.getAnalyzerOpts();
-  llvm::StringRef modelPath = analyzerOpts->getModelPath();
+  llvm::StringRef modelPath = analyzerOpts->ModelPath;
 
   llvm::SmallString<128> fileName;