ldc/gen/cl_helpers.h
kai c2c00d00a2 LLVM 3.7: Workaround for the FlagParser problem.
Replaces the FlagParser with llvm:🆑:parser<bool>.

If no one objects then this will be the default implementation
starting with LLVM 3.7.

TODO: The help text still has the footnote for the FlagParser options.
2015-03-15 18:09:23 +01:00

121 lines
3.5 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;
#if LDC_LLVM_VER >= 307
typedef cl::parser<bool> FlagParser;
#else
/// 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);
};
#endif
/// 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