[llvm] 5f609f9 - [Support] Remove cl::bits (#226628)

via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 26 00:44:07 PDT 2026


Author: Fangrui Song
Date: 2026-09-26T00:43:59-07:00
New Revision: 5f609f950d2e80addf5566623013db68394334db

URL: https://github.com/llvm/llvm-project/commit/5f609f950d2e80addf5566623013db68394334db
DIFF: https://github.com/llvm/llvm-project/commit/5f609f950d2e80addf5566623013db68394334db.diff

LOG: [Support] Remove cl::bits (#226628)

cl::list covers the same use, and cl::bits would block migration to
TableGen based representation.

LLM-aided

Added: 
    

Modified: 
    llvm/docs/CommandLine.md
    llvm/include/llvm/Support/CommandLine.h
    llvm/unittests/Support/CommandLineTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/CommandLine.md b/llvm/docs/CommandLine.md
index fb3bccd242382..36f93501cd631 100644
--- a/llvm/docs/CommandLine.md
+++ b/llvm/docs/CommandLine.md
@@ -517,53 +517,6 @@ the list is simple, just like above.  In this example, we used the
 if the user does not specify any `.o` files on our command line.  Again, this
 just reduces the amount of checking we have to do.
 
-### Collecting options as a set of flags
-
-Instead of collecting sets of options in a list, it is also possible to gather
-information for enum values in a **bit vector**.  The representation used by the
-{ref}`cl::bits <cl::bits>` class is an `unsigned` integer.  An enum value is represented by a
-0/1 in the enum's ordinal value bit position. 1 indicating that the enum was
-specified, 0 otherwise.  As each specified value is parsed, the resulting enum's
-bit is set in the option's bit vector:
-
-```cpp
-bits |= 1 << (unsigned)enum;
-```
-
-Options that are specified multiple times are redundant.  Any instances after
-the first are discarded.
-
-Reworking the above list example, we could replace {ref}`cl::list <cl::list>` with {ref}`cl::bits <cl::bits>`:
-
-```cpp
-cl::bits<Opts> OptimizationBits(cl::desc("Available Optimizations:"),
-  cl::values(
-    clEnumVal(dce               , "Dead Code Elimination"),
-    clEnumVal(instsimplify      , "Instruction Simplification"),
-   clEnumValN(inlining, "inline", "Procedure Integration"),
-    clEnumVal(strip             , "Strip Symbols")));
-```
-
-To test to see if `instsimplify` was specified, we can use the `cl:bits::isSet`
-function:
-
-```cpp
-if (OptimizationBits.isSet(instsimplify)) {
-  ...
-}
-```
-
-It's also possible to get the raw bit vector using the `cl::bits::getBits`
-function:
-
-```cpp
-unsigned bits = OptimizationBits.getBits();
-```
-
-Finally, if external storage is used, then the location specified must be of
-**type** `unsigned`. In all other ways a {ref}`cl::bits <cl::bits>` option is equivalent to a
-{ref}`cl::list <cl::list>` option.
-
 (additional extra text)=
 
 ### Adding freeform text to help output
@@ -1324,25 +1277,6 @@ argument is the **type** of the external storage, not a boolean value.  For this
 class, the marker type '`bool`' is used to indicate that internal storage
 should be used.
 
-(cl::bits)=
-
-#### The `cl::bits` class
-
-The `cl::bits` class is the class used to represent a list of command line
-options in the form of a bit vector.  It is also a templated class which can
-take up to three arguments:
-
-```cpp
-namespace cl {
-  template <class DataType, class Storage = bool,
-            class ParserClass = parser<DataType> >
-  class bits;
-}
-```
-
-This class works the exact same as the {ref}`cl::list <cl::list>` class, except that the second
-argument must be of **type** `unsigned` if external storage is used.
-
 (cl::alias)=
 
 #### The `cl::alias` class

diff  --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h
index 63e25183ba376..fc79cbf476462 100644
--- a/llvm/include/llvm/Support/CommandLine.h
+++ b/llvm/include/llvm/Support/CommandLine.h
@@ -1782,151 +1782,6 @@ class list : public Option, public list_storage<DataType, StorageClass> {
   std::function<void(const typename ParserClass::parser_data_type &)> Callback;
 };
 
-//===----------------------------------------------------------------------===//
-// Default storage class definition: external storage.  This implementation
-// assumes the user will specify a variable to store the data into with the
-// cl::location(x) modifier.
-//
-template <class DataType, class StorageClass> class bits_storage {
-  unsigned *Location = nullptr; // Where to store the bits...
-
-  template <class T> static unsigned Bit(const T &V) {
-    unsigned BitPos = static_cast<unsigned>(V);
-    assert(BitPos < sizeof(unsigned) * CHAR_BIT &&
-           "enum exceeds width of bit vector!");
-    return 1 << BitPos;
-  }
-
-public:
-  bits_storage() = default;
-
-  bool setLocation(Option &O, unsigned &L) {
-    if (Location)
-      return O.error("cl::location(x) specified more than once!");
-    Location = &L;
-    return false;
-  }
-
-  template <class T> void addValue(const T &V) {
-    assert(Location != nullptr &&
-           "cl::location(...) not specified for a command "
-           "line option with external storage!");
-    *Location |= Bit(V);
-  }
-
-  unsigned getBits() { return *Location; }
-
-  void clear() {
-    if (Location)
-      *Location = 0;
-  }
-
-  template <class T> bool isSet(const T &V) {
-    return (*Location & Bit(V)) != 0;
-  }
-};
-
-// Define how to hold bits.  Since we can inherit from a class, we do so.
-// This makes us exactly compatible with the bits in all cases that it is used.
-//
-template <class DataType> class bits_storage<DataType, bool> {
-  unsigned Bits{0}; // Where to store the bits...
-
-  template <class T> static unsigned Bit(const T &V) {
-    unsigned BitPos = static_cast<unsigned>(V);
-    assert(BitPos < sizeof(unsigned) * CHAR_BIT &&
-           "enum exceeds width of bit vector!");
-    return 1 << BitPos;
-  }
-
-public:
-  template <class T> void addValue(const T &V) { Bits |= Bit(V); }
-
-  unsigned getBits() { return Bits; }
-
-  void clear() { Bits = 0; }
-
-  template <class T> bool isSet(const T &V) { return (Bits & Bit(V)) != 0; }
-};
-
-//===----------------------------------------------------------------------===//
-// A bit vector of command options.
-//
-template <class DataType, class Storage = bool,
-          class ParserClass = parser<DataType>>
-class bits : public Option, public bits_storage<DataType, Storage> {
-  std::vector<unsigned> Positions;
-  ParserClass Parser;
-
-  enum ValueExpected getValueExpectedFlagDefault() const override {
-    return Parser.getValueExpectedFlagDefault();
-  }
-
-  void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override {
-    return Parser.getExtraOptionNames(OptionNames);
-  }
-
-  bool handleOccurrence(unsigned pos, StringRef ArgName,
-                        StringRef Arg) override {
-    typename ParserClass::parser_data_type Val =
-        typename ParserClass::parser_data_type();
-    if (Parser.parse(*this, ArgName, Arg, Val))
-      return true; // Parse Error!
-    this->addValue(Val);
-    setPosition(pos);
-    Positions.push_back(pos);
-    if (Callback)
-      Callback(Val);
-    return false;
-  }
-
-  // Forward printing stuff to the parser...
-  size_t getOptionWidth() const override {
-    return Parser.getOptionWidth(*this);
-  }
-
-  void printOptionInfo(size_t GlobalWidth) const override {
-    Parser.printOptionInfo(*this, GlobalWidth);
-  }
-
-  // Unimplemented: bits options don't currently store their default values.
-  void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override {
-  }
-
-  void setDefault() override { bits_storage<DataType, Storage>::clear(); }
-
-  void done() {
-    addArgument();
-    Parser.initialize();
-  }
-
-public:
-  // Command line options should not be copyable
-  bits(const bits &) = delete;
-  bits &operator=(const bits &) = delete;
-
-  ParserClass &getParser() { return Parser; }
-
-  unsigned getPosition(unsigned optnum) const {
-    assert(optnum < this->size() && "Invalid option index");
-    return Positions[optnum];
-  }
-
-  template <class... Mods>
-  explicit bits(const Mods &... Ms)
-      : Option(ZeroOrMore, NotHidden), Parser(*this) {
-    apply(this, Ms...);
-    done();
-  }
-
-  void setCallback(
-      std::function<void(const typename ParserClass::parser_data_type &)> CB) {
-    Callback = CB;
-  }
-
-  std::function<void(const typename ParserClass::parser_data_type &)> Callback;
-};
-
 //===----------------------------------------------------------------------===//
 // Aliased command line option (alias this name to a preexisting name)
 //

diff  --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp
index 822b4637c6f64..e4b5bf4853610 100644
--- a/llvm/unittests/Support/CommandLineTest.cpp
+++ b/llvm/unittests/Support/CommandLineTest.cpp
@@ -1895,13 +1895,6 @@ TEST(CommandLineTest, Callback) {
   cl::ResetAllOptionOccurrences();
 }
 
-enum Enum { Val1, Val2 };
-static cl::bits<Enum> ExampleBits(
-    cl::desc("An example cl::bits to ensure it compiles"),
-    cl::values(
-      clEnumValN(Val1, "bits-val1", "The Val1 value"),
-      clEnumValN(Val1, "bits-val2", "The Val2 value")));
-
 TEST(CommandLineTest, ConsumeAfterOnePositional) {
   cl::ResetCommandLineParser();
 
@@ -2052,7 +2045,7 @@ TEST(CommandLineTest, ResetAllOptionOccurrences) {
   StackOption<bool> Option("option");
   StackOption<std::string> Str("str");
   enum Vals { ValA, ValB, ValC };
-  StackOption<Vals, cl::bits<Vals>> Bits(
+  StackOption<Vals, cl::list<Vals>> List(
       cl::values(clEnumValN(ValA, "enableA", "Enable A"),
                  clEnumValN(ValB, "enableB", "Enable B"),
                  clEnumValN(ValC, "enableC", "Enable C")));
@@ -2069,7 +2062,9 @@ TEST(CommandLineTest, ResetAllOptionOccurrences) {
 
   EXPECT_TRUE(Option);
   EXPECT_EQ("STR", Str);
-  EXPECT_EQ((1u << ValA) | (1u << ValC), Bits.getBits());
+  ASSERT_EQ(2u, List.size());
+  EXPECT_EQ(ValA, List[0]);
+  EXPECT_EQ(ValC, List[1]);
   EXPECT_EQ("input", Input);
   EXPECT_EQ(1u, ExtraArgs.size());
   EXPECT_EQ("-arg", ExtraArgs[0]);
@@ -2077,7 +2072,7 @@ TEST(CommandLineTest, ResetAllOptionOccurrences) {
   cl::ResetAllOptionOccurrences();
   EXPECT_FALSE(Option);
   EXPECT_EQ("", Str);
-  EXPECT_EQ(0u, Bits.getBits());
+  EXPECT_TRUE(List.empty());
   EXPECT_EQ(0, Input.getNumOccurrences());
   EXPECT_EQ(0u, ExtraArgs.size());
 }


        


More information about the llvm-commits mailing list