jansvoboda11 updated this revision to Diff 321131.
jansvoboda11 added a comment.

Fix failures of tests that invoke -cc1 directly


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95793/new/

https://reviews.llvm.org/D95793

Files:
  clang/include/clang/Basic/Sanitizers.h
  clang/include/clang/Driver/Options.td
  clang/include/clang/Frontend/CompilerInvocation.h
  clang/lib/Basic/Sanitizers.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/unittests/Basic/CMakeLists.txt
  clang/unittests/Basic/SanitizersTest.cpp

Index: clang/unittests/Basic/SanitizersTest.cpp
===================================================================
--- /dev/null
+++ clang/unittests/Basic/SanitizersTest.cpp
@@ -0,0 +1,49 @@
+//===- unittests/Basic/SanitizersTest.cpp - Test Sanitizers ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/Sanitizers.h"
+
+#include "gmock/gmock-matchers.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+
+using testing::Contains;
+using testing::Not;
+
+TEST(SanitizersTest, serializeSanitizers) {
+  SanitizerSet Set;
+  Set.set(parseSanitizerValue("memory", false), true);
+  Set.set(parseSanitizerValue("nullability-arg", false), true);
+
+  SmallVector<StringRef, 4> Serialized;
+  serializeSanitizerSet(Set, Serialized);
+
+  ASSERT_EQ(Serialized.size(), 2u);
+  ASSERT_THAT(Serialized, Contains("memory"));
+  ASSERT_THAT(Serialized, Contains("nullability-arg"));
+}
+
+TEST(SanitizersTest, serializeSanitizersIndividual) {
+  SanitizerSet Set;
+  Set.set(parseSanitizerValue("memory", false), true);
+  Set.set(parseSanitizerValue("nullability-arg", false), true);
+  Set.set(parseSanitizerValue("nullability-assign", false), true);
+  Set.set(parseSanitizerValue("nullability-return", false), true);
+
+  SmallVector<StringRef, 4> Serialized;
+  serializeSanitizerSet(Set, Serialized);
+
+  ASSERT_EQ(Serialized.size(), 4u);
+  ASSERT_THAT(Serialized, Contains("memory"));
+  ASSERT_THAT(Serialized, Contains("nullability-arg"));
+  ASSERT_THAT(Serialized, Contains("nullability-assign"));
+  ASSERT_THAT(Serialized, Contains("nullability-return"));
+  // Individual sanitizers don't get squashed into a single group.
+  ASSERT_THAT(Serialized, Not(Contains("nullability")));
+}
Index: clang/unittests/Basic/CMakeLists.txt
===================================================================
--- clang/unittests/Basic/CMakeLists.txt
+++ clang/unittests/Basic/CMakeLists.txt
@@ -8,6 +8,7 @@
   FileEntryTest.cpp
   FileManagerTest.cpp
   LineOffsetMappingTest.cpp
+  SanitizersTest.cpp
   SourceManagerTest.cpp
   )
 
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -214,6 +214,7 @@
     Args.push_back(SA(Value));
     break;
   case Option::JoinedClass:
+  case Option::CommaJoinedClass:
     Args.push_back(SA(Twine(Spelling) + Value));
     break;
   default:
@@ -1195,16 +1196,28 @@
   return Success;
 }
 
