Store const& to AnalyzerOptions in AnalysisManager instead of copying
individual flags.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162929 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/StaticAnalyzer/AnalyzerOptions.h b/include/clang/StaticAnalyzer/AnalyzerOptions.h
index 972887e..356d13a 100644
--- a/include/clang/StaticAnalyzer/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/AnalyzerOptions.h
@@ -77,32 +77,66 @@
 
 class AnalyzerOptions {
 public:
+  typedef llvm::StringMap<std::string> ConfigTable;
+
   /// \brief Pair of checker name and enable/disable.
   std::vector<std::pair<std::string, bool> > CheckersControlList;
-  llvm::StringMap<std::string> Config;
+  
+  /// \brief A key-value table of use-specified configuration values.
+  ConfigTable Config;
   AnalysisStores AnalysisStoreOpt;
   AnalysisConstraints AnalysisConstraintsOpt;
   AnalysisDiagClients AnalysisDiagOpt;
   AnalysisPurgeMode AnalysisPurgeOpt;
+  
+  // \brief The interprocedural analysis mode.
   AnalysisIPAMode IPAMode;
+  
   std::string AnalyzeSpecificFunction;
+  
+  /// \brief The maximum number of exploded nodes the analyzer will generate.
   unsigned MaxNodes;
+  
+  /// \brief The maximum number of times the analyzer visits a block.
   unsigned MaxLoop;
+  
+  
   unsigned ShowCheckerHelp : 1;
   unsigned AnalyzeAll : 1;
   unsigned AnalyzerDisplayProgress : 1;
   unsigned AnalyzeNestedBlocks : 1;
+  
+  /// \brief The flag regulates if we should eagerly assume evaluations of
+  /// conditionals, thus, bifurcating the path.
+  ///
+  /// EagerlyAssume - A flag indicating how the engine should handle
+  ///   expressions such as: 'x = (y != 0)'.  When this flag is true then
+  ///   the subexpression 'y != 0' will be eagerly assumed to be true or false,
+  ///   thus evaluating it to the integers 0 or 1 respectively.  The upside
+  ///   is that this can increase analysis precision until we have a better way
+  ///   to lazily evaluate such logic.  The downside is that it eagerly
+  ///   bifurcates paths.
   unsigned EagerlyAssume : 1;
+  
   unsigned TrimGraph : 1;
   unsigned VisualizeEGDot : 1;
   unsigned VisualizeEGUbi : 1;
   unsigned UnoptimizedCFG : 1;
   unsigned CFGAddImplicitDtors : 1;
-  unsigned EagerlyTrimEGraph : 1;
+  unsigned eagerlyTrimExplodedGraph : 1;
   unsigned PrintStats : 1;
+  
+  /// \brief Do not re-analyze paths leading to exhausted nodes with a different
+  /// strategy. We get better code coverage when retry is enabled.
   unsigned NoRetryExhausted : 1;
+  
+  /// \brief The inlining stack depth limit.
   unsigned InlineMaxStackDepth;
+  
+  /// \brief The mode of function selection used during inlining.
   unsigned InlineMaxFunctionSize;
+
+  /// \brief The mode of function selection used during inlining.
   AnalysisInliningMode InliningMode;
 
 public:
@@ -122,7 +156,7 @@
     VisualizeEGUbi = 0;
     UnoptimizedCFG = 0;
     CFGAddImplicitDtors = 0;
-    EagerlyTrimEGraph = 0;
+    eagerlyTrimExplodedGraph = 0;
     PrintStats = 0;
     NoRetryExhausted = 0;
     // Cap the stack depth at 4 calls (5 stack frames, base + 4 calls).
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index ab569a8..b010372 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -41,70 +41,16 @@
 
   CheckerManager *CheckerMgr;
 
-  /// \brief The maximum number of exploded nodes the analyzer will generate.
-  unsigned MaxNodes;
-
-  /// \brief The maximum number of times the analyzer visits a block.
-  unsigned MaxVisit;
-
-  bool VisualizeEGDot;
-  bool VisualizeEGUbi;
-  AnalysisPurgeMode PurgeDead;
-
-  /// \brief The flag regulates if we should eagerly assume evaluations of
-  /// conditionals, thus, bifurcating the path.
-  ///
-  /// EagerlyAssume - A flag indicating how the engine should handle
-  ///   expressions such as: 'x = (y != 0)'.  When this flag is true then
-  ///   the subexpression 'y != 0' will be eagerly assumed to be true or false,
-  ///   thus evaluating it to the integers 0 or 1 respectively.  The upside
-  ///   is that this can increase analysis precision until we have a better way
-  ///   to lazily evaluate such logic.  The downside is that it eagerly
-  ///   bifurcates paths.
-  bool EagerlyAssume;
-  bool TrimGraph;
-  bool EagerlyTrimEGraph;
-
 public:
-  // \brief inter-procedural analysis mode.
-  AnalysisIPAMode IPAMode;
-
-  // Settings for inlining tuning.
-  /// \brief The inlining stack depth limit.
-  unsigned InlineMaxStackDepth;
-  /// \brief The max number of basic blocks in a function being inlined.
-  unsigned InlineMaxFunctionSize;
-  /// \brief The mode of function selection used during inlining.
-  AnalysisInliningMode InliningMode;
-
-  /// \brief Do not re-analyze paths leading to exhausted nodes with a different
-  /// strategy. We get better code coverage when retry is enabled.
-  bool NoRetryExhausted;
-
-  typedef llvm::StringMap<std::string> ConfigTable;
+  const AnalyzerOptions &options;
   
-  /// \brief A key-value table of use-specified configuration values.
-  const ConfigTable &Config;
-  
-public:
   AnalysisManager(ASTContext &ctx,DiagnosticsEngine &diags,
                   const LangOptions &lang,
                   const PathDiagnosticConsumers &Consumers,
                   StoreManagerCreator storemgr,
                   ConstraintManagerCreator constraintmgr, 
                   CheckerManager *checkerMgr,
-                  const ConfigTable &Config,
-                  unsigned maxnodes, unsigned maxvisit,
-                  bool vizdot, bool vizubi, AnalysisPurgeMode purge,
-                  bool eager, bool trim,
-                  bool useUnoptimizedCFG,
-                  bool addImplicitDtors,
-                  bool eagerlyTrimEGraph,
-                  AnalysisIPAMode ipa,
-                  unsigned inlineMaxStack,
-                  unsigned inlineMaxFunctionSize,
-                  AnalysisInliningMode inliningMode,
-                  bool NoRetry);
+                  const AnalyzerOptions &Options);
 
   ~AnalysisManager();
   
