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

Split into two macro kinds.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83071

Files:
  clang/include/clang/Driver/Options.td
  clang/lib/Frontend/CompilerInvocation.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
@@ -61,8 +61,9 @@
 
 class MarshallingInfo {
 public:
-  static constexpr const char *MacroName = "OPTION_WITH_MARSHALLING";
+  using Ptr = std::unique_ptr<MarshallingInfo>;
 
+  const char *MacroName;
   const Record &R;
   bool ShouldAlwaysEmit;
   StringRef KeyPath;
@@ -78,6 +79,8 @@
   std::vector<StringRef> NormalizedValues;
   std::string ValueTableName;
 
+  static size_t NextTableIndex;
+
   static constexpr const char *ValueTablePreamble = R"(
 struct SimpleEnumValue {
   const char *Name;
@@ -93,7 +96,14 @@
   static constexpr const char *ValueTablesDecl =
       "static const SimpleEnumValueTable SimpleEnumValueTables[] = ";
 
-  void emit(raw_ostream &OS) const {
+  MarshallingInfo(const Record &R)
+      : MacroName("OPTION_WITH_MARSHALLING"), R(R) {}
+  MarshallingInfo(const char *MacroName, const Record &R)
+      : MacroName(MacroName), R(R){};
+
+  virtual ~MarshallingInfo() = default;
+
+  virtual void emit(raw_ostream &OS) const {
     write_cstring(OS, StringRef(getOptionSpelling(R)));
     OS << ", ";
     OS << ShouldAlwaysEmit;
@@ -131,53 +141,6 @@
     return StringRef(ValueTableName);
   }
 
-  static MarshallingInfo create(const Record &R) {
-    assert(!isa<UnsetInit>(R.getValueInit("KeyPath")) &&
-           !isa<UnsetInit>(R.getValueInit("DefaultValue")) &&
-           !isa<UnsetInit>(R.getValueInit("NormalizerRetTy")) &&
-           !isa<UnsetInit>(R.getValueInit("ValueMerger")) &&
-           "MarshallingInfo must have a type");
-
-    MarshallingInfo Ret(R);
-    Ret.ShouldAlwaysEmit = R.getValueAsBit("ShouldAlwaysEmit");
-    Ret.KeyPath = R.getValueAsString("KeyPath");
-    Ret.DefaultValue = R.getValueAsString("DefaultValue");
-    Ret.NormalizedValuesScope = R.getValueAsString("NormalizedValuesScope");
-    Ret.NormalizerRetTy = R.getValueAsString("NormalizerRetTy");
-
-    Ret.Normalizer = R.getValueAsString("Normalizer");
-    Ret.Denormalizer = R.getValueAsString("Denormalizer");
-    Ret.ValueMerger = R.getValueAsString("ValueMerger");
-    Ret.ValueExtractor = R.getValueAsString("ValueExtractor");
-
-    if (!isa<UnsetInit>(R.getValueInit("NormalizedValues"))) {
-      assert(!isa<UnsetInit>(R.getValueInit("Values")) &&
-             "Cannot provide normalized values for value-less options");
-      Ret.TableIndex = NextTableIndex++;
-      Ret.NormalizedValues = R.getValueAsListOfStrings("NormalizedValues");
-      Ret.Values.reserve(Ret.NormalizedValues.size());
-      Ret.ValueTableName = getOptionName(R) + "ValueTable";
-
-      StringRef ValuesStr = R.getValueAsString("Values");
-      for (;;) {
-        size_t Idx = ValuesStr.find(',');
-        if (Idx == StringRef::npos)
-          break;
-        if (Idx > 0)
-          Ret.Values.push_back(ValuesStr.slice(0, Idx));
-        ValuesStr = ValuesStr.slice(Idx + 1, StringRef::npos);
-      }
-      if (!ValuesStr.empty())
-        Ret.Values.push_back(ValuesStr);
-
-      assert(Ret.Values.size() == Ret.NormalizedValues.size() &&
-             "The number of normalized values doesn't match the number of "
-             "values");
-    }
-
-    return Ret;
-  }
-
 private:
   void emitScopedNormalizedValue(raw_ostream &OS,
                                  StringRef NormalizedValue) const {
@@ -185,13 +148,79 @@
       OS << NormalizedValuesScope << "::";
     OS << NormalizedValue;
   }
+};
+
+size_t MarshallingInfo::NextTableIndex = 0;
 
-  MarshallingInfo(const Record &R) : R(R){};
+class MarshallingInfoBooleanFlag : public MarshallingInfo {
+public:
+  const Record &NegOption;
 
-  static size_t NextTableIndex;
+  MarshallingInfoBooleanFlag(const Record &Option, const Record &NegOption)
+      : MarshallingInfo("OPTION_WITH_MARSHALLING_BOOLEAN", Option),
+        NegOption(NegOption) {}
+
+  void emit(raw_ostream &OS) const override {
+    MarshallingInfo::emit(OS);
+    OS << ", ";
+    OS << getOptionName(NegOption);
+    OS << ", ";
+    write_cstring(OS, getOptionSpelling(NegOption));
+  }
 };
 
-size_t MarshallingInfo::NextTableIndex = 0;
+static MarshallingInfo::Ptr createMarshallingInfo(const Record &R) {
+  assert(!isa<UnsetInit>(R.getValueInit("KeyPath")) &&
+         !isa<UnsetInit>(R.getValueInit("DefaultValue")) &&
+         !isa<UnsetInit>(R.getValueInit("NormalizerRetTy")) &&
+         !isa<UnsetInit>(R.getValueInit("ValueMerger")) &&
+         "MarshallingInfo must have a type");
+
+  MarshallingInfo::Ptr Ret;
+  if (Record *MaybeNegOption = R.getValueAsOptionalDef("NegOption")) {
+    Ret = std::make_unique<MarshallingInfoBooleanFlag>(R, *MaybeNegOption);
+  } else {
+    Ret = std::make_unique<MarshallingInfo>(R);
+  }
+
+  Ret->ShouldAlwaysEmit = R.getValueAsBit("ShouldAlwaysEmit");
+  Ret->KeyPath = R.getValueAsString("KeyPath");
+  Ret->DefaultValue = R.getValueAsString("DefaultValue");
+  Ret->NormalizedValuesScope = R.getValueAsString("NormalizedValuesScope");
+  Ret->NormalizerRetTy = R.getValueAsString("NormalizerRetTy");
+
+  Ret->Normalizer = R.getValueAsString("Normalizer");
+  Ret->Denormalizer = R.getValueAsString("Denormalizer");
+  Ret->ValueMerger = R.getValueAsString("ValueMerger");
+  Ret->ValueExtractor = R.getValueAsString("ValueExtractor");
+
+  if (!isa<UnsetInit>(R.getValueInit("NormalizedValues"))) {
+    assert(!isa<UnsetInit>(R.getValueInit("Values")) &&
+           "Cannot provide normalized values for value-less options");
+    Ret->TableIndex = MarshallingInfo::NextTableIndex++;
+    Ret->NormalizedValues = R.getValueAsListOfStrings("NormalizedValues");
+    Ret->Values.reserve(Ret->NormalizedValues.size());
+    Ret->ValueTableName = getOptionName(R) + "ValueTable";
+
+    StringRef ValuesStr = R.getValueAsString("Values");
+    for (;;) {
+      size_t Idx = ValuesStr.find(',');
+      if (Idx == StringRef::npos)
+        break;
+      if (Idx > 0)
+        Ret->Values.push_back(ValuesStr.slice(0, Idx));
+      ValuesStr = ValuesStr.slice(Idx + 1, StringRef::npos);
+    }
+    if (!ValuesStr.empty())
+      Ret->Values.push_back(ValuesStr);
+
+    assert(Ret->Values.size() == Ret->NormalizedValues.size() &&
+           "The number of normalized values doesn't match the number of "
+           "values");
+  }
+
+  return Ret;
+}
 
 /// OptParserEmitter - This tablegen backend takes an input .td file
 /// describing a list of options and emits a data structure for parsing and
@@ -381,7 +410,7 @@
       OS << "nullptr";
   };
 
-  std::vector<MarshallingInfo> OptsWithMarshalling;
+  std::vector<MarshallingInfo::Ptr> OptsWithMarshalling;
   for (unsigned I = 0, E = Opts.size(); I != E; ++I) {
     const Record &R = *Opts[I];
 
@@ -391,18 +420,18 @@
     OS << ")\n";
     if (!isa<UnsetInit>(R.getValueInit("KeyPath")) &&
         !R.getValueAsString("KeyPath").empty())
-      OptsWithMarshalling.push_back(MarshallingInfo::create(R));
+      OptsWithMarshalling.push_back(createMarshallingInfo(R));
   }
   OS << "#endif // OPTION\n";
 
   for (const auto &KindInfo : OptsWithMarshalling) {
-    OS << "#ifdef " << KindInfo.MacroName << "\n";
-    OS << KindInfo.MacroName << "(";
-    WriteOptRecordFields(OS, KindInfo.R);
+    OS << "#ifdef " << KindInfo->MacroName << "\n";
+    OS << KindInfo->MacroName << "(";
+    WriteOptRecordFields(OS, KindInfo->R);
     OS << ", ";
-    KindInfo.emit(OS);
+    KindInfo->emit(OS);
     OS << ")\n";
-    OS << "#endif // " << KindInfo.MacroName << "\n";
+    OS << "#endif // " << KindInfo->MacroName << "\n";
   }
 
   OS << "\n";
@@ -411,7 +440,7 @@
   OS << MarshallingInfo::ValueTablePreamble;
   std::vector<StringRef> ValueTableNames;
   for (const auto &KindInfo : OptsWithMarshalling)
-    if (auto MaybeValueTableName = KindInfo.emitValueTable(OS))
+    if (auto MaybeValueTableName = KindInfo->emitValueTable(OS))
       ValueTableNames.push_back(*MaybeValueTableName);
 
   OS << MarshallingInfo::ValueTablesDecl << "{";
Index: llvm/include/llvm/Option/OptParser.td
===================================================================
--- llvm/include/llvm/Option/OptParser.td
+++ llvm/include/llvm/Option/OptParser.td
@@ -97,6 +97,7 @@
   OptionGroup Group = ?;
   Option Alias = ?;
   list<string> AliasArgs = [];
+  string MarshallingInfoKind = ?;
   code KeyPath = ?;
   code DefaultValue = ?;
   bit ShouldAlwaysEmit = 0;
@@ -107,6 +108,8 @@
   code ValueMerger = "mergeForwardValue";
   code ValueExtractor = "extractForwardValue";
   list<code> NormalizedValues = ?;
+  // Used for BooleanFlagKind
+  Option NegOption = ?;
 }
 
 // Helpers for defining options.