-static void parseSanitizerKinds(StringRef FlagName,
+static bool parseSanitizerKinds(StringRef FlagName,
                                 const std::vector<std::string> &Sanitizers,
                                 DiagnosticsEngine &Diags, SanitizerSet &S) {
+  bool Success = true;
+
   for (const auto &Sanitizer : Sanitizers) {
     SanitizerMask K = parseSanitizerValue(Sanitizer, /*AllowGroups=*/false);
-    if (K == SanitizerMask())
+    if (K == SanitizerMask()) {
       Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;
+      Success = false;
+    }
     else
       S.set(K, true);
   }
+
+  return Success;
+}
+
+static SmallVector<StringRef, 4> serializeSanitizerKinds(SanitizerSet S) {
+  SmallVector<StringRef, 4> Values;
+  serializeSanitizerSet(S, Values);
+  return Values;
 }
 
 static void parseXRayInstrumentationBundle(StringRef FlagName, StringRef Bundle,
@@ -2628,21 +2641,232 @@
   llvm_unreachable("unknown input language");
 }
 
-static void GenerateLangArgs(const LangOptions &Opts,
-                             SmallVectorImpl<const char *> &Args,
-                             CompilerInvocation::StringAllocator SA) {
+void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
+                                          SmallVectorImpl<const char *> &Args,
+                                          StringAllocator SA,
+                                          const llvm::Triple &T) {
+  OptSpecifier StdOpt;
+  switch (Opts.LangStd) {
+  case LangStandard::lang_opencl10:
+  case LangStandard::lang_opencl11:
+  case LangStandard::lang_opencl12:
+  case LangStandard::lang_opencl20:
+  case LangStandard::lang_opencl30:
+  case LangStandard::lang_openclcpp:
+    StdOpt = OPT_cl_std_EQ;
+    break;
+  default:
+    StdOpt = OPT_std_EQ;
+    break;
+  }
+
+  auto LangStandard = LangStandard::getLangStandardForKind(Opts.LangStd);
+  GenerateArg(Args, StdOpt, LangStandard.getName(), SA);
+
   if (Opts.IncludeDefaultHeader)
     GenerateArg(Args, OPT_finclude_default_header, SA);
   if (Opts.DeclareOpenCLBuiltins)
     GenerateArg(Args, OPT_fdeclare_opencl_builtins, SA);
+
+  const LangOptions *LangOpts = &Opts;
+
+#define LANG_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 LANG_OPTION_WITH_MARSHALLING
+
+  // The '-fcf-protection=' option is generated by CodeGenOpts generator.
+
+  if (Opts.ObjC) {
+    std::string Buffer;
+    llvm::raw_string_ostream Stream(Buffer);
+    Stream << Opts.ObjCRuntime;
+    GenerateArg(Args, OPT_fobjc_runtime_EQ, Stream.str(), SA);
+
+    if (Opts.GC == LangOptions::GCOnly)
+      GenerateArg(Args, OPT_fobjc_gc_only, SA);
+    else if (Opts.GC == LangOptions::HybridGC)
+      GenerateArg(Args, OPT_fobjc_gc, SA);
+    else if (Opts.ObjCAutoRefCount == 1)
+      GenerateArg(Args, OPT_fobjc_arc, SA);
+
+    if (Opts.ObjCWeakRuntime)
+      GenerateArg(Args, OPT_fobjc_runtime_has_weak, SA);
+
+    if (Opts.ObjCWeak)
+      GenerateArg(Args, OPT_fobjc_weak, SA);
+
+    if (Opts.ObjCSubscriptingLegacyRuntime)
+      GenerateArg(Args, OPT_fobjc_subscripting_legacy_runtime, SA);
+  }
+
+  if (Opts.GNUCVersion != 0) {
+    unsigned Major = Opts.GNUCVersion / 100 / 100;
+    unsigned Minor = (Opts.GNUCVersion / 100) % 100;
+    unsigned Patch = Opts.GNUCVersion % 100;
+    GenerateArg(Args, OPT_fgnuc_version_EQ,
+                Twine(Major) + "." + Twine(Minor) + "." + Twine(Patch), SA);
+  }
+
+  if (Opts.SignedOverflowBehavior == LangOptions::SOB_Trapping) {
+    GenerateArg(Args, OPT_ftrapv, SA);
+    GenerateArg(Args, OPT_ftrapv_handler, Opts.OverflowHandler, SA);
+  } else if (Opts.SignedOverflowBehavior == LangOptions::SOB_Defined) {
+    GenerateArg(Args, OPT_fwrapv, SA);
+  }
+
+  if (Opts.MSCompatibilityVersion != 0) {
+    unsigned Major = Opts.MSCompatibilityVersion / 10000000;
+    unsigned Minor = (Opts.MSCompatibilityVersion / 100000) % 100;
+    unsigned Subminor = Opts.MSCompatibilityVersion % 100000;
+    GenerateArg(Args, OPT_fms_compatibility_version,
+                Twine(Major) + "." + Twine(Minor) + "." + Twine(Subminor), SA);
+  }
+
+  if ((!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17) || T.isOSzOS()) {
+    if (!Opts.Trigraphs)
+      GenerateArg(Args, OPT_fno_trigraphs, SA);
+  } else {
+    if (Opts.Trigraphs)
+      GenerateArg(Args, OPT_ftrigraphs, SA);
+  }
+
+  if (Opts.Blocks && !(Opts.OpenCL && Opts.OpenCLVersion == 200))
+    GenerateArg(Args, OPT_fblocks, SA);
+
+  if (Opts.ConvergentFunctions &&
+      !(Opts.OpenCL || (Opts.CUDA && Opts.CUDAIsDevice) || Opts.SYCLIsDevice))
+    GenerateArg(Args, OPT_fconvergent_functions, SA);
+
+  if (Opts.NoBuiltin && !Opts.Freestanding)
+    GenerateArg(Args, OPT_fno_builtin, SA);
+
+  // Not generating '-fno-builtin-xxx'. It's handled for CodeGenOptions, that
+  // also read OPT_fno_builtin_.
+
+  if (Opts.LongDoubleSize == 128)
+    GenerateArg(Args, OPT_mlong_double_128, SA);
+  else if (Opts.LongDoubleSize == 64)
+    GenerateArg(Args, OPT_mlong_double_64, SA);
+
+  // Not generating '-mrtd', it's just an alias for '-fdefault-calling-conv='.
+
+  // OpenMP was requested via '-fopenmp', not implied by '-fopenmp-simd' or
+  // '-fopenmp-targets='.
+  if (Opts.OpenMP && !Opts.OpenMPSimd) {
+    GenerateArg(Args, OPT_fopenmp, SA);
+
+    if (Opts.OpenMP != 50)
+      GenerateArg(Args, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP), SA);
+
+    if (!Opts.OpenMPUseTLS)
+      GenerateArg(Args, OPT_fnoopenmp_use_tls, SA);
+
+    if (Opts.OpenMPIsDevice)
+      GenerateArg(Args, OPT_fopenmp_is_device, SA);
+
+    if (Opts.OpenMPIRBuilder)
+      GenerateArg(Args, OPT_fopenmp_enable_irbuilder, SA);
+  }
+
+  if (Opts.OpenMPSimd) {
+    GenerateArg(Args, OPT_fopenmp_simd, SA);
+
+    if (Opts.OpenMP != 50)
+      GenerateArg(Args, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP), SA);
+  }
+
+  if (Opts.OpenMPCUDANumSMs != 0)
+    GenerateArg(Args, OPT_fopenmp_cuda_number_of_sm_EQ,
+                Twine(Opts.OpenMPCUDANumSMs), SA);
+
+  if (Opts.OpenMPCUDABlocksPerSM != 0)
+    GenerateArg(Args, OPT_fopenmp_cuda_blocks_per_sm_EQ,
+                Twine(Opts.OpenMPCUDABlocksPerSM), SA);
+
+  if (Opts.OpenMPCUDAReductionBufNum != 1024)
+    GenerateArg(Args, OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
+                Twine(Opts.OpenMPCUDAReductionBufNum), SA);
+
+  if (!Opts.OMPTargetTriples.empty()) {
+    std::string Targets;
+    llvm::raw_string_ostream OS(Targets);
+    llvm::interleave(
+        Opts.OMPTargetTriples, OS,
+        [&OS](const llvm::Triple &T) { OS << T.str(); }, ",");
+    GenerateArg(Args, OPT_fopenmp_targets_EQ, OS.str(), SA);
+  }
+
+  if (!Opts.OMPHostIRFile.empty())
+    GenerateArg(Args, OPT_fopenmp_host_ir_file_path, Opts.OMPHostIRFile, SA);
+
+  if (Opts.OpenMPCUDAMode)
+    GenerateArg(Args, OPT_fopenmp_cuda_mode, SA);
+
+  if (Opts.OpenMPCUDATargetParallel)
+    GenerateArg(Args, OPT_fopenmp_cuda_parallel_target_regions, SA);
+
+  if (Opts.OpenMPCUDAForceFullRuntime)
+    GenerateArg(Args, OPT_fopenmp_cuda_force_full_runtime, SA);
+
+  // The arguments used to set 'Optimize' and 'OptimizeSize' will be generated
+  // by CodeGenOptions.
+
+  if (Opts.NoInlineDefine && Opts.Optimize)
+    GenerateArg(Args, OPT_fno_inline, SA);
+
+  if (Opts.DefaultFPContractMode == LangOptions::FPM_Fast)
+    GenerateArg(Args, OPT_ffp_contract, "fast", SA);
+  else if (Opts.DefaultFPContractMode == LangOptions::FPM_On)
+    GenerateArg(Args, OPT_ffp_contract, "on", SA);
+  else if (Opts.DefaultFPContractMode == LangOptions::FPM_Off)
+    GenerateArg(Args, OPT_ffp_contract, "off", SA);
+  else if (Opts.DefaultFPContractMode == LangOptions::FPM_FastHonorPragmas)
+    GenerateArg(Args, OPT_ffp_contract, "fast-honor-pragmas", SA);
+
+  for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
+    GenerateArg(Args, OPT_fsanitize_EQ, Sanitizer, SA);
+
+  // Conflating '-fsanitize-system-blacklist' and '-fsanitize-blacklist'.
+  for (const std::string &F : Opts.SanitizerBlacklistFiles)
+    GenerateArg(Args, OPT_fsanitize_blacklist, F, SA);
+
+  if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver3_8)
+    GenerateArg(Args, OPT_fclang_abi_compat_EQ, "3.8", SA);
+  else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver4)
+    GenerateArg(Args, OPT_fclang_abi_compat_EQ, "4.0", SA);
+  else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver6)
+    GenerateArg(Args, OPT_fclang_abi_compat_EQ, "6.0", SA);
+  else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver7)
+    GenerateArg(Args, OPT_fclang_abi_compat_EQ, "7.0", SA);
+  else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver9)
+    GenerateArg(Args, OPT_fclang_abi_compat_EQ, "9.0", SA);
+  else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver11)
+    GenerateArg(Args, OPT_fclang_abi_compat_EQ, "11.0", SA);
+
+  if (Opts.getSignReturnAddressScope() ==
+      LangOptions::SignReturnAddressScopeKind::All)
+    GenerateArg(Args, OPT_msign_return_address_EQ, "all", SA);
+  else if (Opts.getSignReturnAddressScope() ==
+           LangOptions::SignReturnAddressScopeKind::NonLeaf)
+    GenerateArg(Args, OPT_msign_return_address_EQ, "non-leaf", SA);
+
+  if (Opts.getSignReturnAddressKey() ==
+      LangOptions::SignReturnAddressKeyKind::BKey)
+    GenerateArg(Args, OPT_msign_return_address_key_EQ, "b_key", SA);
 }
 
-bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
-                                       InputKind IK, const llvm::Triple &T,
-                                       std::vector<std::string> &Includes,
-                                       DiagnosticsEngine &Diags) {
+bool CompilerInvocation::ParseLangArgsImpl(LangOptions &Opts, ArgList &Args,
+                                           InputKind IK, const llvm::Triple &T,
+                                           std::vector<std::string> &Includes,
+                                           DiagnosticsEngine &Diags) {
   unsigned NumErrorsBefore = Diags.getNumErrors();
-
   // FIXME: Cleanup per-file based stuff.
   LangStandard::Kind LangStd = LangStandard::lang_unspecified;
   if (const Arg *A = Args.getLastArg(OPT_std_EQ)) {
@@ -2858,6 +3082,8 @@
     }
   }
 
+  // Check if -fopenmp is specified and set default version to 5.0.
+  Opts.OpenMP = Args.hasArg(OPT_fopenmp) ? 50 : 0;
   // Check if -fopenmp-simd is specified.
   bool IsSimdSpecified =
       Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd,
@@ -2997,8 +3223,10 @@
   }
 
   // Parse -fsanitize= arguments.
-  parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
-                      Diags, Opts.Sanitize);
+  Success &=
+      parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
+                          Diags, Opts.Sanitize);
+  Opts.SanitizerBlacklistFiles = Args.getAllArgValues(OPT_fsanitize_blacklist);
   std::vector<std::string> systemBlacklists =
       Args.getAllArgValues(OPT_fsanitize_system_blacklist);
   Opts.SanitizerBlacklistFiles.insert(Opts.SanitizerBlacklistFiles.end(),
@@ -3075,6 +3303,55 @@
   return Success && Diags.getNumErrors() == NumErrorsBefore;
 }
 
