dang updated this revision to Diff 263796.
dang added a comment.

Upload the right patch


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D79796

Files:
  clang/include/clang/Driver/CC1Options.td
  clang/include/clang/Frontend/CompilerInvocation.h
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/unittests/Frontend/CMakeLists.txt
  clang/unittests/Frontend/CompilerInvocationTest.cpp
  llvm/include/llvm/Option/OptParser.td
  llvm/utils/TableGen/OptParserEmitter.cpp

Index: llvm/utils/TableGen/OptParserEmitter.cpp
===================================================================
--- llvm/utils/TableGen/OptParserEmitter.cpp
+++ llvm/utils/TableGen/OptParserEmitter.cpp
@@ -33,6 +33,20 @@
   return OS;
 }
 
+static void EmitMarshallingInfo(raw_ostream &OS, const Record &R) {
+  OS << R.getValueAsString("KeyPath");
+  OS << ", ";
+  if (!isa<UnsetInit>(R.getValueInit("IsPositive")))
+    OS << R.getValueAsBit("IsPositive");
+  else
+    OS << "INVALID";
+  OS << ", ";
+  if (!isa<UnsetInit>(R.getValueInit("DefaultValue")))
+    OS << R.getValueAsString("DefaultValue");
+  else
+    OS << "INVALID";
+}
+
 /// OptParserEmitter - This tablegen backend takes an input .td file
 /// describing a list of options and emits a data structure for parsing and
 /// working with those options when given an input command line.
@@ -135,12 +149,8 @@
 
   OS << "//////////\n";
   OS << "// Options\n\n";
-  for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
-    const Record &R = *Opts[i];
-
-    // Start a single option entry.
-    OS << "OPTION(";
 
+  auto WriteOptRecordFields = [&](raw_ostream &OS, const Record &R) {
     // The option prefix;
     std::vector<StringRef> prf = R.getValueAsListOfStrings("Prefixes");
     OS << Prefixes[PrefixKeyT(prf.begin(), prf.end())] << ", ";
@@ -149,7 +159,7 @@
     write_cstring(OS, R.getValueAsString("Name"));
 
     // The option identifier name.
-    OS  << ", "<< getOptionName(R);
+    OS << ", " << getOptionName(R);
 
     // The option kind.
     OS << ", " << R.getValueAsDef("Kind")->getValueAsString("Name");
@@ -190,8 +200,7 @@
     int NumFlags = 0;
     const ListInit *LI = R.getValueAsListInit("Flags");
     for (Init *I : *LI)
-      OS << (NumFlags++ ? " | " : "")
-         << cast<DefInit>(I)->getDef()->getName();
+      OS << (NumFlags++ ? " | " : "") << cast<DefInit>(I)->getDef()->getName();
     if (GroupFlags) {
       for (Init *I : *GroupFlags)
         OS << (NumFlags++ ? " | " : "")
@@ -224,11 +233,33 @@
       write_cstring(OS, R.getValueAsString("Values"));
     else
       OS << "nullptr";
+  };
+
+  for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
+    const Record &R = *Opts[i];
 
+    // Start a single option entry.
+    OS << "OPTION(";
+    WriteOptRecordFields(OS, R);
     OS << ")\n";
   }
   OS << "#endif // OPTION\n";
 
+  OS << "#ifdef OPTION_WITH_MARSHALLING\n";
+  for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
+    const Record &R = *Opts[i];
+
+    if (!isa<UnsetInit>(R.getValueInit("MarshallingInfo"))) {
+      OS << "OPTION_WITH_MARSHALLING(";
+      WriteOptRecordFields(OS, R);
+      OS << ", ";
+      EmitMarshallingInfo(
+          OS, *cast<DefInit>(R.getValueInit("MarshallingInfo"))->getDef());
+      OS << ")\n";
+    }
+  }
+  OS << "#endif // OPTION_WITH_MARSHALLING\n";
+
   OS << "\n";
   OS << "#ifdef OPTTABLE_ARG_INIT\n";
   OS << "//////////\n";
@@ -252,8 +283,8 @@
             "OptTable!\");\n";
     }
     OS << "}\n";
+    }
+    OS << "\n";
+    OS << "#endif // OPTTABLE_ARG_INIT\n";
   }
-  OS << "\n";
-  OS << "#endif // OPTTABLE_ARG_INIT\n";
-}
 } // end namespace llvm