@@ -148,27 +94,13 @@
 
   void FlushDiagnostics();
 
-  unsigned getMaxNodes() const { return MaxNodes; }
-
-  unsigned getMaxVisit() const { return MaxVisit; }
-
-  bool shouldVisualizeGraphviz() const { return VisualizeEGDot; }
-
-  bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; }
-
   bool shouldVisualize() const {
-    return VisualizeEGDot || VisualizeEGUbi;
+    return options.VisualizeEGDot || options.VisualizeEGUbi;
   }
 
-  bool shouldEagerlyTrimExplodedGraph() const { return EagerlyTrimEGraph; }
-
-  bool shouldTrimGraph() const { return TrimGraph; }
-
-  AnalysisPurgeMode getPurgeMode() const { return PurgeDead; }
-
-  bool shouldEagerlyAssume() const { return EagerlyAssume; }
-
-  bool shouldInlineCall() const { return (IPAMode != None); }
+  bool shouldInlineCall() const {
+    return options.IPAMode != None;
+  }
 
   CFG *getCFG(Decl const *D) {
     return AnaCtxMgr.getContext(D)->getCFG();
@@ -186,7 +118,6 @@
   AnalysisDeclContext *getAnalysisDeclContext(const Decl *D) {
     return AnaCtxMgr.getContext(D);
   }
-
 };
 
 } // enAnaCtxMgrspace
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index c260c1b..13bb3f6 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -64,8 +64,8 @@
     return Eng.getStoreManager();
   }
 