+bool CompilerInvocation::ParseLangArgs(CompilerInvocation &Res,
+                                       LangOptions &Opts,
+                                       llvm::opt::ArgList &Args, InputKind IK,
+                                       const llvm::Triple &T,
+                                       std::vector<std::string> &Includes,
+                                       DiagnosticsEngine &Diags) {
+  auto DummyOpts = std::make_shared<LangOptions>();
+
+  // We need to work around inconsistencies related to optimization flags. Their
+  // primary consumer is CodeGenOptions. However, the LangOptions parser also
+  // queries them, which means RoundTrip expects us to generate them. We don't
+  // want to do it in GenerateLangArgs, because it should eventually be the
+  // responsibility of GenerateCodeGenArgs. Until we start doing one big
+  // round-trip, let's do it here.
+  //
+  // Our parser always queries OPT_O_Group. When given -O1, -O2 or -O3, it also
+  // queries OPT_O. To ensure RoundTrip consistently considers us responsible
+  // for generating all of them, we ensure to proactively query them all.
+
+  return RoundTrip(
+      [IK, &T, &Includes](CompilerInvocation &Res, ArgList &Args,
+                          DiagnosticsEngine &Diags) {
+        // Proactively query all optimization flags.
+        Args.getLastArg(OPT_O0, OPT_O4, OPT_O, OPT_Ofast);
+        return ParseLangArgsImpl(*Res.getLangOpts(), Args, IK, T, Includes,
+                                 Diags);
+      },
+      [&T, &Args](CompilerInvocation &Res,
+                  SmallVectorImpl<const char *> &GenArgs, StringAllocator SA) {
+        GenerateLangArgs(*Res.getLangOpts(), GenArgs, SA, T);
+        // Generate all optimization flags we queried.
+        if (Arg *A = Args.getLastArg(OPT_O_Group)) {
+          OptSpecifier Opt = A->getOption().getID();
+
+          if (A->getNumValues() > 0)
+            GenerateArg(GenArgs, Opt, A->getValues().back(), SA);
+          else
+            GenerateArg(GenArgs, Opt, SA);
+        }
+
+        // We also queried -fcf-protection, but don't have enough information to
+        // generate it. Eventually, it will be generated from CodeGenOptions.
+        if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ))
+          GenerateArg(GenArgs, OPT_fcf_protection_EQ, A->getValue(), SA);
+      },
+      [&DummyOpts](CompilerInvocation &Res) { Res.LangOpts.swap(DummyOpts); },
+      Res, Args, Diags, "LangOptions");
+}
+
 static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
   switch (Action) {
   case frontend::ASTDeclList:
@@ -3408,12 +3685,13 @@
     // set regardless of the input type.
     LangOpts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
     LangOpts.PIE = Args.hasArg(OPT_pic_is_pie);
-    parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
-                        Diags, LangOpts.Sanitize);
+    Success &= parseSanitizerKinds(
+        "-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ), Diags,
+        LangOpts.Sanitize);
   } else {
     // Other LangOpts are only initialized when the input is not AST or LLVM IR.
     // FIXME: Should we really be calling this for an Language::Asm input?
-    Success &= ParseLangArgs(LangOpts, Args, DashX, T,
+    Success &= ParseLangArgs(Res, LangOpts, Args, DashX, T,
                              Res.getPreprocessorOpts().Includes, Diags);
     if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC)
       LangOpts.ObjCExceptions = 1;
@@ -3600,21 +3878,21 @@
                                    EXTRACTOR, TABLE_INDEX)
 
 #define DIAG_OPTION_WITH_MARSHALLING OPTION_WITH_MARSHALLING