@@ -143,6 +146,7 @@
 // Helpers for defining marshalling information.
 
 class MarshallingInfo<code keypath, code defaultvalue> {
+  string MarshallingInfoKind = "Default";
   code KeyPath = keypath;
   code DefaultValue = defaultvalue;
 }
@@ -156,6 +160,7 @@
   : MarshallingInfo<keypath, defaultvalue> {
   code NormalizerRetTy = ty;
   code Normalizer = "normalizeSimpleFlag";
+  code Denormalizer = "denormalizeSimpleFlag";
 }
 
 class MarshallingInfoBitfieldFlag<code keypath, code value> : MarshallingInfoFlag<keypath, "0u", "unsigned"> {
@@ -164,6 +169,15 @@
   code ValueExtractor = "(extractMaskValue<unsigned, decltype("#value#"), "#value#">)";
 }
 
+class MarshallingInfoBooleanFlag<code keypath, code defaultvalue, Option negopt>
+  : MarshallingInfoFlag<keypath, defaultvalue> {
+  bit ShouldAlwaysEmit = 1;
+  string MarshallingInfoKind = "BooleanFlag";
+  code Normalizer = "normalizeBooleanFlag";
+  code Denormalizer = "denormalizeBooleanFlag";
+  Option NegOption = negopt;
+}
+
 // Mixins for additional marshalling attributes.
 
 class IsNegative {
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -138,6 +138,13 @@
   return !Args.hasArg(Opt);
 }
 