-  const AnalysisManager::ConfigTable &getConfig() const {
-    return Eng.getAnalysisManager().Config;
+  const AnalyzerOptions::ConfigTable &getConfig() const {
+    return Eng.getAnalysisManager().options.Config;
   }
   
   /// \brief Returns the previous node in the exploded graph, which includes
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 4f489fe..69acd41 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1130,7 +1130,7 @@
   Opts.TrimGraph = Args.hasArg(OPT_trim_egraph);
   Opts.MaxNodes = Args.getLastArgIntValue(OPT_analyzer_max_nodes, 150000,Diags);
   Opts.MaxLoop = Args.getLastArgIntValue(OPT_analyzer_max_loop, 4, Diags);
-  Opts.EagerlyTrimEGraph = !Args.hasArg(OPT_analyzer_no_eagerly_trim_egraph);
+  Opts.eagerlyTrimExplodedGraph = !Args.hasArg(OPT_analyzer_no_eagerly_trim_egraph);
   Opts.PrintStats = Args.hasArg(OPT_analyzer_stats);
   Opts.InlineMaxStackDepth =
     Args.getLastArgIntValue(OPT_analyzer_inline_max_stack_depth,
diff --git a/lib/StaticAnalyzer/Core/AnalysisManager.cpp b/lib/StaticAnalyzer/Core/AnalysisManager.cpp
index 339208b..6a01edf 100644
--- a/lib/StaticAnalyzer/Core/AnalysisManager.cpp
+++ b/lib/StaticAnalyzer/Core/AnalysisManager.cpp
@@ -20,35 +20,17 @@
                                  StoreManagerCreator storemgr,
                                  ConstraintManagerCreator constraintmgr, 
                                  CheckerManager *checkerMgr,
-                                 const ConfigTable &Config,
-                                 unsigned maxnodes, unsigned maxvisit,
-                                 bool vizdot, bool vizubi,
-                                 AnalysisPurgeMode purge,
-                                 bool eager, bool trim,
-                                 bool useUnoptimizedCFG,
-                                 bool addImplicitDtors,
-                                 bool eagerlyTrimEGraph,
-                                 AnalysisIPAMode ipa,
-                                 unsigned inlineMaxStack,
-                                 unsigned inlineMaxFunctionSize,
-                                 AnalysisInliningMode IMode,
-                                 bool NoRetry)
-  : AnaCtxMgr(useUnoptimizedCFG, addImplicitDtors, /*addInitializers=*/true),
-    Ctx(ctx), Diags(diags), LangOpts(lang),
+                                 const AnalyzerOptions &Options)
+  : AnaCtxMgr(Options.UnoptimizedCFG,
+              Options.CFGAddImplicitDtors,
+              /*addInitializers=*/true),
+    Ctx(ctx),
+    Diags(diags),
+    LangOpts(lang),
     PathConsumers(PDC),
     CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
     CheckerMgr(checkerMgr),