-#define LANG_OPTION_WITH_MARSHALLING OPTION_WITH_MARSHALLING
 #define CODEGEN_OPTION_WITH_MARSHALLING OPTION_WITH_MARSHALLING
 
 #include "clang/Driver/Options.inc"
 
 #undef CODEGEN_OPTION_WITH_MARSHALLING
-#undef LANG_OPTION_WITH_MARSHALLING
 #undef DIAG_OPTION_WITH_MARSHALLING
 #undef OPTION_WITH_MARSHALLING
 
+  llvm::Triple T(TargetOpts->Triple);
+
   GeneratePreprocessorArgs(*PreprocessorOpts, Args, SA, *LangOpts,
                            FrontendOpts, CodeGenOpts);
   GenerateAnalyzerArgs(*AnalyzerOpts, Args, SA);
   GenerateHeaderSearchArgs(*HeaderSearchOpts, Args, SA);
-  GenerateLangArgs(*LangOpts, Args, SA);
+  GenerateLangArgs(*LangOpts, Args, SA,  T);
 }
 
 IntrusiveRefCntPtr<llvm::vfs::FileSystem>
Index: clang/lib/Basic/Sanitizers.cpp
===================================================================
--- clang/lib/Basic/Sanitizers.cpp
+++ clang/lib/Basic/Sanitizers.cpp
@@ -12,6 +12,7 @@
 
 #include "clang/Basic/Sanitizers.h"
 #include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringSwitch.h"
 
 using namespace clang;
