diff options
Diffstat (limited to 'utils/TableGen')
-rw-r--r-- | utils/TableGen/CMakeLists.txt | 1 | ||||
-rw-r--r-- | utils/TableGen/LLVMCConfigurationEmitter.cpp | 3134 | ||||
-rw-r--r-- | utils/TableGen/LLVMCConfigurationEmitter.h | 34 | ||||
-rw-r--r-- | utils/TableGen/TableGen.cpp | 7 |
4 files changed, 0 insertions, 3176 deletions
diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt index 047d731de6..0202f53c42 100644 --- a/utils/TableGen/CMakeLists.txt +++ b/utils/TableGen/CMakeLists.txt @@ -31,7 +31,6 @@ add_llvm_utility(tblgen InstrEnumEmitter.cpp InstrInfoEmitter.cpp IntrinsicEmitter.cpp - LLVMCConfigurationEmitter.cpp NeonEmitter.cpp OptParserEmitter.cpp PseudoLoweringEmitter.cpp diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp deleted file mode 100644 index cd0cbeb1c6..0000000000 --- a/utils/TableGen/LLVMCConfigurationEmitter.cpp +++ /dev/null @@ -1,3134 +0,0 @@ -//===- LLVMCConfigurationEmitter.cpp - Generate LLVMC config ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This tablegen backend is responsible for emitting LLVMC configuration code. -// -//===----------------------------------------------------------------------===// - -#include "LLVMCConfigurationEmitter.h" -#include "Record.h" - -#include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringSet.h" - -#include <algorithm> -#include <cassert> -#include <functional> -#include <stdexcept> -#include <string> -#include <typeinfo> - - -using namespace llvm; - -namespace { - -//===----------------------------------------------------------------------===// -/// Typedefs - -typedef std::vector<Record*> RecordVector; -typedef std::vector<const DagInit*> DagVector; -typedef std::vector<std::string> StrVector; - -//===----------------------------------------------------------------------===// -/// Constants - -// Indentation. -const unsigned TabWidth = 4; -const unsigned Indent1 = TabWidth*1; -const unsigned Indent2 = TabWidth*2; -const unsigned Indent3 = TabWidth*3; -const unsigned Indent4 = TabWidth*4; - -// Default help string. -const char * const DefaultHelpString = "NO HELP MESSAGE PROVIDED"; - -// Name for the "sink" option. -const char * const SinkOptionName = "SinkOption"; - -//===----------------------------------------------------------------------===// -/// Helper functions - -/// Id - An 'identity' function object. -struct Id { - template<typename T0> - void operator()(const T0&) const { - } - template<typename T0, typename T1> - void operator()(const T0&, const T1&) const { - } - template<typename T0, typename T1, typename T2> - void operator()(const T0&, const T1&, const T2&) const { - } -}; - -int InitPtrToInt(const Init* ptr) { - const IntInit& val = dynamic_cast<const IntInit&>(*ptr); - return val.getValue(); -} - -bool InitPtrToBool(const Init* ptr) { - bool ret = false; - const DefInit& val = dynamic_cast<const DefInit&>(*ptr); - const std::string& str = val.getAsString(); - - if (str == "true") { - ret = true; - } - else if (str == "false") { - ret = false; - } - else { - throw "Incorrect boolean value: '" + str + - "': must be either 'true' or 'false'"; - } - - return ret; -} - -const std::string& InitPtrToString(const Init* ptr) { - const StringInit& val = dynamic_cast<const StringInit&>(*ptr); - return val.getValue(); -} - -const ListInit& InitPtrToList(const Init* ptr) { - const ListInit& val = dynamic_cast<const ListInit&>(*ptr); - return val; -} - -const DagInit& InitPtrToDag(const Init* ptr) { - const DagInit& val = dynamic_cast<const DagInit&>(*ptr); - return val; -} - -const std::string GetOperatorName(const DagInit& D) { - return D.getOperator()->getAsString(); -} - -/// CheckBooleanConstant - Check that the provided value is a boolean constant. -void CheckBooleanConstant(const Init* I) { - InitPtrToBool(I); -} - -// CheckNumberOfArguments - Ensure that the number of args in d is -// greater than or equal to min_arguments, otherwise throw an exception. -void CheckNumberOfArguments (const DagInit& d, unsigned minArgs) { - if (d.getNumArgs() < minArgs) - throw GetOperatorName(d) + ": too few arguments!"; -} - -// EscapeVariableName - Escape commas and other symbols not allowed -// in the C++ variable names. Makes it possible to use options named -// like "Wa," (useful for prefix options). -std::string EscapeVariableName (const std::string& Var) { - std::string ret; - for (unsigned i = 0; i != Var.size(); ++i) { - char cur_char = Var[i]; - if (cur_char == ',') { - ret += "_comma_"; - } - else if (cur_char == '+') { - ret += "_plus_"; - } - else if (cur_char == '-') { - ret += "_dash_"; - } - else { - ret.push_back(cur_char); - } - } - return ret; -} - -/// EscapeQuotes - Replace '"' with '\"'. -std::string EscapeQuotes (const std::string& Var) { - std::string ret; - for (unsigned i = 0; i != Var.size(); ++i) { - char cur_char = Var[i]; - if (cur_char == '"') { - ret += "\\\""; - } - else { - ret.push_back(cur_char); - } - } - return ret; -} - -/// OneOf - Does the input string contain this character? -bool OneOf(const char* lst, char c) { - while (*lst) { - if (*lst++ == c) - return true; - } - return false; -} - -template <class I, class S> -void CheckedIncrement(I& P, I E, S ErrorString) { - ++P; - if (P == E) - throw ErrorString; -} - -//===----------------------------------------------------------------------===// -/// Back-end specific code - - -/// OptionType - One of six different option types. See the -/// documentation for detailed description of differences. -namespace OptionType { - - enum OptionType { Alias, Switch, SwitchList, - Parameter, ParameterList, Prefix, PrefixList }; - - bool IsAlias(OptionType t) { - return (t == Alias); - } - - bool IsList (OptionType t) { - return (t == SwitchList || t == ParameterList || t == PrefixList); - } - - bool IsSwitch (OptionType t) { - return (t == Switch); - } - - bool IsSwitchList (OptionType t) { - return (t == SwitchList); - } - - bool IsParameter (OptionType t) { - return (t == Parameter || t == Prefix); - } - -} - -OptionType::OptionType stringToOptionType(const std::string& T) { - if (T == "alias_option") - return OptionType::Alias; - else if (T == "switch_option") - return OptionType::Switch; - else if (T == "switch_list_option") - return OptionType::SwitchList; - 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 + '!'; -} - -namespace OptionDescriptionFlags { - enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2, - ReallyHidden = 0x4, OneOrMore = 0x8, - Optional = 0x10, CommaSeparated = 0x20, - ForwardNotSplit = 0x40, ZeroOrMore = 0x80 }; -} - -/// OptionDescription - Represents data contained in a single -/// OptionList entry. -struct OptionDescription { - OptionType::OptionType Type; - std::string Name; - unsigned Flags; - std::string Help; - unsigned MultiVal; - Init* InitVal; - - OptionDescription(OptionType::OptionType t = OptionType::Switch, - const std::string& n = "", - const std::string& h = DefaultHelpString) - : Type(t), Name(n), Flags(0x0), Help(h), MultiVal(1), InitVal(0) - {} - - /// GenTypeDeclaration - Returns the C++ variable type of this - /// option. - const char* GenTypeDeclaration() const; - - /// GenVariableName - Returns the variable name used in the - /// generated C++ code. - std::string GenVariableName() const - { return "autogenerated::" + GenOptionType() + EscapeVariableName(Name); } - - /// GenPlainVariableName - Returns the variable name without the namespace - /// prefix. - std::string GenPlainVariableName() const - { return GenOptionType() + EscapeVariableName(Name); } - - /// Merge - Merge two option descriptions. - void Merge (const OptionDescription& other); - - /// CheckConsistency - Check that the flags are consistent. - void CheckConsistency() const; - - // Misc convenient getters/setters. - - bool isAlias() const; - - bool isMultiVal() const; - - bool isCommaSeparated() const; - void setCommaSeparated(); - - bool isForwardNotSplit() const; - void setForwardNotSplit(); - - bool isRequired() const; - void setRequired(); - - bool isOneOrMore() const; - void setOneOrMore(); - - bool isZeroOrMore() const; - void setZeroOrMore(); - - bool isOptional() const; - void setOptional(); - - bool isHidden() const; - void setHidden(); - - bool isReallyHidden() const; - void setReallyHidden(); - - bool isSwitch() const - { return OptionType::IsSwitch(this->Type); } - - bool isSwitchList() const - { return OptionType::IsSwitchList(this->Type); } - - bool isParameter() const - { return OptionType::IsParameter(this->Type); } - - bool isList() const - { return OptionType::IsList(this->Type); } - - bool isParameterList() const - { return (OptionType::IsList(this->Type) - && !OptionType::IsSwitchList(this->Type)); } - -private: - - // GenOptionType - Helper function used by GenVariableName(). - std::string GenOptionType() const; -}; - -void OptionDescription::CheckConsistency() const { - unsigned i = 0; - - i += this->isRequired(); - i += this->isOptional(); - i += this->isOneOrMore(); - i += this->isZeroOrMore(); - - if (i > 1) { - throw "Only one of (required), (optional), (one_or_more) or " - "(zero_or_more) properties is allowed!"; - } -} - -void OptionDescription::Merge (const OptionDescription& other) -{ - if (other.Type != Type) - throw "Conflicting definitions for the option " + Name + "!"; - - if (Help == other.Help || Help == DefaultHelpString) - Help = other.Help; - else if (other.Help != DefaultHelpString) { - llvm::errs() << "Warning: several different help strings" - " defined for option " + Name + "\n"; - } - - Flags |= other.Flags; -} - -bool OptionDescription::isAlias() const { - return OptionType::IsAlias(this->Type); -} - -bool OptionDescription::isMultiVal() const { - return MultiVal > 1; -} - -bool OptionDescription::isCommaSeparated() const { - return Flags & OptionDescriptionFlags::CommaSeparated; -} -void OptionDescription::setCommaSeparated() { - Flags |= OptionDescriptionFlags::CommaSeparated; -} - -bool OptionDescription::isForwardNotSplit() const { - return Flags & OptionDescriptionFlags::ForwardNotSplit; -} -void OptionDescription::setForwardNotSplit() { - Flags |= OptionDescriptionFlags::ForwardNotSplit; -} - -bool OptionDescription::isRequired() const { - return Flags & OptionDescriptionFlags::Required; -} -void OptionDescription::setRequired() { - Flags |= OptionDescriptionFlags::Required; -} - -bool OptionDescription::isOneOrMore() const { - return Flags & OptionDescriptionFlags::OneOrMore; -} -void OptionDescription::setOneOrMore() { - Flags |= OptionDescriptionFlags::OneOrMore; -} - -bool OptionDescription::isZeroOrMore() const { - return Flags & OptionDescriptionFlags::ZeroOrMore; -} -void OptionDescription::setZeroOrMore() { - Flags |= OptionDescriptionFlags::ZeroOrMore; -} - -bool OptionDescription::isOptional() const { - return Flags & OptionDescriptionFlags::Optional; -} -void OptionDescription::setOptional() { - Flags |= OptionDescriptionFlags::Optional; -} - -bool OptionDescription::isHidden() const { - return Flags & OptionDescriptionFlags::Hidden; -} -void OptionDescription::setHidden() { - Flags |= OptionDescriptionFlags::Hidden; -} - -bool OptionDescription::isReallyHidden() const { - return Flags & OptionDescriptionFlags::ReallyHidden; -} -void OptionDescription::setReallyHidden() { - Flags |= OptionDescriptionFlags::ReallyHidden; -} - -const char* OptionDescription::GenTypeDeclaration() const { - switch (Type) { - case OptionType::Alias: - return "cl::alias"; - case OptionType::PrefixList: - case OptionType::ParameterList: - return "cl::list<std::string>"; - case OptionType::Switch: - return "cl::opt<bool>"; - case OptionType::SwitchList: - return "cl::list<bool>"; - case OptionType::Parameter: - case OptionType::Prefix: - default: - return "cl::opt<std::string>"; - } -} - -std::string OptionDescription::GenOptionType() const { - switch (Type) { - case OptionType::Alias: - return "Alias_"; - case OptionType::PrefixList: - case OptionType::ParameterList: - return "List_"; - case OptionType::Switch: - return "Switch_"; - case OptionType::SwitchList: - return "SwitchList_"; - case OptionType::Prefix: - case OptionType::Parameter: - default: - return "Parameter_"; - } -} - -/// OptionDescriptions - An OptionDescription array plus some helper -/// functions. -class OptionDescriptions { - typedef StringMap<OptionDescription> container_type; - - /// Descriptions - A list of OptionDescriptions. - container_type Descriptions; - -public: - /// FindOption - exception-throwing wrapper for find(). - const OptionDescription& FindOption(const std::string& OptName) const; - - // Wrappers for FindOption that throw an exception in case the option has a - // wrong type. - const OptionDescription& FindSwitch(const std::string& OptName) const; - const OptionDescription& FindParameter(const std::string& OptName) const; - const OptionDescription& FindParameterList(const std::string& OptName) const; - const OptionDescription& - FindListOrParameter(const std::string& OptName) const; - const OptionDescription& - FindParameterListOrParameter(const std::string& OptName) const; - - /// insertDescription - Insert new OptionDescription into - /// OptionDescriptions list - void InsertDescription (const OptionDescription& o); - - // Support for STL-style iteration - typedef container_type::const_iterator const_iterator; - const_iterator begin() const { return Descriptions.begin(); } - const_iterator end() const { return Descriptions.end(); } -}; - -const OptionDescription& -OptionDescriptions::FindOption(const std::string& OptName) const { - const_iterator I = Descriptions.find(OptName); - if (I != Descriptions.end()) - return I->second; - else - throw OptName + ": no such option!"; -} - -const OptionDescription& -OptionDescriptions::FindSwitch(const std::string& OptName) const { - const OptionDescription& OptDesc = this->FindOption(OptName); - if (!OptDesc.isSwitch()) - throw OptName + ": incorrect option type - should be a switch!"; - return OptDesc; -} - -const OptionDescription& -OptionDescriptions::FindParameterList(const std::string& OptName) const { - const OptionDescription& OptDesc = this->FindOption(OptName); - if (!OptDesc.isList() || OptDesc.isSwitchList()) - throw OptName + ": incorrect option type - should be a parameter list!"; - return OptDesc; -} - -const OptionDescription& -OptionDescriptions::FindParameter(const std::string& OptName) const { - const OptionDescription& OptDesc = this->FindOption(OptName); - if (!OptDesc.isParameter()) - throw OptName + ": incorrect option type - should be a parameter!"; - return OptDesc; -} - -const OptionDescription& -OptionDescriptions::FindListOrParameter(const std::string& OptName) const { - const OptionDescription& OptDesc = this->FindOption(OptName); - if (!OptDesc.isList() && !OptDesc.isParameter()) - throw OptName - + ": incorrect option type - should be a list or parameter!"; - return OptDesc; -} - -const OptionDescription& -OptionDescriptions::FindParameterListOrParameter -(const std::string& OptName) const { - const OptionDescription& OptDesc = this->FindOption(OptName); - if ((!OptDesc.isList() && !OptDesc.isParameter()) || OptDesc.isSwitchList()) - throw OptName - + ": incorrect option type - should be a parameter list or parameter!"; - return OptDesc; -} - -void OptionDescriptions::InsertDescription (const OptionDescription& o) { - container_type::iterator I = Descriptions.find(o.Name); - if (I != Descriptions.end()) { - OptionDescription& D = I->second; - D.Merge(o); - } - else { - Descriptions[o.Name] = o; - } -} - -/// HandlerTable - A base class for function objects implemented as -/// 'tables of handlers'. -template <typename Handler> -class HandlerTable { -protected: - // Implementation details. - - /// HandlerMap - A map from property names to property handlers - typedef StringMap<Handler> HandlerMap; - - static HandlerMap Handlers_; - static bool staticMembersInitialized_; - -public: - - Handler GetHandler (const std::string& HandlerName) const { - typename HandlerMap::iterator method = Handlers_.find(HandlerName); - - if (method != Handlers_.end()) { - Handler h = method->second; - return h; - } - else { - throw "No handler found for property " + HandlerName + "!"; - } - } - - void AddHandler(const char* Property, Handler H) { - Handlers_[Property] = H; - } - -}; - -template <class Handler, class FunctionObject> -Handler GetHandler(FunctionObject* Obj, const DagInit& Dag) { - const std::string& HandlerName = GetOperatorName(Dag); - return Obj->GetHandler(HandlerName); -} - -template <class FunctionObject> -void InvokeDagInitHandler(FunctionObject* Obj, Init* I) { - typedef void (FunctionObject::*Handler) (const DagInit&); - - const DagInit& Dag = InitPtrToDag(I); - Handler h = GetHandler<Handler>(Obj, Dag); - - ((Obj)->*(h))(Dag); -} - -template <class FunctionObject> -void InvokeDagInitHandler(const FunctionObject* const Obj, - const Init* I, unsigned IndentLevel, raw_ostream& O) -{ - typedef void (FunctionObject::*Handler) - (const DagInit&, unsigned IndentLevel, raw_ostream& O) const; - - const DagInit& Dag = InitPtrToDag(I); - Handler h = GetHandler<Handler>(Obj, Dag); - - ((Obj)->*(h))(Dag, IndentLevel, O); -} - -template <typename H> -typename HandlerTable<H>::HandlerMap HandlerTable<H>::Handlers_; - -template <typename H> -bool HandlerTable<H>::staticMembersInitialized_ = false; - - -/// CollectOptionProperties - Function object for iterating over an -/// option property list. -class CollectOptionProperties; -typedef void (CollectOptionProperties::* CollectOptionPropertiesHandler) -(const DagInit&); - -class CollectOptionProperties -: public HandlerTable<CollectOptionPropertiesHandler> -{ -private: - - /// optDescs_ - OptionDescriptions table. This is where the - /// information is stored. - OptionDescription& optDesc_; - -public: - - explicit CollectOptionProperties(OptionDescription& OD) - : optDesc_(OD) - { - if (!staticMembersInitialized_) { - AddHandler("help", &CollectOptionProperties::onHelp); - AddHandler("hidden", &CollectOptionProperties::onHidden); - AddHandler("init", &CollectOptionProperties::onInit); - AddHandler("multi_val", &CollectOptionProperties::onMultiVal); - AddHandler("one_or_more", &CollectOptionProperties::onOneOrMore); - AddHandler("zero_or_more", &CollectOptionProperties::onZeroOrMore); - AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden); - AddHandler("required", &CollectOptionProperties::onRequired); - AddHandler("optional", &CollectOptionProperties::onOptional); - AddHandler("comma_separated", &CollectOptionProperties::onCommaSeparated); - AddHandler("forward_not_split", - &CollectOptionProperties::onForwardNotSplit); - - staticMembersInitialized_ = true; - } - } - - /// operator() - Just forwards to the corresponding property - /// handler. - void operator() (Init* I) { - InvokeDagInitHandler(this, I); - } - -private: - - /// Option property handlers -- - /// Methods that handle option properties such as (help) or (hidden). - - void onHelp (const DagInit& d) { - CheckNumberOfArguments(d, 1); - optDesc_.Help = EscapeQuotes(InitPtrToString(d.getArg(0))); - } - - void onHidden (const DagInit& d) { - CheckNumberOfArguments(d, 0); - optDesc_.setHidden(); - } - - void onReallyHidden (const DagInit& d) { - CheckNumberOfArguments(d, 0); - optDesc_.setReallyHidden(); - } - - void onCommaSeparated (const DagInit& d) { - CheckNumberOfArguments(d, 0); - if (!optDesc_.isParameterList()) - throw "'comma_separated' is valid only on parameter list options!"; - optDesc_.setCommaSeparated(); - } - - void onForwardNotSplit (const DagInit& d) { - CheckNumberOfArguments(d, 0); - if (!optDesc_.isParameter()) - throw "'forward_not_split' is valid only for parameter options!"; - optDesc_.setForwardNotSplit(); - } - - void onRequired (const DagInit& d) { - CheckNumberOfArguments(d, 0); - - optDesc_.setRequired(); - optDesc_.CheckConsistency(); - } - - void onInit (const DagInit& d) { - CheckNumberOfArguments(d, 1); - Init* i = d.getArg(0); - const std::string& str = i->getAsString(); - - bool correct = optDesc_.isParameter() && dynamic_cast<StringInit*>(i); - correct |= (optDesc_.isSwitch() && (str == "true" || str == "false")); - - if (!correct) - throw "Incorrect usage of the 'init' option property!"; - - optDesc_.InitVal = i; - } - - void onOneOrMore (const DagInit& d) { - CheckNumberOfArguments(d, 0); - - optDesc_.setOneOrMore(); - optDesc_.CheckConsistency(); - } - - void onZeroOrMore (const DagInit& d) { - CheckNumberOfArguments(d, 0); - - if (optDesc_.isList()) - llvm::errs() << "Warning: specifying the 'zero_or_more' property " - "on a list option has no effect.\n"; - - optDesc_.setZeroOrMore(); - optDesc_.CheckConsistency(); - } - - void onOptional (const DagInit& d) { - CheckNumberOfArguments(d, 0); - - if (!optDesc_.isList()) - llvm::errs() << "Warning: specifying the 'optional' property" - "on a non-list option has no effect.\n"; - - optDesc_.setOptional(); - optDesc_.CheckConsistency(); - } - - void onMultiVal (const DagInit& d) { - CheckNumberOfArguments(d, 1); - int val = InitPtrToInt(d.getArg(0)); - if (val < 2) - throw "Error in the 'multi_val' property: " - "the value must be greater than 1!"; - if (!optDesc_.isParameterList()) - throw "The multi_val property is valid only on list options!"; - optDesc_.MultiVal = val; - } - -}; - -/// AddOption - A function object that is applied to every option -/// description. Used by CollectOptionDescriptions. -class AddOption { -private: - OptionDescriptions& OptDescs_; - -public: - explicit AddOption(OptionDescriptions& OD) : OptDescs_(OD) - {} - - void operator()(const Init* i) { - const DagInit& d = InitPtrToDag(i); - CheckNumberOfArguments(d, 1); - - const OptionType::OptionType Type = - stringToOptionType(GetOperatorName(d)); - const std::string& Name = InitPtrToString(d.getArg(0)); - - OptionDescription OD(Type, Name); - - CheckNumberOfArguments(d, 2); - - // Alias option store the aliased option name in the 'Help' field and do not - // have any properties. - if (OD.isAlias()) { - OD.Help = InitPtrToString(d.getArg(1)); - } - else { - processOptionProperties(d, OD); - } - - // Switch options are ZeroOrMore by default. - if (OD.isSwitch()) { - if (!(OD.isOptional() || OD.isOneOrMore() || OD.isRequired())) - OD.setZeroOrMore(); - } - - OptDescs_.InsertDescription(OD); - } - -private: - /// processOptionProperties - Go through the list of option - /// properties and call a corresponding handler for each. - static void processOptionProperties (const DagInit& d, OptionDescription& 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(o)); - } - -}; - -/// CollectOptionDescriptions - Collects option properties from all -/// OptionLists. -void CollectOptionDescriptions (const RecordVector& V, - OptionDescriptions& OptDescs) -{ - // For every OptionList: - for (RecordVector::const_iterator B = V.begin(), E = V.end(); B!=E; ++B) - { - // Throws an exception if the value does not exist. - ListInit* PropList = (*B)->getValueAsListInit("options"); - - // For every option description in this list: invoke AddOption. - std::for_each(PropList->begin(), PropList->end(), AddOption(OptDescs)); - } -} - -// Tool information record - -namespace ToolFlags { - enum ToolFlags { Join = 0x1, Sink = 0x2 }; -} - -struct ToolDescription : public RefCountedBase<ToolDescription> { - std::string Name; - Init* CmdLine; - Init* Actions; - StrVector InLanguage; - std::string InFileOption; - std::string OutFileOption; - StrVector OutLanguage; - std::string OutputSuffix; - unsigned Flags; - const Init* OnEmpty; - - // Various boolean properties - void setSink() { Flags |= ToolFlags::Sink; } - bool isSink() const { return Flags & ToolFlags::Sink; } - void setJoin() { Flags |= ToolFlags::Join; } - bool isJoin() const { return Flags & ToolFlags::Join; } - - // Default ctor here is needed because StringMap can only store - // DefaultConstructible objects - ToolDescription (const std::string &n = "") - : Name(n), CmdLine(0), Actions(0), OutFileOption("-o"), - Flags(0), OnEmpty(0) - {} -}; - -/// ToolDescriptions - A list of Tool information records. -typedef std::vector<IntrusiveRefCntPtr<ToolDescription> > ToolDescriptions; - - -/// CollectToolProperties - Function object for iterating over a list of -/// tool property records. - -class CollectToolProperties; -typedef void (CollectToolProperties::* CollectToolPropertiesHandler) -(const DagInit&); - -class CollectToolProperties : public HandlerTable<CollectToolPropertiesHandler> -{ -private: - - /// toolDesc_ - Properties of the current Tool. This is where the - /// information is stored. - ToolDescription& toolDesc_; - -public: - - explicit CollectToolProperties (ToolDescription& d) - : toolDesc_(d) - { - if (!staticMembersInitialized_) { - - AddHandler("actions", &CollectToolProperties::onActions); - AddHandler("command", &CollectToolProperties::onCommand); - AddHandler("in_language", &CollectToolProperties::onInLanguage); - AddHandler("join", &CollectToolProperties::onJoin); - AddHandler("out_language", &CollectToolProperties::onOutLanguage); - - AddHandler("out_file_option", &CollectToolProperties::onOutFileOption); - AddHandler("in_file_option", &CollectToolProperties::onInFileOption); - - AddHandler("output_suffix", &CollectToolProperties::onOutputSuffix); - AddHandler("sink", &CollectToolProperties::onSink); - AddHandler("works_on_empty", &CollectToolProperties::onWorksOnEmpty); - - staticMembersInitialized_ = true; - } - } - - void operator() (Init* I) { - InvokeDagInitHandler(this, I); - } - -private: - - /// Property handlers -- - /// Functions that extract information about tool properties from - /// DAG representation. - - void onActions (const DagInit& d) { - CheckNumberOfArguments(d, 1); - Init* Case = d.getArg(0); - if (typeid(*Case) != typeid(DagInit) || - GetOperatorName(static_cast<DagInit&>(*Case)) != "case") - throw "The argument to (actions) should be a 'case' construct!"; - toolDesc_.Actions = Case; - } - - void onCommand (const DagInit& d) { - CheckNumberOfArguments(d, 1); - toolDesc_.CmdLine = d.getArg(0); - } - - /// onInOutLanguage - Common implementation of on{In,Out}Language(). - void onInOutLanguage (const DagInit& d, StrVector& OutVec) { - CheckNumberOfArguments(d, 1); - - // Copy strings to the output vector. - for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) { - OutVec.push_back(InitPtrToString(d.getArg(i))); - } - - // Remove duplicates. - std::sort(OutVec.begin(), OutVec.end()); - StrVector::iterator newE = std::unique(OutVec.begin(), OutVec.end()); - OutVec.erase(newE, OutVec.end()); - } - - - void onInLanguage (const DagInit& d) { - this->onInOutLanguage(d, toolDesc_.InLanguage); - } - - void onJoin (const DagInit& d) { - bool isReallyJoin = false; - - if (d.getNumArgs() == 0) { - isReallyJoin = true; - } - else { - Init* I = d.getArg(0); - isReallyJoin = InitPtrToBool(I); - } - - // Is this *really* a join tool? We allow (join false) for generating two - // tool descriptions from a single generic one. - // TOFIX: come up with a cleaner solution. - if (isReallyJoin) { - toolDesc_.setJoin(); - } - } - - void onOutLanguage (const DagInit& d) { - this->onInOutLanguage(d, toolDesc_.OutLanguage); - } - - void onOutFileOption (const DagInit& d) { - CheckNumberOfArguments(d, 1); - toolDesc_.OutFileOption = InitPtrToString(d.getArg(0)); - } - - void onInFileOption (const DagInit& d) { - CheckNumberOfArguments(d, 1); - toolDesc_.InFileOption = InitPtrToString(d.getArg(0)); - } - - void onOutputSuffix (const DagInit& d) { - CheckNumberOfArguments(d, 1); - toolDesc_.OutputSuffix = InitPtrToString(d.getArg(0)); - } - - void onSink (const DagInit& d) { - CheckNumberOfArguments(d, 0); - toolDesc_.setSink(); - } - - void onWorksOnEmpty (const DagInit& d) { - toolDesc_.OnEmpty = d.getArg(0); - } - -}; - -/// CollectToolDescriptions - Gather information about tool properties -/// from the parsed TableGen data (basically a wrapper for the -/// CollectToolProperties function object). -void CollectToolDescriptions (const RecordVector& Tools, - ToolDescriptions& ToolDescs) -{ - // Iterate over a properties list of every Tool definition - for (RecordVector::const_iterator B = Tools.begin(), - E = Tools.end(); B!=E; ++B) { - const Record* T = *B; - // Throws an exception if the value does not exist. - ListInit* PropList = T->getValueAsListInit("properties"); - - IntrusiveRefCntPtr<ToolDescription> - ToolDesc(new ToolDescription(T->getName())); - - std::for_each(PropList->begin(), PropList->end(), - CollectToolProperties(*ToolDesc)); - ToolDescs.push_back(ToolDesc); - } -} - -/// FillInEdgeVector - Merge all compilation graph definitions into -/// one single edge list. -void FillInEdgeVector(const RecordVector& CompilationGraphs, - DagVector& Out) { - for (RecordVector::const_iterator B = CompilationGraphs.begin(), - E = CompilationGraphs.end(); B != E; ++B) { - const ListInit* Edges = (*B)->getValueAsListInit("edges"); - - for (ListInit::const_iterator B = Edges->begin(), - E = Edges->end(); B != E; ++B) { - Out.push_back(&InitPtrToDag(*B)); - } - } -} - -/// NotInGraph - Helper function object for FilterNotInGraph. -struct NotInGraph { -private: - const llvm::StringSet<>& ToolsInGraph_; - -public: - NotInGraph(const llvm::StringSet<>& ToolsInGraph) - : ToolsInGraph_(ToolsInGraph) - {} - - bool operator()(const IntrusiveRefCntPtr<ToolDescription>& x) { - return (ToolsInGraph_.count(x->Name) == 0); - } -}; - -/// FilterNotInGraph - Filter out from ToolDescs all Tools not -/// mentioned in the compilation graph definition. -void FilterNotInGraph (const DagVector& EdgeVector, - ToolDescriptions& ToolDescs) { - - // List all tools mentioned in the graph. - llvm::StringSet<> ToolsInGraph; - - for (DagVector::const_iterator B = EdgeVector.begin(), - E = EdgeVector.end(); B != E; ++B) { - - const DagInit* Edge = *B; - const std::string& NodeA = InitPtrToString(Edge->getArg(0)); - const std::string& NodeB = InitPtrToString(Edge->getArg(1)); - - if (NodeA != "root") - ToolsInGraph.insert(NodeA); - ToolsInGraph.insert(NodeB); - } - - // Filter ToolPropertiesList. - ToolDescriptions::iterator new_end = - std::remove_if(ToolDescs.begin(), ToolDescs.end(), - NotInGraph(ToolsInGraph)); - ToolDescs.erase(new_end, ToolDescs.end()); -} - -/// FillInToolToLang - Fills in two tables that map tool names to -/// input & output language names. Helper function used by TypecheckGraph(). -void FillInToolToLang (const ToolDescriptions& ToolDescs, - StringMap<StringSet<> >& ToolToInLang, - StringMap<StringSet<> >& ToolToOutLang) { |