Index: llvm/include/llvm/Option/OptParser.td
===================================================================
--- llvm/include/llvm/Option/OptParser.td
+++ llvm/include/llvm/Option/OptParser.td
@@ -80,6 +80,16 @@
   list<OptionFlag> Flags = [];
 }
 
+// Add support for generating marshalling code
+
+class OptionMarshallingInfo<code keypath> {
+  code KeyPath = keypath;
+  // Used by the Flag option kind.
+  bit IsPositive = ?;
+  code DefaultValue = ?;
+  list<code> EnumValues = ?;
+}
+
 // Define the option class.
 
 class Option<list<string> prefixes, string name, OptionKind kind> {
@@ -97,6 +107,7 @@
   OptionGroup Group = ?;
   Option Alias = ?;
   list<string> AliasArgs = [];
+  OptionMarshallingInfo MarshallingInfo = ?;
 }
 
 // Helpers for defining options.
@@ -130,6 +141,22 @@
 class Values<string value> { string Values = value; }
 class ValuesCode<code valuecode> { code ValuesCode = valuecode; }
 
+class MarshallingInfo<OptionMarshallingInfo info> { OptionMarshallingInfo MarshallingInfo = info; }
+class MarshallingFlag<code keypath, bit ispositive, code defaultvalue>
+  : OptionMarshallingInfo<keypath> {
+  bit IsPositive = ispositive;
+  code DefaultValue = defaultvalue;
+}
+class MarshallingString<code keypath, code defaultvalue>
+  : OptionMarshallingInfo<keypath> {
+  code DefaultValue = defaultvalue;
+}
+class MarshallingEnum<code keypath, code defaultvalue, list<code> enumvalues>
+  : OptionMarshallingInfo<keypath> {
+  code DefaultValue = defaultvalue;
+  list<code>EnumValues = enumvalues;
+}
+
 // Predefined options.
 
 // FIXME: Have generator validate that these appear in correct position (and
Index: clang/unittests/Frontend/CompilerInvocationTest.cpp
===================================================================
--- /dev/null
+++ clang/unittests/Frontend/CompilerInvocationTest.cpp
@@ -0,0 +1,38 @@
+//===- unittests/Frontend/CompilerInvocationTest.cpp - CI tests //---------===//
+//
+// 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/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace clang;
+
+namespace {
+
+TEST(CompilerInvocation, CanGenerateCC1CommandLine) {
+  const char *Args[] = {"clang", "-xc++", "-fmodules-strict-context-hash", "-"};
+
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
+      CompilerInstance::createDiagnostics(new DiagnosticOptions());
+
+  CompilerInvocation CInvok;
+  CompilerInvocation::CreateFromArgs(CInvok, Args, *Diags);
+
+  SmallVector<const char *, 32> GeneratedArgs;
+  SmallVector<std::string, 32> GeneratedArgsStorage;
+  auto StringAlloc = [&GeneratedArgsStorage](const Twine &Arg) {
+    return GeneratedArgsStorage.emplace_back(Arg.str()).c_str();
+  };
+
+  CInvok.generateCC1CommandLine(GeneratedArgs, StringAlloc);
+
+  ASSERT_STREQ(GeneratedArgs[0], "-fmodules-strict-context-hash");
+}
+
+} // anonymous namespace
Index: clang/unittests/Frontend/CMakeLists.txt
===================================================================
--- clang/unittests/Frontend/CMakeLists.txt
+++ clang/unittests/Frontend/CMakeLists.txt
@@ -4,6 +4,7 @@
 
 add_clang_unittest(FrontendTests
   ASTUnitTest.cpp
+  CompilerInvocationTest.cpp
   CompilerInstanceTest.cpp
   FixedPointString.cpp
   FrontendActionTest.cpp
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -51,6 +51,7 @@
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
@@ -2105,7 +2106,6 @@
     Opts.AddPrebuiltModulePath(A->getValue());
   Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);
   Opts.ModulesHashContent = Args.hasArg(OPT_fmodules_hash_content);
-  Opts.ModulesStrictContextHash = Args.hasArg(OPT_fmodules_strict_context_hash);
   Opts.ModulesValidateDiagnosticOptions =
       !Args.hasArg(OPT_fmodules_disable_diagnostic_validation);
   Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps);