+void denormalizeSimpleFlag(SmallVectorImpl<const char *> &Args,
+                           const char *Spelling,
+                           CompilerInvocation::StringAllocator SA,
+                           unsigned TableIndex, unsigned Value) {
+  Args.push_back(Spelling);
+}
+
 template <typename T, T Value>
 static llvm::Optional<T>
 normalizeFlagToValue(OptSpecifier Opt, unsigned TableIndex, const ArgList &Args,
@@ -147,6 +154,27 @@
   return None;
 }
 
+static Optional<bool> normalizeBooleanFlag(OptSpecifier PosOpt,
+                                           OptSpecifier NegOpt,
+                                           unsigned TableIndex,
+                                           const ArgList &Args,
+                                           DiagnosticsEngine &Diags) {
+  if (const Arg *A = Args.getLastArg(PosOpt, NegOpt))
+    return A->getOption().matches(PosOpt);
+  return None;
+}
+
+static void denormalizeBooleanFlag(SmallVectorImpl<const char *> &Args,
+                                   const char *Spelling,
+                                   const char *NegSpelling,
+                                   CompilerInvocation::StringAllocator SA,
+                                   unsigned TableIndex, unsigned Value) {
+  if (Value)
+    Args.push_back(Spelling);
+  else
+    Args.push_back(NegSpelling);
+}
+
 static llvm::Optional<unsigned> normalizeSimpleEnum(OptSpecifier Opt,
                                                     unsigned TableIndex,
                                                     const ArgList &Args,
@@ -169,12 +197,14 @@
 }
 
 static void denormalizeSimpleEnum(SmallVectorImpl<const char *> &Args,
+                                  const char *Spelling,
                                   CompilerInvocation::StringAllocator SA,
                                   unsigned TableIndex, unsigned Value) {
   assert(TableIndex < SimpleEnumValueTablesSize);
   const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex];
   for (int I = 0, E = Table.Size; I != E; ++I) {
     if (Value == Table.Table[I].Value) {
+      Args.push_back(Spelling);
       Args.push_back(Table.Table[I].Name);
       return;
     }
@@ -185,8 +215,10 @@
 }
 
 static void denormalizeString(SmallVectorImpl<const char *> &Args,
+                              const char *Spelling,
                               CompilerInvocation::StringAllocator SA,
                               unsigned TableIndex, const std::string &Value) {
+  Args.push_back(Spelling);
   Args.push_back(SA(Value));
 }
 