-    MaxNodes(maxnodes), MaxVisit(maxvisit),
-    VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
-    EagerlyAssume(eager), TrimGraph(trim),
-    EagerlyTrimEGraph(eagerlyTrimEGraph),
-    IPAMode(ipa),
-    InlineMaxStackDepth(inlineMaxStack),
-    InlineMaxFunctionSize(inlineMaxFunctionSize),
-    InliningMode(IMode),
-    NoRetryExhausted(NoRetry),
-    Config(Config)
-{
+    options(Options) {
   AnaCtxMgr.getCFGBuildOptions().setAllAlwaysAdd();
 }
 
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 6603b6c..5f52724 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -70,12 +70,12 @@
     currStmt(NULL), currStmtIdx(0), currBldrCtx(0),
     NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
     RaiseSel(GetNullarySelector("raise", getContext())),
-    ObjCGCEnabled(gcEnabled), BR(mgr, *this) {
-  
-  if (mgr.shouldEagerlyTrimExplodedGraph()) {
-    // Enable eager node reclaimation when constructing the ExplodedGraph.  
-    G.enableNodeReclamation();
-  }
+    ObjCGCEnabled(gcEnabled), BR(mgr, *this)
+{
+    if (mgr.options.eagerlyTrimExplodedGraph) {
+      // Enable eager node reclaimation when constructing the ExplodedGraph.
+      G.enableNodeReclamation();
+    }
 }
 
 ExprEngine::~ExprEngine() {
@@ -228,7 +228,7 @@
                                      const LocationContext *LC) {
   
   // Are we never purging state values?
-  if (AMgr.getPurgeMode() == PurgeNone)
+  if (AMgr.options.AnalysisPurgeOpt == PurgeNone)
     return false;
 
   // Is this the beginning of a basic block?
@@ -704,7 +704,7 @@
 
       Bldr.takeNodes(Pred);
       
-      if (AMgr.shouldEagerlyAssume() &&
+      if (AMgr.options.EagerlyAssume &&
           (B->isRelationalOp() || B->isEqualityOp())) {
         ExplodedNodeSet Tmp;
         VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
@@ -924,7 +924,7 @@
     case Stmt::UnaryOperatorClass: {
       Bldr.takeNodes(Pred);
       const UnaryOperator *U = cast<UnaryOperator>(S);
-      if (AMgr.shouldEagerlyAssume() && (U->getOpcode() == UO_LNot)) {
+      if (AMgr.options.EagerlyAssume && (U->getOpcode() == UO_LNot)) {
         ExplodedNodeSet Tmp;
         VisitUnaryOperator(U, Pred, Tmp);
         evalEagerlyAssume(Dst, Tmp, U);
@@ -1024,7 +1024,7 @@
   // FIXME: Refactor this into a checker.
   ExplodedNode *pred = nodeBuilder.getContext().getPred();
   
-  if (nodeBuilder.getContext().blockCount() >= AMgr.getMaxVisit()) {
+  if (nodeBuilder.getContext().blockCount() >= AMgr.options.MaxLoop) {
     static SimpleProgramPointTag tag("ExprEngine : Block count exceeded");
     const ExplodedNode *Sink =
                    nodeBuilder.generateSink(pred->getState(), pred, &tag);
@@ -1042,7 +1042,8 @@
       // no-inlining policy in the state and enqueuing the new work item on
       // the list. Replay should almost never fail. Use the stats to catch it
       // if it does.
-      if ((!AMgr.NoRetryExhausted && replayWithoutInlining(pred, CalleeLC)))
+      if ((!AMgr.options.NoRetryExhausted &&
+           replayWithoutInlining(pred, CalleeLC)))
         return;
       NumMaxBlockCountReachedInInlined++;
     } else
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 0f29735..70350ce 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -176,7 +176,7 @@
   // that we report the issues such as leaks in the stack contexts in which
   // they occurred.
   ExplodedNodeSet CleanedNodes;
-  if (LastSt && Blk && AMgr.getPurgeMode() != PurgeNone) {
+  if (LastSt && Blk && AMgr.options.AnalysisPurgeOpt != PurgeNone) {
     static SimpleProgramPointTag retValBind("ExprEngine : Bind Return Value");
     PostStmt Loc(LastSt, calleeCtx, &retValBind);
     bool isNew;
@@ -268,13 +268,13 @@
     return false;
 
   if (getNumberStackFrames(Pred->getLocationContext())
-        == AMgr.InlineMaxStackDepth)
+        == AMgr.options.InlineMaxStackDepth)
     return false;
 
   if (Engine.FunctionSummaries->hasReachedMaxBlockCount(D))
     return false;
 
-  if (CalleeCFG->getNumBlockIDs() > AMgr.InlineMaxFunctionSize)
+  if (CalleeCFG->getNumBlockIDs() > AMgr.options.InlineMaxFunctionSize)
     return false;
 
   // Do not inline variadic calls (for now).
@@ -317,7 +317,7 @@
 }}
 
 static bool shouldInlineCXX(AnalysisManager &AMgr) {
-  switch (AMgr.IPAMode) {
+  switch (AMgr.options.IPAMode) {
   case None:
   case BasicInlining:
     return false;
@@ -424,8 +424,8 @@
     break;
   }
   case CE_ObjCMessage:
-    if (!(getAnalysisManager().IPAMode == DynamicDispatch ||
-          getAnalysisManager().IPAMode == DynamicDispatchBifurcate))
+    if (!(getAnalysisManager().options.IPAMode == DynamicDispatch ||
+          getAnalysisManager().options.IPAMode == DynamicDispatchBifurcate))
       return false;
     break;
   }
@@ -600,13 +600,13 @@
     if (D) {
       if (RD.mayHaveOtherDefinitions()) {
         // Explore with and without inlining the call.
-        if (getAnalysisManager().IPAMode == DynamicDispatchBifurcate) {
+        if (getAnalysisManager().options.IPAMode == DynamicDispatchBifurcate) {
           BifurcateCall(RD.getDispatchRegion(), *Call, D, Bldr, Pred);
           return;
         }
 
         // Don't inline if we're not in any dynamic dispatch mode.
-        if (getAnalysisManager().IPAMode != DynamicDispatch) {
+        if (getAnalysisManager().options.IPAMode != DynamicDispatch) {
           conservativeEvalCall(*Call, Bldr, Pred, State);
           return;
         }
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 0be0afa..2c96115 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -255,22 +255,7 @@
                                   CreateStoreMgr,
                                   CreateConstraintMgr,
                                   checkerMgr.get(),
-                                  Opts.Config,
-                                  Opts.MaxNodes,
-                                  Opts.MaxLoop,
-                                  Opts.VisualizeEGDot,
-                                  Opts.VisualizeEGUbi,
-                                  Opts.AnalysisPurgeOpt,
-                                  Opts.EagerlyAssume,
-                                  Opts.TrimGraph,
-                                  Opts.UnoptimizedCFG,
-                                  Opts.CFGAddImplicitDtors,
-                                  Opts.EagerlyTrimEGraph,
-                                  Opts.IPAMode,
-                                  Opts.InlineMaxStackDepth,
-                                  Opts.InlineMaxFunctionSize,
-                                  Opts.InliningMode,
-                                  Opts.NoRetryExhausted));
+                                  Opts));
   }
 
   /// \brief Store the top level decls in the set to be processed later on.
@@ -426,7 +411,7 @@
     Decl *D = N->getDecl();
     assert(D);
     HandleCode(D, ANALYSIS_PATH,
-               (Mgr->InliningMode == All ? 0 : &VisitedCallees));
+               (Mgr->options.InliningMode == All ? 0 : &VisitedCallees));
 
     // Add the visited callees to the global visited set.
     for (SetOfConstDecls::iterator I = VisitedCallees.begin(),
@@ -588,22 +573,22 @@
 
   // Set the graph auditor.
   OwningPtr<ExplodedNode::Auditor> Auditor;
-  if (Mgr->shouldVisualizeUbigraph()) {
+  if (Mgr->options.VisualizeEGUbi) {
     Auditor.reset(CreateUbiViz());
     ExplodedNode::SetAuditor(Auditor.get());
   }
 
   // Execute the worklist algorithm.
   Eng.ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D),
-                      Mgr->getMaxNodes());
+                      Mgr->options.MaxNodes);
 
   // Release the auditor (if any) so that it doesn't monitor the graph
   // created BugReporter.
   ExplodedNode::SetAuditor(0);
 
   // Visualize the exploded graph.
-  if (Mgr->shouldVisualizeGraphviz())
-    Eng.ViewGraph(Mgr->shouldTrimGraph());
+  if (Mgr->options.VisualizeEGDot)
+    Eng.ViewGraph(Mgr->options.TrimGraph);
 
   // Display warnings.
   Eng.getBugReporter().FlushReports();