@@ -3600,6 +3600,15 @@
   unsigned MissingArgIndex, MissingArgCount;
   InputArgList Args = Opts.ParseArgs(CommandLineArgs, MissingArgIndex,
                                      MissingArgCount, IncludedFlagsBitmask);
+
+#define OPTION_WITH_MARSHALLING(PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS,     \
+                                ALIASARGS, FLAGS, PARAM, HELPTEXT, METAVAR,    \
+                                VALUES, KEYPATH, IS_POSITIVE, DEFAULT_VALUE)   \
+  if (Option::KIND##Class == Option::FlagClass)                                \
+    Res.KEYPATH = Args.hasArg(OPT_##ID) && IS_POSITIVE;
+#include "clang/Driver/Options.inc"
+#undef OPTION_WITH_MARSHALLING
+
   LangOptions &LangOpts = *Res.getLangOpts();
 
   // Check for missing argument error.
@@ -3823,6 +3832,22 @@
   return llvm::APInt(64, code).toString(36, /*Signed=*/false);
 }
 
+void CompilerInvocation::generateCC1CommandLine(
+    SmallVectorImpl<const char *> &Args,
+    llvm::function_ref<const char *(const Twine &)> StringAllocator) const {
+#define PREFIX(PREFIX_TYPE, BRACED_INIT)                                       \
+  const char *PREFIX_TYPE[4] = BRACED_INIT;
+#define OPTION_WITH_MARSHALLING(PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS,     \
+                                ALIASARGS, FLAGS, PARAM, HELPTEXT, METAVAR,    \
+                                VALUES, KEYPATH, IS_POSITIVE, DEFAULT_VALUE)   \
+  if (Option::KIND##Class == Option::FlagClass &&                              \
+      IS_POSITIVE != DEFAULT_VALUE && this->KEYPATH != DEFAULT_VALUE)          \
+    Args.push_back(StringAllocator(Twine(PREFIX_TYPE[0]) + NAME));
+#include "clang/Driver/Options.inc"
+#undef OPTION_WITH_MARSHALLING
+#undef PREFIX
+}
+
 namespace clang {
 
 IntrusiveRefCntPtr<llvm::vfs::FileSystem>
Index: clang/include/clang/Frontend/CompilerInvocation.h
===================================================================
--- clang/include/clang/Frontend/CompilerInvocation.h
+++ clang/include/clang/Frontend/CompilerInvocation.h
@@ -153,6 +153,8 @@
   /// one of the vaild-to-access (albeit arbitrary) states.
   ///
   /// \param [out] Res - The resulting invocation.
+  /// \param [in] CommandLineArgs - Array of argument strings, this should not
+  /// contain "-cc1".
   static bool CreateFromArgs(CompilerInvocation &Res,
                              ArrayRef<const char *> CommandLineArgs,
                              DiagnosticsEngine &Diags);
@@ -183,6 +185,20 @@
   /// identifying the conditions under which the module was built.
   std::string getModuleHash() const;
 
+  /// Generate a cc1-compatible command line arguments from this instance.
+  ///
+  /// \param [out] Args - The generated arguments. Note that the caller is
+  /// responsible for insersting the path to the clang executable and "-cc1" if
+  /// desired.
+  /// \param StringAllocator - A function that given a Twine can allocate
+  /// storage for a given command line argument and return a pointer to the
+  /// newly allocated string. The returned pointer is what gets appended to
+  /// Args.
+  void
+  generateCC1CommandLine(llvm::SmallVectorImpl<const char *> &Args,
+                         llvm::function_ref<const char *(const llvm::Twine &)>
+                             StringAllocator) const;
+
   /// @}
   /// @name Option Subgroups
   /// @{
Index: clang/include/clang/Driver/CC1Options.td
===================================================================
--- clang/include/clang/Driver/CC1Options.td
+++ clang/include/clang/Driver/CC1Options.td
@@ -832,7 +832,8 @@
   HelpText<"Enable hashing the content of a module file">;
 def fmodules_strict_context_hash : Flag<["-"], "fmodules-strict-context-hash">,
   HelpText<"Enable hashing of all compiler options that could impact the "
-           "semantics of a module in an implicit build">;
+           "semantics of a module in an implicit build">,
+  MarshallingInfo<MarshallingFlag<"HeaderSearchOpts->ModulesStrictContextHash", 1, "false">>;
 def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"<directory>">,
   HelpText<"Add directory to the C SYSTEM include search path">;
 def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to