@@ -781,10 +813,6 @@
     }
   }
 
-  Opts.ExperimentalNewPassManager = Args.hasFlag(
-      OPT_fexperimental_new_pass_manager, OPT_fno_experimental_new_pass_manager,
-      /* Default */ ENABLE_EXPERIMENTAL_NEW_PASS_MANAGER);
-
   Opts.DebugPassManager =
       Args.hasFlag(OPT_fdebug_pass_manager, OPT_fno_debug_pass_manager,
                    /* Default */ false);
@@ -3636,7 +3664,21 @@
       this->KEYPATH = MERGER(this->KEYPATH, DEFAULT_VALUE);                    \
   }
 
+#define OPTION_WITH_MARSHALLING_BOOLEAN(                                       \
+    PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,        \
+    HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE,  \
+    TYPE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX, NEG_ID,    \
+    NEG_SPELLING)                                                              \
+  {                                                                            \
+    if (auto MaybeValue =                                                      \
+            NORMALIZER(OPT_##ID, OPT_##NEG_ID, TABLE_INDEX, Args, Diags))      \
+      this->KEYPATH = MERGER(this->KEYPATH, static_cast<TYPE>(*MaybeValue));   \
+    else                                                                       \
+      this->KEYPATH = MERGER(this->KEYPATH, DEFAULT_VALUE);                    \
+  }
+
 #include "clang/Driver/Options.inc"
+#undef OPTION_WITH_MARSHALLING_BOOLEAN
 #undef OPTION_WITH_MARSHALLING
   return true;
 }
@@ -3894,16 +3936,22 @@
     TYPE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX)            \
   if (((FLAGS)&options::CC1Option) &&                                          \
       (ALWAYS_EMIT || EXTRACTOR(this->KEYPATH) != DEFAULT_VALUE)) {            \
-    if (Option::KIND##Class == Option::FlagClass) {                            \
-      Args.push_back(SPELLING);                                                \
-    }                                                                          \
-    if (Option::KIND##Class == Option::SeparateClass) {                        \
-      Args.push_back(SPELLING);                                                \
-      DENORMALIZER(Args, SA, TABLE_INDEX, EXTRACTOR(this->KEYPATH));           \
-    }                                                                          \
+    DENORMALIZER(Args, SPELLING, SA, TABLE_INDEX, EXTRACTOR(this->KEYPATH));   \
+  }
+
+#define OPTION_WITH_MARSHALLING_BOOLEAN(                                       \
+    PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,        \
+    HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE,  \
+    TYPE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX, NEG_ID,    \
+    NEG_SPELLING)                                                              \
+  if (((FLAGS)&options::CC1Option) &&                                          \
+      (ALWAYS_EMIT || EXTRACTOR(this->KEYPATH) != DEFAULT_VALUE)) {            \
+    DENORMALIZER(Args, SPELLING, NEG_SPELLING, SA, TABLE_INDEX,                \
+                 EXTRACTOR(this->KEYPATH));                                    \
   }
 
 #include "clang/Driver/Options.inc"
