mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
c3480b6f9b
A logic issue existed when validating whether a `cl::opt<T>` was set. This has been addressed by replacing `isDefaultOption` method with `getNumOccurrences`, as the former one was not meant to be used for checking if the option was set or not. Likewise, the default Option itself is written to a `std::string`, in method `get`; the latter is leveraged by `Invokable`.
91 lines
2.3 KiB
C++
91 lines
2.3 KiB
C++
#pragma once
|
|
|
|
//
|
|
// This file is distributed under the MIT License. See LICENSE.md for details.
|
|
//
|
|
|
|
#include "llvm/ADT/StringMap.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
|
|
#include "revng/Support/Assert.h"
|
|
|
|
namespace pipeline {
|
|
|
|
class CLOptionBase {
|
|
public:
|
|
explicit CLOptionBase(llvm::StringRef Name) {
|
|
getRegisteredOptions()[Name] = this;
|
|
}
|
|
virtual ~CLOptionBase() = default;
|
|
virtual bool isSet() const = 0;
|
|
virtual std::string get() const = 0;
|
|
virtual llvm::StringRef name() const = 0;
|
|
|
|
static const CLOptionBase &getOption(llvm::StringRef Name) {
|
|
std::string Msg = "option has not been registered " + Name.str();
|
|
|
|
revng_assert(hasOption(Name), Msg.c_str());
|
|
return *getRegisteredOptions()[Name];
|
|
}
|
|
|
|
static bool hasOption(llvm::StringRef Name) {
|
|
return getRegisteredOptions().count(Name) != 0;
|
|
}
|
|
|
|
private:
|
|
static llvm::StringMap<const CLOptionBase *> &getRegisteredOptions() {
|
|
static llvm::StringMap<const CLOptionBase *> RegisteredOption;
|
|
return RegisteredOption;
|
|
}
|
|
};
|
|
|
|
namespace detail {
|
|
|
|
template<typename T>
|
|
llvm::StringRef typeNameImpl();
|
|
|
|
template<>
|
|
inline llvm::StringRef typeNameImpl<std::string>() {
|
|
return "string";
|
|
}
|
|
|
|
template<>
|
|
inline llvm::StringRef typeNameImpl<int>() {
|
|
return "int";
|
|
}
|
|
|
|
}; // namespace detail
|
|
|
|
template<typename T>
|
|
class CLOptionWrapper : public CLOptionBase {
|
|
public:
|
|
CLOptionWrapper(const CLOptionWrapper &) = delete;
|
|
CLOptionWrapper(CLOptionWrapper &&) = delete;
|
|
CLOptionWrapper &operator=(const CLOptionWrapper &) = delete;
|
|
CLOptionWrapper &operator=(CLOptionWrapper &&) = delete;
|
|
|
|
template<typename... Args>
|
|
CLOptionWrapper(llvm::StringRef InvokableType,
|
|
llvm::StringRef Name,
|
|
Args &&...Arguments) :
|
|
CLOptionBase(Name),
|
|
FullName((InvokableType + "-" + Name).str()),
|
|
Option(llvm::StringRef(FullName), std::forward<Args>(Arguments)...) {}
|
|
|
|
bool isSet() const override { return Option.getNumOccurrences() != 0; }
|
|
std::string get() const override {
|
|
std::string ToReturn;
|
|
llvm::raw_string_ostream SO(ToReturn);
|
|
SO << Option.getValue();
|
|
SO.flush();
|
|
return ToReturn;
|
|
}
|
|
llvm::StringRef name() const override { return Option.ArgStr; }
|
|
|
|
private:
|
|
std::string FullName;
|
|
llvm::cl::opt<T> Option;
|
|
};
|
|
} // namespace pipeline
|