From 09b51c348c9966bb6472f509bcf790ca98f8150c Mon Sep 17 00:00:00 2001 From: Mikhail Glushenkov Date: Fri, 30 May 2008 06:27:02 +0000 Subject: Refactoring: split CollectProperties into two separate function objects. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51756 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/LLVMCConfigurationEmitter.cpp | 363 +++++++++++++++++---------- 1 file changed, 226 insertions(+), 137 deletions(-) (limited to 'utils/TableGen/LLVMCConfigurationEmitter.cpp') diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp index 77daf627a2..b16d841f1a 100644 --- a/utils/TableGen/LLVMCConfigurationEmitter.cpp +++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp @@ -251,6 +251,19 @@ struct GlobalOptionDescriptions { throw OptName + ": no such option!"; } + // Insert new GlobalOptionDescription into GlobalOptionDescriptions list + void insertDescription (const GlobalOptionDescription& o) + { + container_type::iterator I = Descriptions.find(o.Name); + if (I != Descriptions.end()) { + GlobalOptionDescription& D = I->second; + D.Merge(o); + } + else { + Descriptions[o.Name] = o; + } + } + // Support for STL-style iteration const_iterator begin() const { return Descriptions.begin(); } const_iterator end() const { return Descriptions.end(); } @@ -348,12 +361,171 @@ struct ToolProperties : public RefCountedBase { typedef std::vector > ToolPropertiesList; +/// CollectOptionProperties - Function object for iterating over a +/// list (usually, a DAG) of option property records. +class CollectOptionProperties { +private: + // Implementation details. + + /// OptionPropertyHandler - a function that extracts information + /// about a given option property from its DAG representation. + typedef void (CollectOptionProperties::* OptionPropertyHandler) + (const DagInit*); + + /// OptionPropertyHandlerMap - A map from option property names to + /// option property handlers + typedef StringMap OptionPropertyHandlerMap; + + static OptionPropertyHandlerMap optionPropertyHandlers_; + static bool staticMembersInitialized_; + + /// This is where the information is stored + + /// toolProps_ - Properties of the current Tool. + ToolProperties* toolProps_; + /// optDescs_ - OptionDescriptions table (used to register options + /// globally). + GlobalOptionDescription& optDesc_; + +public: + + explicit CollectOptionProperties(ToolProperties* TP, + GlobalOptionDescription& OD) + : toolProps_(TP), optDesc_(OD) + { + if (!staticMembersInitialized_) { + optionPropertyHandlers_["append_cmd"] = + &CollectOptionProperties::onAppendCmd; + optionPropertyHandlers_["forward"] = + &CollectOptionProperties::onForward; + optionPropertyHandlers_["help"] = + &CollectOptionProperties::onHelp; + optionPropertyHandlers_["output_suffix"] = + &CollectOptionProperties::onOutputSuffix; + optionPropertyHandlers_["required"] = + &CollectOptionProperties::onRequired; + optionPropertyHandlers_["stop_compilation"] = + &CollectOptionProperties::onStopCompilation; + optionPropertyHandlers_["unpack_values"] = + &CollectOptionProperties::onUnpackValues; + + staticMembersInitialized_ = true; + } + } + + /// operator() - Gets called for every option property; Just forwards + /// to the corresponding property handler. + void operator() (Init* i) { + const DagInit& option_property = InitPtrToDag(i); + const std::string& option_property_name + = option_property.getOperator()->getAsString(); + OptionPropertyHandlerMap::iterator method + = optionPropertyHandlers_.find(option_property_name); + + if (method != optionPropertyHandlers_.end()) { + OptionPropertyHandler h = method->second; + (this->*h)(&option_property); + } + else { + throw "Unknown option property: " + option_property_name + "!"; + } + } + +private: + + /// Option property handlers -- + /// Methods that handle properties that are common for all types of + /// options (like append_cmd, stop_compilation) + + void onAppendCmd (const DagInit* d) { + checkNumberOfArguments(d, 1); + checkToolProps(d); + const std::string& cmd = InitPtrToString(d->getArg(0)); + + toolProps_->OptDescs[optDesc_.Name]. + AddProperty(OptionPropertyType::AppendCmd, cmd); + } + + void onOutputSuffix (const DagInit* d) { + checkNumberOfArguments(d, 1); + checkToolProps(d); + const std::string& suf = InitPtrToString(d->getArg(0)); + + if (toolProps_->OptDescs[optDesc_.Name].Type != OptionType::Switch) + throw "Option " + optDesc_.Name + + " can't have 'output_suffix' property since it isn't a switch!"; + + toolProps_->OptDescs[optDesc_.Name].AddProperty + (OptionPropertyType::OutputSuffix, suf); + } + + void onForward (const DagInit* d) { + checkNumberOfArguments(d, 0); + checkToolProps(d); + toolProps_->OptDescs[optDesc_.Name].setForward(); + } + + void onHelp (const DagInit* d) { + checkNumberOfArguments(d, 1); + const std::string& help_message = InitPtrToString(d->getArg(0)); + + optDesc_.Help = help_message; + } + + void onRequired (const DagInit* d) { + checkNumberOfArguments(d, 0); + checkToolProps(d); + optDesc_.setRequired(); + } + + void onStopCompilation (const DagInit* d) { + checkNumberOfArguments(d, 0); + checkToolProps(d); + if (optDesc_.Type != OptionType::Switch) + throw std::string("Only options of type Switch can stop compilation!"); + toolProps_->OptDescs[optDesc_.Name].setStopCompilation(); + } + + void onUnpackValues (const DagInit* d) { + checkNumberOfArguments(d, 0); + checkToolProps(d); + toolProps_->OptDescs[optDesc_.Name].setUnpackValues(); + } + + // Helper functions + + /// checkToolProps - Throw an error if toolProps_ == 0. + void checkToolProps(const DagInit* d) { + if (!d) + throw "Option property " + d->getOperator()->getAsString() + + " can't be used in this context"; + } + +}; + +CollectOptionProperties::OptionPropertyHandlerMap +CollectOptionProperties::optionPropertyHandlers_; + +bool CollectOptionProperties::staticMembersInitialized_ = false; + + +/// processOptionProperties - Go through the list of option +/// properties and call a corresponding handler for each. +void processOptionProperties (const DagInit* d, ToolProperties* t, + GlobalOptionDescription& o) { + checkNumberOfArguments(d, 2); + DagInit::const_arg_iterator B = d->arg_begin(); + // Skip the first argument: it's always the option name. + ++B; + std::for_each(B, d->arg_end(), CollectOptionProperties(t, o)); +} + /// CollectProperties - Function object for iterating over a list of /// tool property records. class CollectProperties { private: - /// Implementation details + // Implementation details /// PropertyHandler - a function that extracts information /// about a given tool property from its DAG representation @@ -363,18 +535,8 @@ private: /// handlers. typedef StringMap PropertyHandlerMap; - /// OptionPropertyHandler - a function that extracts information - /// about a given option property from its DAG representation. - typedef void (CollectProperties::* OptionPropertyHandler) - (const DagInit*, GlobalOptionDescription &); - - /// OptionPropertyHandlerMap - A map from option property names to - /// option property handlers - typedef StringMap OptionPropertyHandlerMap; - // Static maps from strings to CollectProperties methods("handlers") static PropertyHandlerMap propertyHandlers_; - static OptionPropertyHandlerMap optionPropertyHandlers_; static bool staticMembersInitialized_; @@ -392,7 +554,6 @@ public: : toolProps_(p), optDescs_(d) { if (!staticMembersInitialized_) { - // Init tool property handlers propertyHandlers_["cmd_line"] = &CollectProperties::onCmdLine; propertyHandlers_["in_language"] = &CollectProperties::onInLanguage; propertyHandlers_["join"] = &CollectProperties::onJoin; @@ -409,18 +570,6 @@ public: propertyHandlers_["switch_option"] = &CollectProperties::onSwitch; propertyHandlers_["alias_option"] = &CollectProperties::onAlias; - // Init option property handlers - optionPropertyHandlers_["append_cmd"] = &CollectProperties::onAppendCmd; - optionPropertyHandlers_["forward"] = &CollectProperties::onForward; - optionPropertyHandlers_["help"] = &CollectProperties::onHelp; - optionPropertyHandlers_["output_suffix"] = - &CollectProperties::onOutputSuffixOptionProp; - optionPropertyHandlers_["required"] = &CollectProperties::onRequired; - optionPropertyHandlers_["stop_compilation"] = - &CollectProperties::onStopCompilation; - optionPropertyHandlers_["unpack_values"] = - &CollectProperties::onUnpackValues; - staticMembersInitialized_ = true; } } @@ -504,7 +653,7 @@ private: void onAlias (const DagInit* d) { checkNumberOfArguments(d, 2); // We just need a GlobalOptionDescription for the aliases. - insertDescription + optDescs_.insertDescription (GlobalOptionDescription(OptionType::Alias, InitPtrToString(d->getArg(0)), InitPtrToString(d->getArg(1)))); @@ -530,120 +679,24 @@ private: addOption(d, OptionType::PrefixList); } - /// Option property handlers -- - /// Methods that handle properties that are common for all types of - /// options (like append_cmd, stop_compilation) - - void onAppendCmd (const DagInit* d, GlobalOptionDescription& o) { - checkNumberOfArguments(d, 1); - const std::string& cmd = InitPtrToString(d->getArg(0)); - - toolProps_.OptDescs[o.Name].AddProperty(OptionPropertyType::AppendCmd, cmd); - } - - void onOutputSuffixOptionProp (const DagInit* d, GlobalOptionDescription& o) { - checkNumberOfArguments(d, 1); - const std::string& suf = InitPtrToString(d->getArg(0)); - - if (toolProps_.OptDescs[o.Name].Type != OptionType::Switch) - throw "Option " + o.Name - + " can't have 'output_suffix' property since it isn't a switch!"; - - toolProps_.OptDescs[o.Name].AddProperty - (OptionPropertyType::OutputSuffix, suf); - } - - void onForward (const DagInit* d, GlobalOptionDescription& o) { - checkNumberOfArguments(d, 0); - toolProps_.OptDescs[o.Name].setForward(); - } - - void onHelp (const DagInit* d, GlobalOptionDescription& o) { - checkNumberOfArguments(d, 1); - const std::string& help_message = InitPtrToString(d->getArg(0)); - - o.Help = help_message; - } - - void onRequired (const DagInit* d, GlobalOptionDescription& o) { - checkNumberOfArguments(d, 0); - o.setRequired(); - } - - void onStopCompilation (const DagInit* d, GlobalOptionDescription& o) { - checkNumberOfArguments(d, 0); - if (o.Type != OptionType::Switch) - throw std::string("Only options of type Switch can stop compilation!"); - toolProps_.OptDescs[o.Name].setStopCompilation(); - } - - void onUnpackValues (const DagInit* d, GlobalOptionDescription& o) { - checkNumberOfArguments(d, 0); - toolProps_.OptDescs[o.Name].setUnpackValues(); - } - /// Helper functions // Add an option of type t void addOption (const DagInit* d, OptionType::OptionType t) { checkNumberOfArguments(d, 2); - const std::string& name = InitPtrToString(d->getArg(0)); - - GlobalOptionDescription o(t, name); - toolProps_.OptDescs[name].Type = t; - toolProps_.OptDescs[name].Name = name; - processOptionProperties(d, o); - insertDescription(o); - } + const std::string& Name = InitPtrToString(d->getArg(0)); + GlobalOptionDescription OD(t, Name); - // Insert new GlobalOptionDescription into GlobalOptionDescriptions list - void insertDescription (const GlobalOptionDescription& o) - { - if (optDescs_.Descriptions.count(o.Name)) { - GlobalOptionDescription& D = optDescs_.Descriptions[o.Name]; - D.Merge(o); - } - else { - optDescs_.Descriptions[o.Name] = o; - } + toolProps_.OptDescs[Name].Type = t; + toolProps_.OptDescs[Name].Name = Name; + processOptionProperties(d, &toolProps_, OD); + optDescs_.insertDescription(OD); } - /// processOptionProperties - Go through the list of option - /// properties and call a corresponding handler for each. - /// - /// Parameters: - /// name - option name - /// d - option property list - void processOptionProperties (const DagInit* d, GlobalOptionDescription& o) { - // First argument is option name - checkNumberOfArguments(d, 2); - - for (unsigned B = 1, E = d->getNumArgs(); B!=E; ++B) { - const DagInit& option_property - = InitPtrToDag(d->getArg(B)); - const std::string& option_property_name - = option_property.getOperator()->getAsString(); - OptionPropertyHandlerMap::iterator method - = optionPropertyHandlers_.find(option_property_name); - - if (method != optionPropertyHandlers_.end()) { - OptionPropertyHandler h = method->second; - (this->*h)(&option_property, o); - } - else { - throw "Unknown option property: " + option_property_name + "!"; - } - } - } }; -// Static members of CollectProperties -CollectProperties::PropertyHandlerMap -CollectProperties::propertyHandlers_; - -CollectProperties::OptionPropertyHandlerMap -CollectProperties::optionPropertyHandlers_; - +// Defintions of static members of CollectProperties. +CollectProperties::PropertyHandlerMap CollectProperties::propertyHandlers_; bool CollectProperties::staticMembersInitialized_ = false; @@ -670,25 +723,61 @@ void CollectToolProperties (RecordVector::const_iterator B, } } -/// CollectToolPropertiesFromOptionList - Gather information about +/// AddOption - A helper function object used by +/// CollectPropertiesFromOptionList. +// TOFIX: this largely duplicates CollectProperties::addOption, find a +// way to merge them. +class AddOption { +private: + GlobalOptionDescriptions& OptDescs_; + +public: + explicit AddOption(GlobalOptionDescriptions& OD) : OptDescs_(OD) + {} + + void operator()(Init* i) { + const DagInit& d = InitPtrToDag(i); + checkNumberOfArguments(&d, 2); + const std::string& Type = d.getOperator()->getAsString(); + const std::string& Name = InitPtrToString(d.getArg(0)); + GlobalOptionDescription OD(AddOption::getType(Type), Name); + if (OD.Type != OptionType::Alias) + processOptionProperties(&d, 0, OD); + OptDescs_.insertDescription(OD); + } + + OptionType::OptionType getType(const std::string& T) const { + if (T == "alias_option") + return OptionType::Alias; + else if (T == "switch_option") + return OptionType::Switch; + else if (T == "parameter_option") + return OptionType::Parameter; + else if (T == "parameter_list_option") + return OptionType::ParameterList; + else if (T == "prefix_option") + return OptionType::Prefix; + else if (T == "prefix_list_option") + return OptionType::PrefixList; + else + throw "Unknown option type: " + T + '!'; + } +}; + +/// CollectPropertiesFromOptionList - Gather information about /// *global* option properties from the OptionList. -// TOFIX - This is kinda hacky, since it allows to use arbitrary tool -// properties in the OptionList. CollectProperties function object -// should be split into two parts that collect tool and option -// properties, respectively. void CollectPropertiesFromOptionList (RecordVector::const_iterator B, RecordVector::const_iterator E, GlobalOptionDescriptions& OptDescs) { // Iterate over a properties list of every Tool definition - ToolProperties ToolProps("dummy"); + for (;B!=E;++B) { RecordVector::value_type T = *B; // Throws an exception if the value does not exist. ListInit* PropList = T->getValueAsListInit("options"); - std::for_each(PropList->begin(), PropList->end(), - CollectProperties(ToolProps, OptDescs)); + std::for_each(PropList->begin(), PropList->end(), AddOption(OptDescs)); } } -- cgit v1.2.3