ldc/gen/cl_helpers.h
kai ff5759d5dd LLVM 3.7: Fix implementation of FlagParser
The initialization of the parser is now split into a constructor
and the initialize() method which reqires storing a reference to
the option.
Due to some LLVM refactoring, ArgStr must be set using the setter
method.
2015-02-08 00:06:56 +01:00

117 lines
3.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//===-- gen/cl_helpers.h - Command line processing helpers ------*- C++ -*-===//
//
// LDC the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//
//
// Helpers to augment the LLVM command line parsing library with some extra
// functionality.
//
//===----------------------------------------------------------------------===//
#ifndef LDC_GEN_CL_HELPERS_H
#define LDC_GEN_CL_HELPERS_H
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#if LDC_LLVM_VER < 306
#define LLVM_END_WITH_NULL END_WITH_NULL
#endif
template <typename TYPE> struct Array;
typedef Array<const char *> Strings;
namespace opts {
namespace cl = llvm::cl;
/// Helper class for fancier options
class FlagParser : public cl::parser<bool> {
#if LDC_LLVM_VER >= 307
cl::Option &Opt;
#endif
std::vector<std::pair<std::string, bool> > switches;
public:
#if LDC_LLVM_VER >= 307
FlagParser(cl::Option &O) : parser(O), Opt(O) { }
void initialize() {
std::string Name(Opt.ArgStr);
switches.push_back(make_pair("enable-" + Name, true));
switches.push_back(make_pair("disable-" + Name, false));
// Replace <foo> with -enable-<foo> and register -disable-<foo>
// A literal option can only registered if the argstr is empty -
// just do this first.
Opt.setArgStr("");
AddLiteralOption(Opt, strdup(switches[1].first.data()));
Opt.setArgStr(switches[0].first.data());
}
#else
template <class Opt>
void initialize(Opt &O) {
std::string Name = O.ArgStr;
switches.push_back(make_pair("enable-" + Name, true));
switches.push_back(make_pair("disable-" + Name, false));
// Replace <foo> with -enable-<foo>
O.ArgStr = switches[0].first.data();
}
#endif
bool parse(cl::Option &O, llvm::StringRef ArgName, llvm::StringRef ArgValue, bool &Val);
void getExtraOptionNames(llvm::SmallVectorImpl<const char*> &Names);
};
/// Helper class for options that set multiple flags
class MultiSetter {
std::vector<bool*> locations;
bool invert;
MultiSetter(bool); //not implemented, disable auto-conversion
public:
MultiSetter(bool invert, bool* p, ...) LLVM_END_WITH_NULL;
void operator=(bool val);
};
/// Helper class to fill Strings with char* when given strings
/// (Errors on empty strings)
class StringsAdapter {
const char* name;
Strings** arrp;
public:
StringsAdapter(const char* name_, Strings*& arr) {
name = name_;
arrp = &arr;
assert(name);
assert(arrp);
}
void push_back(const char* cstr);
void push_back(const std::string& str) {
push_back(str.c_str());
}
};
/// Helper class to allow use of a parser<bool> with BoolOrDefault
class BoolOrDefaultAdapter {
cl::boolOrDefault value;
public:
operator cl::boolOrDefault() {
return value;
}
void operator=(cl::boolOrDefault val) {
value = val;
}
void operator=(bool val) {
*this = (val ? cl::BOU_TRUE : cl::BOU_FALSE);
}
};
}
#endif