jansvoboda11 created this revision.
jansvoboda11 added reviewers: Bigcheese, dexonsmith.
Herald added subscribers: steakhal, dang, ASDenysPetrov, dkrupp, donat.nagy, 
Szelethus, a.sidorin, baloghadamsoftware.
jansvoboda11 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch implements generation of remaining analyzer options.

Marked as WIP until the round-tripping mechanism gets decided in D94472 
<https://reviews.llvm.org/D94472>.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D95369

Files:
  clang/include/clang/Driver/Options.td
  clang/lib/Frontend/CompilerInvocation.cpp

Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -649,9 +649,121 @@
   Funcs.insert(Funcs.end(), Values.begin(), Values.end());
 }
 
-static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
+static void GenerateAnalyzerArgs(AnalyzerOptions &Opts,
+                                 SmallVectorImpl<const char *> &Args,
+                                 CompilerInvocation::StringAllocator SA) {
+  const AnalyzerOptions *AnalyzerOpts = &Opts;
+
+#define ANALYZER_OPTION_WITH_MARSHALLING(                                      \
+    PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,        \
+    HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH,   \
+    DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER,     \
+    MERGER, EXTRACTOR, TABLE_INDEX)                                            \
+  GENERATE_OPTION_WITH_MARSHALLING(                                            \
+      Args, SA, KIND, FLAGS, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE,    \
+      IMPLIED_CHECK, IMPLIED_VALUE, DENORMALIZER, EXTRACTOR, TABLE_INDEX)
+#include "clang/Driver/Options.inc"
+#undef ANALYZER_OPTION_WITH_MARSHALLING
+
+  if (Opts.AnalysisStoreOpt != RegionStoreModel) {
+    switch (Opts.AnalysisStoreOpt) {
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)                           \
+  case NAME##Model:                                                            \
+    GenerateArg(Args, OPT_analyzer_store, CMDFLAG, SA);                        \
+    break;
+#include "clang/StaticAnalyzer/Core/Analyses.def"
+    default:
+      llvm_unreachable("Tried to generate unknown analysis store.");
+    }
+  }
+
+  if (Opts.AnalysisConstraintsOpt != RangeConstraintsModel) {
+    switch (Opts.AnalysisConstraintsOpt) {
+#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN)                     \
+  case NAME##Model:                                                            \
+    GenerateArg(Args, OPT_analyzer_constraints, CMDFLAG, SA);                  \
+    break;
+#include "clang/StaticAnalyzer/Core/Analyses.def"
+    default:
+      llvm_unreachable("Tried to generate unknown analysis constraint.");
+    }
+  }
+
+  if (Opts.AnalysisDiagOpt != PD_HTML) {
+    switch (Opts.AnalysisDiagOpt) {
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN)                     \
+  case PD_##NAME:                                                              \
+    GenerateArg(Args, OPT_analyzer_output, CMDFLAG, SA);                       \
+    break;
+#include "clang/StaticAnalyzer/Core/Analyses.def"
+    default:
+      llvm_unreachable("Tried to generate unknown analysis diagnostic client.");
+    }
+  }
+
+  if (Opts.AnalysisPurgeOpt != PurgeStmt) {
+    switch (Opts.AnalysisPurgeOpt) {
+#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC)                                    \
+  case NAME:                                                                   \
+    GenerateArg(Args, OPT_analyzer_purge, CMDFLAG, SA);                        \
+    break;
+#include "clang/StaticAnalyzer/Core/Analyses.def"
+    default:
+      llvm_unreachable("Tried to generate unknown analysis purge mode.");
+    }
+  }
+
+  if (Opts.InliningMode != NoRedundancy) {
+    switch (Opts.InliningMode) {
+#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC)                            \
+  case NAME:                                                                   \
+    GenerateArg(Args, OPT_analyzer_inlining_mode, CMDFLAG, SA);                \
+    break;
+#include "clang/StaticAnalyzer/Core/Analyses.def"
+    default:
+      llvm_unreachable("Tried to generate unknown analysis inlining mode.");
+    }
+  }
+
+  for (const auto &CP : Opts.CheckersAndPackages) {
+    OptSpecifier Opt =
+        CP.second ? OPT_analyzer_checker : OPT_analyzer_disable_checker;
+    GenerateArg(Args, Opt, CP.first, SA);
+  }
+
+  AnalyzerOptions ConfigOpts;
+  parseAnalyzerConfigs(ConfigOpts, nullptr);
+
+  for (const auto &C : Opts.Config) {
+    // Don't generate anything that came from parseAnalyzerConfigs. It would be
+    // redundant and may not be valid on the command line.
+    auto Entry = ConfigOpts.Config.find(C.getKey());
+    if (Entry != ConfigOpts.Config.end() && Entry->getValue() == C.getValue())
+      continue;
+
+    GenerateArg(Args, OPT_analyzer_config, C.getKey() + "=" + C.getValue(), SA);
+  }
+
+  // Nothing to generate for FullCompilerInvocation.
+}
+
+static bool ParseAnalyzerArgsImpl(AnalyzerOptions &Opts, ArgList &Args,
                               DiagnosticsEngine &Diags) {
+  AnalyzerOptions *AnalyzerOpts = &Opts;
   bool Success = true;
+
+#define ANALYZER_OPTION_WITH_MARSHALLING(                                      \
+    PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,        \
+    HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH,   \
+    DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER,     \
+    MERGER, EXTRACTOR, TABLE_INDEX)                                            \
+  PARSE_OPTION_WITH_MARSHALLING(Args, Diags, Success, ID, FLAGS, PARAM,        \
+                                SHOULD_PARSE, KEYPATH, DEFAULT_VALUE,          \
+                                IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER,      \
+                                MERGER, TABLE_INDEX)
+#include "clang/Driver/Options.inc"
+#undef ANALYZER_OPTION_WITH_MARSHALLING
+
   if (Arg *A = Args.getLastArg(OPT_analyzer_store)) {
     StringRef Name = A->getValue();
     AnalysisStores Value = llvm::StringSwitch<AnalysisStores>(Name)
@@ -801,6 +913,31 @@
   return Success;
 }
 
