namespace llvm {
+class StringSaver;
+
/// cl Namespace - This namespace contains all of the command line option
/// processing machinery. It is intentionally a short name to make qualified
/// usage concise.
unsigned AdditionalVals; // Greater than 0 for multi-valued option.
public:
- const char *ArgStr; // The argument string itself (ex: "help", "o")
- const char *HelpStr; // The descriptive text message for -help
- const char *ValueStr; // String describing what the value of this option is
+ StringRef ArgStr; // The argument string itself (ex: "help", "o")
+ StringRef HelpStr; // The descriptive text message for -help
+ StringRef ValueStr; // String describing what the value of this option is
OptionCategory *Category; // The Category this option belongs to
bool FullyInitialized; // Has addArguemnt been called?
inline unsigned getNumAdditionalVals() const { return AdditionalVals; }
// hasArgStr - Return true if the argstr != ""
- bool hasArgStr() const { return ArgStr[0] != 0; }
+ bool hasArgStr() const { return !ArgStr.empty(); }
//-------------------------------------------------------------------------===
// Accessor functions set by OptionModifiers
//
- void setArgStr(const char *S);
- void setDescription(const char *S) { HelpStr = S; }
- void setValueStr(const char *S) { ValueStr = S; }
+ void setArgStr(StringRef S);
+ void setDescription(StringRef S) { HelpStr = S; }
+ void setValueStr(StringRef S) { ValueStr = S; }
void setNumOccurrencesFlag(enum NumOccurrencesFlag Val) { Occurrences = Val; }
void setValueExpectedFlag(enum ValueExpected Val) { Value = Val; }
void setHiddenFlag(enum OptionHidden Val) { HiddenFlag = Val; }
virtual void printOptionValue(size_t GlobalWidth, bool Force) const = 0;
- virtual void getExtraOptionNames(SmallVectorImpl<const char *> &) {}
+ virtual void getExtraOptionNames(SmallVectorImpl<StringRef> &) {}
// addOccurrence - Wrapper around handleOccurrence that enforces Flags.
//
// Support value comparison outside the template.
struct GenericOptionValue {
- virtual ~GenericOptionValue() {}
virtual bool compare(const GenericOptionValue &V) const = 0;
+protected:
+ ~GenericOptionValue() = default;
+ GenericOptionValue() = default;
+ GenericOptionValue(const GenericOptionValue&) = default;
+ GenericOptionValue &operator=(const GenericOptionValue &) = default;
+
private:
virtual void anchor();
};
bool compare(const GenericOptionValue & /*V*/) const override {
return false;
}
+
+protected:
+ ~OptionValueBase() = default;
};
// Simple copy of the option value.
DataType Value;
bool Valid;
+protected:
+ ~OptionValueCopy() = default;
+ OptionValueCopy(const OptionValueCopy&) = default;
+ OptionValueCopy &operator=(const OptionValueCopy&) = default;
+
public:
OptionValueCopy() : Valid(false) {}
template <class DataType>
struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> {
typedef DataType WrapperType;
+
+protected:
+ ~OptionValueBase() = default;
+ OptionValueBase() = default;
+ OptionValueBase(const OptionValueBase&) = default;
+ OptionValueBase &operator=(const OptionValueBase&) = default;
};
// Top-level option class.
template <class DataType>
-struct OptionValue : OptionValueBase<DataType, std::is_class<DataType>::value> {
- OptionValue() {}
+struct OptionValue final
+ : OptionValueBase<DataType, std::is_class<DataType>::value> {
+ OptionValue() = default;
OptionValue(const DataType &V) { this->setValue(V); }
// Some options may take their value from a different data type.
// Other safe-to-copy-by-value common option types.
enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE };
template <>
-struct OptionValue<cl::boolOrDefault> : OptionValueCopy<cl::boolOrDefault> {
+struct OptionValue<cl::boolOrDefault> final
+ : OptionValueCopy<cl::boolOrDefault> {
typedef cl::boolOrDefault WrapperType;
OptionValue() {}
void anchor() override;
};
-template <> struct OptionValue<std::string> : OptionValueCopy<std::string> {
+template <>
+struct OptionValue<std::string> final : OptionValueCopy<std::string> {
typedef StringRef WrapperType;
OptionValue() {}
void initialize() {}
- void getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) {
+ void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) {
// If there has been no argstr specified, that means that we need to add an
// argument for every possible option. This ensures that our options are
// vectored to us.
//
class basic_parser_impl { // non-template implementation of basic_parser<t>
public:
- basic_parser_impl(Option &O) {}
+ basic_parser_impl(Option &) {}
- virtual ~basic_parser_impl() {}
enum ValueExpected getValueExpectedFlagDefault() const {
return ValueRequired;
}
- void getExtraOptionNames(SmallVectorImpl<const char *> &) {}
+ void getExtraOptionNames(SmallVectorImpl<StringRef> &) {}
void initialize() {}
virtual void anchor();
protected:
+ ~basic_parser_impl() = default;
// A helper for basic_parser::printOptionDiff.
void printOptionName(const Option &O, size_t GlobalWidth) const;
};
basic_parser(Option &O) : basic_parser_impl(O) {}
typedef DataType parser_data_type;
typedef OptionValue<DataType> OptVal;
+
+protected:
+ // Workaround Clang PR22793
+ ~basic_parser() {}
};
//--------------------------------------------------
// parser<bool>
//
-template <> class parser<bool> : public basic_parser<bool> {
+template <> class parser<bool> final : public basic_parser<bool> {
public:
parser(Option &O) : basic_parser(O) {}
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
+extern template class basic_parser<bool>;
//--------------------------------------------------
// parser<boolOrDefault>
-template <> class parser<boolOrDefault> : public basic_parser<boolOrDefault> {
+template <>
+class parser<boolOrDefault> final : public basic_parser<boolOrDefault> {
public:
parser(Option &O) : basic_parser(O) {}
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
+extern template class basic_parser<boolOrDefault>;
//--------------------------------------------------
// parser<int>
//
-template <> class parser<int> : public basic_parser<int> {
+template <> class parser<int> final : public basic_parser<int> {
public:
parser(Option &O) : basic_parser(O) {}
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
+extern template class basic_parser<int>;
//--------------------------------------------------
// parser<unsigned>
//
-template <> class parser<unsigned> : public basic_parser<unsigned> {
+template <> class parser<unsigned> final : public basic_parser<unsigned> {
public:
parser(Option &O) : basic_parser(O) {}
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
+extern template class basic_parser<unsigned>;
//--------------------------------------------------
// parser<unsigned long long>
//
template <>
-class parser<unsigned long long> : public basic_parser<unsigned long long> {
+class parser<unsigned long long> final
+ : public basic_parser<unsigned long long> {
public:
parser(Option &O) : basic_parser(O) {}
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>);
+extern template class basic_parser<unsigned long long>;
//--------------------------------------------------
// parser<double>
//
-template <> class parser<double> : public basic_parser<double> {
+template <> class parser<double> final : public basic_parser<double> {
public:
parser(Option &O) : basic_parser(O) {}
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
+extern template class basic_parser<double>;
//--------------------------------------------------
// parser<float>
//
-template <> class parser<float> : public basic_parser<float> {
+template <> class parser<float> final : public basic_parser<float> {
public:
parser(Option &O) : basic_parser(O) {}
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
+extern template class basic_parser<float>;
//--------------------------------------------------
// parser<std::string>
//
-template <> class parser<std::string> : public basic_parser<std::string> {
+template <> class parser<std::string> final : public basic_parser<std::string> {
public:
parser(Option &O) : basic_parser(O) {}
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
+extern template class basic_parser<std::string>;
//--------------------------------------------------
// parser<char>
//
-template <> class parser<char> : public basic_parser<char> {
+template <> class parser<char> final : public basic_parser<char> {
public:
parser(Option &O) : basic_parser(O) {}
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>);
+extern template class basic_parser<char>;
//--------------------------------------------------
// PrintOptionDiff
// This is instantiated for basic parsers when the parsed value has a different
// type than the option value. e.g. HelpPrinter.
template <class ParserDT, class ValDT> struct OptionDiffPrinter {
- void print(const Option &O, const parser<ParserDT> P, const ValDT & /*V*/,
+ void print(const Option &O, const parser<ParserDT> &P, const ValDT & /*V*/,
const OptionValue<ValDT> & /*Default*/, size_t GlobalWidth) {
P.printOptionNoValue(O, GlobalWidth);
}
// This is instantiated for basic parsers when the parsed value has the same
// type as the option value.
template <class DT> struct OptionDiffPrinter<DT, DT> {
- void print(const Option &O, const parser<DT> P, const DT &V,
+ void print(const Option &O, const parser<DT> &P, const DT &V,
const OptionValue<DT> &Default, size_t GlobalWidth) {
P.printOptionDiff(O, V, Default, GlobalWidth);
}
enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
- void
- getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) override {
+ void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override {
return Parser.getExtraOptionNames(OptionNames);
}
}
};
-EXTERN_TEMPLATE_INSTANTIATION(class opt<unsigned>);
-EXTERN_TEMPLATE_INSTANTIATION(class opt<int>);
-EXTERN_TEMPLATE_INSTANTIATION(class opt<std::string>);
-EXTERN_TEMPLATE_INSTANTIATION(class opt<char>);
-EXTERN_TEMPLATE_INSTANTIATION(class opt<bool>);
+extern template class opt<unsigned>;
+extern template class opt<int>;
+extern template class opt<std::string>;
+extern template class opt<char>;
+extern template class opt<bool>;
//===----------------------------------------------------------------------===//
// list_storage class
}
};
-// Define how to hold a class type object, such as a string. Since we can
-// inherit from a class, we do so. This makes us exactly compatible with the
-// object in all cases that it is used.
+// Define how to hold a class type object, such as a string.
+// Originally this code inherited from std::vector. In transitioning to a new
+// API for command line options we should change this. The new implementation
+// of this list_storage specialization implements the minimum subset of the
+// std::vector API required for all the current clients.
//
-template <class DataType>
-class list_storage<DataType, bool> : public std::vector<DataType> {
+// FIXME: Reduce this API to a more narrow subset of std::vector
+//
+template <class DataType> class list_storage<DataType, bool> {
+ std::vector<DataType> Storage;
+
public:
- template <class T> void addValue(const T &V) {
- std::vector<DataType>::push_back(V);
+ typedef typename std::vector<DataType>::iterator iterator;
+
+ iterator begin() { return Storage.begin(); }
+ iterator end() { return Storage.end(); }
+
+ typedef typename std::vector<DataType>::const_iterator const_iterator;
+ const_iterator begin() const { return Storage.begin(); }
+ const_iterator end() const { return Storage.end(); }
+
+ typedef typename std::vector<DataType>::size_type size_type;
+ size_type size() const { return Storage.size(); }
+
+ bool empty() const { return Storage.empty(); }
+
+ void push_back(const DataType &value) { Storage.push_back(value); }
+ void push_back(DataType &&value) { Storage.push_back(value); }
+
+ typedef typename std::vector<DataType>::reference reference;
+ typedef typename std::vector<DataType>::const_reference const_reference;
+ reference operator[](size_type pos) { return Storage[pos]; }
+ const_reference operator[](size_type pos) const { return Storage[pos]; }
+
+ iterator erase(const_iterator pos) { return Storage.erase(pos); }
+ iterator erase(const_iterator first, const_iterator last) {
+ return Storage.erase(first, last);
+ }
+
+ iterator erase(iterator pos) { return Storage.erase(pos); }
+ iterator erase(iterator first, iterator last) {
+ return Storage.erase(first, last);
+ }
+
+ iterator insert(const_iterator pos, const DataType &value) {
+ return Storage.insert(pos, value);
+ }
+ iterator insert(const_iterator pos, DataType &&value) {
+ return Storage.insert(pos, value);
+ }
+
+ iterator insert(iterator pos, const DataType &value) {
+ return Storage.insert(pos, value);
+ }
+ iterator insert(iterator pos, DataType &&value) {
+ return Storage.insert(pos, value);
}
+
+ reference front() { return Storage.front(); }
+ const_reference front() const { return Storage.front(); }
+
+ operator std::vector<DataType>&() { return Storage; }
+ operator ArrayRef<DataType>() { return Storage; }
+ std::vector<DataType> *operator&() { return &Storage; }
+ const std::vector<DataType> *operator&() const { return &Storage; }
+
+ template <class T> void addValue(const T &V) { Storage.push_back(V); }
};
//===----------------------------------------------------------------------===//
// list - A list of command line options.
//
-template <class DataType, class Storage = bool,
+template <class DataType, class StorageClass = bool,
class ParserClass = parser<DataType>>
-class list : public Option, public list_storage<DataType, Storage> {
+class list : public Option, public list_storage<DataType, StorageClass> {
std::vector<unsigned> Positions;
ParserClass Parser;
enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
- void
- getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) override {
+ void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override {
return Parser.getExtraOptionNames(OptionNames);
}
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
return true; // Parse Error!
- list_storage<DataType, Storage>::addValue(Val);
+ list_storage<DataType, StorageClass>::addValue(Val);
setPosition(pos);
Positions.push_back(pos);
return false;
enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
- void
- getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) override {
+ void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override {
return Parser.getExtraOptionNames(OptionNames);
}
// Standalone command line processing utilities.
//
-/// \brief Saves strings in the inheritor's stable storage and returns a stable
-/// raw character pointer.
-class StringSaver {
- virtual void anchor();
-
-public:
- virtual const char *SaveString(const char *Str) = 0;
- virtual ~StringSaver(){}; // Pacify -Wnon-virtual-dtor.
-};
-
/// \brief Tokenizes a command line that can contain escapes and quotes.
//
/// The quoting rules match those used by GCC and other tools that use