+#undef OPTION_WITH_MARSHALLING_BOOLEAN
 #undef OPTION_WITH_MARSHALLING
 }
 
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -249,6 +249,12 @@
                MarshallingInfoFlag<keypath, "false">;
 }
 
+multiclass BooleanMarshalledFFlag<string name, code keypath, code default_value, string pos_help = "", string neg_help=""> {
+  def fno_#NAME : Flag<["-"], "fno-"#name>, HelpText<neg_help>;
+  def f#NAME : Flag<["-"], "f"#name>, HelpText<pos_help>,
+    MarshallingInfoBooleanFlag<keypath, default_value, !cast<Option>("fno_"#NAME)>;
+}
+
 /////////
 // Options
 
@@ -1257,9 +1263,9 @@
   HelpText<"Enables the global instruction selector">;
 def fexperimental_isel : Flag<["-"], "fexperimental-isel">, Group<f_clang_Group>,
   Alias<fglobal_isel>;
-def fexperimental_new_pass_manager : Flag<["-"], "fexperimental-new-pass-manager">,
-  Group<f_clang_Group>, Flags<[CC1Option]>,
-  HelpText<"Enables an experimental new pass manager in LLVM.">;
+defm experimental_new_pass_manager : BooleanMarshalledFFlag<"experimental-new-pass-manager", "CodeGenOpts.ExperimentalNewPassManager",
+  "static_cast<unsigned>(ENABLE_EXPERIMENTAL_NEW_PASS_MANAGER)", "Enables an experimental new pass manager in LLVM.",
+  "Disables an experimental new pass manager in LLVM.">, Group<f_clang_Group>, Flags<[CC1Option]>;
 def finput_charset_EQ : Joined<["-"], "finput-charset=">, Group<f_Group>;
 def fexec_charset_EQ : Joined<["-"], "fexec-charset=">, Group<f_Group>;
 def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>,
@@ -1537,9 +1543,6 @@
   HelpText<"Disables the global instruction selector">;
 def fno_experimental_isel : Flag<["-"], "fno-experimental-isel">, Group<f_clang_Group>,
   Alias<fno_global_isel>;
-def fno_experimental_new_pass_manager : Flag<["-"], "fno-experimental-new-pass-manager">,
-  Group<f_clang_Group>, Flags<[CC1Option]>,
-  HelpText<"Disables an experimental new pass manager in LLVM.">;
 def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>, Flags<[CC1Option]>,
     HelpText<"Use the given vector functions library">, Values<"Accelerate,MASSV,SVML,none">;
 def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D83071: Add suppor... Daniel Grumberg via Phabricator via cfe-commits

Reply via email to