+static bool ParseAnalyzerArgs(CompilerInvocation &Res, AnalyzerOptions &Opts,
+                              ArgList &Args, DiagnosticsEngine &Diags) {
+  bool Success = true;
+
+  auto Temp = IntrusiveRefCntPtr<AnalyzerOptions>(new AnalyzerOptions());
+
+  auto Parse = [&Success, &Diags](CompilerInvocation &Res, ArgList &Args) {
+    Success = ParseAnalyzerArgsImpl(*Res.getAnalyzerOpts(), Args, Diags);
+  };
+
+  auto Generate = [](CompilerInvocation &Res,
+                     SmallVectorImpl<const char *> &Args,
+                     CompilerInvocation::StringAllocator SA) {
+    GenerateAnalyzerArgs(*Res.getAnalyzerOpts(), Args, SA);
+  };
+
+  auto Swap = [&Temp](CompilerInvocation &Res) {
+    Res.getAnalyzerOpts().swap(Temp);
+  };
+
+  RoundTrip(Parse, Generate, Swap, Res, Args);
+
+  return Success;
+}
+
 static StringRef getStringOption(AnalyzerOptions::ConfigTable &Config,
                                  StringRef OptionName, StringRef DefaultVal) {
   return Config.insert({OptionName, std::string(DefaultVal)}).first->second;
@@ -3266,7 +3403,7 @@
 
   Success &= Res.parseSimpleArgs(Args, Diags);
 
-  Success &= ParseAnalyzerArgs(*Res.getAnalyzerOpts(), Args, Diags);
+  Success &= ParseAnalyzerArgs(Res, *Res.getAnalyzerOpts(), Args, Diags);
   ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), Args);
   if (!Res.getDependencyOutputOpts().OutputFile.empty() &&
       Res.getDependencyOutputOpts().Targets.empty()) {
@@ -3495,6 +3632,7 @@
 #undef DIAG_OPTION_WITH_MARSHALLING
 #undef OPTION_WITH_MARSHALLING
 
+  GenerateAnalyzerArgs(*AnalyzerOpts, Args, SA);
   GeneratePreprocessorArgs(*PreprocessorOpts, Args, SA, *LangOpts,
                            FrontendOpts, CodeGenOpts);
   GenerateHeaderSearchArgs(*HeaderSearchOpts, Args, SA);
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -262,7 +262,7 @@
 class FileSystemOpts<string base>
   : KeyPathAndMacro<"FileSystemOpts.", base> {}
 class AnalyzerOpts<string base>
-  : KeyPathAndMacro<"AnalyzerOpts->", base> {}
+  : KeyPathAndMacro<"AnalyzerOpts->", base, "ANALYZER_"> {}
 class MigratorOpts<string base>
   : KeyPathAndMacro<"MigratorOpts.", base> {}
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D95369: [WIP][clang][c... Jan Svoboda via Phabricator via cfe-commits

Reply via email to