+ void onSetSwitch(const Init* I,
+ unsigned IndentLevel, raw_ostream& O) const {
+ const std::string& OptName = InitPtrToString(I);
+ const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
+
+ if (OptDesc.isSwitch())
+ O.indent(IndentLevel) << OptDesc.GenVariableName() << " = true;\n";
+ else
+ throw "set_option: -" + OptName + " is not a switch option!";
+ }
+
+ void onSetOption(const DagInit& d,
+ unsigned IndentLevel, raw_ostream& O) const
+ {
+ CheckNumberOfArguments(d, 1);
+
+ // 2-argument form: (set_option "A", true), (set_option "B", "C"),
+ // (set_option "D", ["E", "F"])
+ if (d.getNumArgs() == 2) {
+ const OptionDescription& OptDesc =
+ OptDescs_.FindOption(InitPtrToString(d.getArg(0)));
+ const Init* Opt2 = d.getArg(1);
+
+ if (!OptDesc.isSwitch() || typeid(*Opt2) != typeid(StringInit)) {
+ this->onSetOptionImpl(d, IndentLevel, O);
+ return;
+ }
+ }
+
+ // Multiple argument form: (set_option "A"), (set_option "B", "C", "D")
+ this->onEachArgument(d, &EmitPreprocessOptionsCallback::onSetSwitch,
+ IndentLevel, O);
+ }
+
+public:
+
+ EmitPreprocessOptionsCallback(const OptionDescriptions& OptDescs)
+ : OptDescs_(OptDescs)
+ {
+ if (!staticMembersInitialized_) {
+ AddHandler("error", &EmitPreprocessOptionsCallback::onErrorDag);
+ AddHandler("warning", &EmitPreprocessOptionsCallback::onWarningDag);
+ AddHandler("unset_option", &EmitPreprocessOptionsCallback::onUnsetOption);
+ AddHandler("set_option", &EmitPreprocessOptionsCallback::onSetOption);
+
+ staticMembersInitialized_ = true;
+ }
+ }
+
+ void operator()(const Init* I,
+ unsigned IndentLevel, raw_ostream& O) const
+ {
+ InvokeDagInitHandler(this, I, IndentLevel, O);
+ }
+
+};
+
+/// EmitPreprocessOptions - Emit the PreprocessOptions() function.
+void EmitPreprocessOptions (const RecordKeeper& Records,
+ const OptionDescriptions& OptDecs, raw_ostream& O)
+{
+ O << "int PreprocessOptions () {\n";
+
+ const RecordVector& OptionPreprocessors =
+ Records.getAllDerivedDefinitions("OptionPreprocessor");
+
+ for (RecordVector::const_iterator B = OptionPreprocessors.begin(),
+ E = OptionPreprocessors.end(); B!=E; ++B) {
+ DagInit* Case = (*B)->getValueAsDag("preprocessor");
+ EmitCaseConstructHandler(Case, Indent1,
+ EmitPreprocessOptionsCallback(OptDecs),
+ false, OptDecs, O);
+ }
+
+ O << '\n';
+ O.indent(Indent1) << "return 0;\n";