@@ -34,6 +35,14 @@
   return ParsedKind;
 }
 
+void clang::serializeSanitizerSet(SanitizerSet Set,
+                                  SmallVectorImpl<StringRef> &Values) {
+#define SANITIZER(NAME, ID)                                                    \
+  if (Set.has(SanitizerKind::ID))                                              \
+    Values.push_back(NAME);
+#include "clang/Basic/Sanitizers.def"
+}
+
 SanitizerMask clang::expandSanitizerGroups(SanitizerMask Kinds) {
 #define SANITIZER(NAME, ID)
 #define SANITIZER_GROUP(NAME, ID, ALIAS)                                       \
Index: clang/include/clang/Frontend/CompilerInvocation.h
===================================================================
--- clang/include/clang/Frontend/CompilerInvocation.h
+++ clang/include/clang/Frontend/CompilerInvocation.h
@@ -249,11 +249,21 @@
                        DiagnosticsEngine &Diags);
 
   /// Parse command line options that map to LangOptions.
-  static bool ParseLangArgs(LangOptions &Opts, llvm::opt::ArgList &Args,
-                            InputKind IK, const llvm::Triple &T,
+  static bool ParseLangArgsImpl(LangOptions &Opts, llvm::opt::ArgList &Args,
+                                InputKind IK, const llvm::Triple &T,
+                                std::vector<std::string> &Includes,
+                                DiagnosticsEngine &Diags);
+
+  static bool ParseLangArgs(CompilerInvocation &Res, LangOptions &Opts,
+                            llvm::opt::ArgList &Args, InputKind IK,
+                            const llvm::Triple &T,
                             std::vector<std::string> &Includes,
                             DiagnosticsEngine &Diags);
 
+  static void GenerateLangArgs(const LangOptions &Opts,
+                               SmallVectorImpl<const char *> &Args,
+                               StringAllocator SA, const llvm::Triple &T);
+
   /// Parse command line options that map to CodeGenOptions.
   static bool ParseCodeGenArgs(CodeGenOptions &Opts, llvm::opt::ArgList &Args,
                                InputKind IK, DiagnosticsEngine &Diags,
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1401,8 +1401,7 @@
                       Flags<[CoreOption, NoXarchOption]>;
 def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">,
                           Group<f_clang_Group>,
-                          HelpText<"Path to blacklist file for sanitizers">,
-                          MarshallingInfoStringVector<LangOpts<"SanitizerBlacklistFiles">>;
+                          HelpText<"Path to blacklist file for sanitizers">;
 def fsanitize_system_blacklist : Joined<["-"], "fsanitize-system-blacklist=">,
   HelpText<"Path to system blacklist file for sanitizers">,
   Flags<[CC1Option]>;
@@ -2137,8 +2136,7 @@
 def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>;
 def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
 def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>,
-  HelpText<"Parse OpenMP pragmas and generate parallel code.">,
-  MarshallingInfoFlag<LangOpts<"OpenMP">, "0u">, Normalizer<"makeFlagToValueNormalizer(50u)">;
+  HelpText<"Parse OpenMP pragmas and generate parallel code.">;
 def fno_openmp : Flag<["-"], "fno-openmp">, Group<f_Group>, Flags<[NoArgumentUnused]>;
 def fopenmp_version_EQ : Joined<["-"], "fopenmp-version=">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
 def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>;
Index: clang/include/clang/Basic/Sanitizers.h
===================================================================
--- clang/include/clang/Basic/Sanitizers.h
+++ clang/include/clang/Basic/Sanitizers.h
@@ -178,6 +178,10 @@
 /// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
 SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
 
+/// Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
+void serializeSanitizerSet(SanitizerSet Set,
+                           SmallVectorImpl<StringRef> &Values);
+
 /// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
 /// this group enables.
 SanitizerMask expandSanitizerGroups(SanitizerMask Kinds);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to