summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorEric Christopher <echristo@apple.com>2011-09-20 00:34:27 +0000
committerEric Christopher <echristo@apple.com>2011-09-20 00:34:27 +0000
commiteae5a13078037e6b6591fd4f414452a7075cecf7 (patch)
tree3d79a7b7512ca2662c0268e8c3e30be66047e72f /utils
parent400b624e02216dcbe1ec0c17963caa088b33c57a (diff)
downloadllvm-eae5a13078037e6b6591fd4f414452a7075cecf7.tar.gz
llvm-eae5a13078037e6b6591fd4f414452a7075cecf7.tar.bz2
llvm-eae5a13078037e6b6591fd4f414452a7075cecf7.tar.xz
Remove more of llvmc and dependencies.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140121 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/CMakeLists.txt1
-rw-r--r--utils/TableGen/LLVMCConfigurationEmitter.cpp3134
-rw-r--r--utils/TableGen/LLVMCConfigurationEmitter.h34
-rw-r--r--utils/TableGen/TableGen.cpp7
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) {
- for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
- E = ToolDescs.end(); B != E; ++B) {
- const ToolDescription& D = *(*B);
- for (StrVector::const_iterator B = D.InLanguage.begin(),
- E = D.InLanguage.end(); B != E; ++B)
- ToolToInLang[D.Name].insert(*B);
- for (StrVector::const_iterator B = D.OutLanguage.begin(),
- E = D.OutLanguage.end(); B != E; ++B)
- ToolToOutLang[D.Name].insert(*B);
- }
-}
-
-/// Intersect - Is set intersection non-empty?
-bool Intersect (const StringSet<>& S1, const StringSet<>& S2) {
- for (StringSet<>::const_iterator B = S1.begin(), E = S1.end(); B != E; ++B) {
- if (S2.count(B->first()) != 0)
- return true;
- }
- return false;
-}
-
-/// TypecheckGraph - Check that names for output and input languages
-/// on all edges do match.
-void TypecheckGraph (const DagVector& EdgeVector,
- const ToolDescriptions& ToolDescs) {
- StringMap<StringSet<> > ToolToInLang;
- StringMap<StringSet<> > ToolToOutLang;
-
- FillInToolToLang(ToolDescs, ToolToInLang, ToolToOutLang);
-
- 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));
- StringMap<StringSet<> >::iterator IA = ToolToOutLang.find(NodeA);
- StringMap<StringSet<> >::iterator IB = ToolToInLang.find(NodeB);
-
- if (NodeB == "root")
- throw "Edges back to the root are not allowed!";
-
- if (NodeA != "root") {
- if (IA == ToolToOutLang.end())
- throw NodeA + ": no output language defined!";
- if (IB == ToolToInLang.end())
- throw NodeB + ": no input language defined!";
-
- if (!Intersect(IA->second, IB->second)) {
- throw "Edge " + NodeA + "->" + NodeB
- + ": output->input language mismatch";
- }
- }
- }
-}
-
-/// WalkCase - Walks the 'case' expression DAG and invokes
-/// TestCallback on every test, and StatementCallback on every
-/// statement. Handles 'case' nesting, but not the 'and' and 'or'
-/// combinators (that is, they are passed directly to TestCallback).
-/// TestCallback must have type 'void TestCallback(const DagInit*, unsigned
-/// IndentLevel, bool FirstTest)'.
-/// StatementCallback must have type 'void StatementCallback(const Init*,
-/// unsigned IndentLevel)'.
-template <typename F1, typename F2>
-void WalkCase(const Init* Case, F1 TestCallback, F2 StatementCallback,
- unsigned IndentLevel = 0)
-{
- const DagInit& d = InitPtrToDag(Case);
-
- // Error checks.
- if (GetOperatorName(d) != "case")
- throw "WalkCase should be invoked only on 'case' expressions!";
-
- if (d.getNumArgs() < 2)
- throw "There should be at least one clause in the 'case' expression:\n"
- + d.getAsString();
-
- // Main loop.
- bool even = false;
- const unsigned numArgs = d.getNumArgs();
- unsigned i = 1;
- for (DagInit::const_arg_iterator B = d.arg_begin(), E = d.arg_end();
- B != E; ++B) {
- Init* arg = *B;
-
- if (!even)
- {
- // Handle test.
- const DagInit& Test = InitPtrToDag(arg);
-
- if (GetOperatorName(Test) == "default" && (i+1 != numArgs))
- throw "The 'default' clause should be the last in the "
- "'case' construct!";
- if (i == numArgs)
- throw "Case construct handler: no corresponding action "
- "found for the test " + Test.getAsString() + '!';
-
- TestCallback(Test, IndentLevel, (i == 1));
- }
- else
- {
- if (dynamic_cast<DagInit*>(arg)
- && GetOperatorName(static_cast<DagInit&>(*arg)) == "case") {
- // Nested 'case'.
- WalkCase(arg, TestCallback, StatementCallback, IndentLevel + Indent1);
- }
-
- // Handle statement.
- StatementCallback(arg, IndentLevel);
- }
-
- ++i;
- even = !even;
- }
-}
-
-/// ExtractOptionNames - A helper function object used by
-/// CheckForSuperfluousOptions() to walk the 'case' DAG.
-class ExtractOptionNames {
- llvm::StringSet<>& OptionNames_;
-
- void processDag(const Init* Statement) {
- const DagInit& Stmt = InitPtrToDag(Statement);
- const std::string& ActionName = GetOperatorName(Stmt);
- if (ActionName == "forward" || ActionName == "forward_as" ||
- ActionName == "forward_value" ||
- ActionName == "forward_transformed_value" ||
- ActionName == "parameter_equals" || ActionName == "element_in_list") {
- CheckNumberOfArguments(Stmt, 1);
-
- Init* Arg = Stmt.getArg(0);
- if (typeid(*Arg) == typeid(StringInit))
- OptionNames_.insert(InitPtrToString(Arg));
- }
- else if (ActionName == "any_switch_on" || ActionName == "switch_on" ||
- ActionName == "any_not_empty" || ActionName == "any_empty" ||
- ActionName == "not_empty" || ActionName == "empty") {
- for (unsigned i = 0, NumArgs = Stmt.getNumArgs(); i < NumArgs; ++i) {
- Init* Arg = Stmt.getArg(i);
- if (typeid(*Arg) == typeid(StringInit))
- OptionNames_.insert(InitPtrToString(Arg));
- }
- }
- else if (ActionName == "and" || ActionName == "or" || ActionName == "not") {
- for (unsigned i = 0, NumArgs = Stmt.getNumArgs(); i < NumArgs; ++i) {
- this->processDag(Stmt.getArg(i));
- }
- }
- }
-
-public:
- ExtractOptionNames(llvm::StringSet<>& OptionNames) : OptionNames_(OptionNames)
- {}
-
- void operator()(const Init* Statement) {
- // Statement is either a dag, or a list of dags.
- if (typeid(*Statement) == typeid(ListInit)) {
- const ListInit& DagList = *static_cast<const ListInit*>(Statement);
- for (ListInit::const_iterator B = DagList.begin(), E = DagList.end();
- B != E; ++B)
- this->processDag(*B);
- }
- else {
- this->processDag(Statement);
- }
- }
-
- void operator()(const DagInit& Test, unsigned, bool) {
- this->operator()(&Test);
- }
- void operator()(const Init* Statement, unsigned) {
- this->operator()(Statement);
- }
-};
-
-/// IsOptionalEdge - Validate that the 'optional_edge' has proper structure.
-bool IsOptionalEdge (const DagInit& Edg) {
- return (GetOperatorName(Edg) == "optional_edge") && (Edg.getNumArgs() > 2);
-}
-
-/// CheckForSuperfluousOptions - Check that there are no side
-/// effect-free options (specified only in the OptionList). Otherwise,
-/// output a warning.
-void CheckForSuperfluousOptions (const DagVector& EdgeVector,
- const ToolDescriptions& ToolDescs,
- const OptionDescriptions& OptDescs) {
- llvm::StringSet<> nonSuperfluousOptions;
-
- // Add all options mentioned in the ToolDesc.Actions to the set of
- // non-superfluous options.
- for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
- E = ToolDescs.end(); B != E; ++B) {
- const ToolDescription& TD = *(*B);
- ExtractOptionNames Callback(nonSuperfluousOptions);
- if (TD.Actions)
- WalkCase(TD.Actions, Callback, Callback);
- }
-
- // Add all options mentioned in the 'case' clauses of the
- // OptionalEdges of the compilation graph to the set of
- // non-superfluous options.
- for (DagVector::const_iterator B = EdgeVector.begin(),
- E = EdgeVector.end(); B != E; ++B) {
- const DagInit& Edge = **B;
- if (IsOptionalEdge(Edge)) {
- const DagInit& Weight = InitPtrToDag(Edge.getArg(2));
- WalkCase(&Weight, ExtractOptionNames(nonSuperfluousOptions), Id());
- }
- }
-
- // Check that all options in OptDescs belong to the set of
- // non-superfluous options.
- for (OptionDescriptions::const_iterator B = OptDescs.begin(),
- E = OptDescs.end(); B != E; ++B) {
- const OptionDescription& Val = B->second;
- if (!nonSuperfluousOptions.count(Val.Name)
- && Val.Type != OptionType::Alias)
- llvm::errs() << "Warning: option '-" << Val.Name << "' has no effect! "
- "Probable cause: this option is specified only in the OptionList.\n";
- }
-}
-
-/// EmitCaseTest0Args - Helper function used by EmitCaseConstructHandler().
-bool EmitCaseTest0Args(const std::string& TestName, raw_ostream& O) {
- if (TestName == "single_input_file") {
- O << "InputFilenames.size() == 1";
- return true;
- }
- else if (TestName == "multiple_input_files") {
- O << "InputFilenames.size() > 1";
- return true;
- }
-
- return false;
-}
-
-/// EmitMultipleArgumentTest - Helper function used by
-/// EmitCaseTestMultipleArgs()
-template <typename F>
-void EmitMultipleArgumentTest(const DagInit& D, const char* LogicOp,
- F Callback, raw_ostream& O)
-{
- for (unsigned i = 0, NumArgs = D.getNumArgs(); i < NumArgs; ++i) {
- if (i != 0)
- O << ' ' << LogicOp << ' ';
- Callback(InitPtrToString(D.getArg(i)), O);
- }
-}
-
-// Callbacks for use with EmitMultipleArgumentTest
-
-class EmitSwitchOn {
- const OptionDescriptions& OptDescs_;
-public:
- EmitSwitchOn(const OptionDescriptions& OptDescs) : OptDescs_(OptDescs)
- {}
-
- void operator()(const std::string& OptName, raw_ostream& O) const {
- const OptionDescription& OptDesc = OptDescs_.FindSwitch(OptName);
- O << OptDesc.GenVariableName();
- }
-};
-
-class EmitEmptyTest {
- bool EmitNegate_;
- const OptionDescriptions& OptDescs_;
-public:
- EmitEmptyTest(bool EmitNegate, const OptionDescriptions& OptDescs)
- : EmitNegate_(EmitNegate), OptDescs_(OptDescs)
- {}
-
- void operator()(const std::string& OptName, raw_ostream& O) const {
- const char* Neg = (EmitNegate_ ? "!" : "");
- if (OptName == "o") {
- O << Neg << "OutputFilename.empty()";
- }
- else if (OptName == "save-temps") {
- O << Neg << "(SaveTemps == SaveTempsEnum::Unset)";
- }
- else {
- const OptionDescription& OptDesc = OptDescs_.FindListOrParameter(OptName);
- O << Neg << OptDesc.GenVariableName() << ".empty()";
- }
- }
-};
-
-
-/// EmitCaseTestMultipleArgs - Helper function used by EmitCaseTest1Arg()
-bool EmitCaseTestMultipleArgs (const std::string& TestName,
- const DagInit& d,
- const OptionDescriptions& OptDescs,
- raw_ostream& O) {
- if (TestName == "any_switch_on") {
- EmitMultipleArgumentTest(d, "||", EmitSwitchOn(OptDescs), O);
- return true;
- }
- else if (TestName == "switch_on") {
- EmitMultipleArgumentTest(d, "&&", EmitSwitchOn(OptDescs), O);
- return true;
- }
- else if (TestName == "any_not_empty") {
- EmitMultipleArgumentTest(d, "||", EmitEmptyTest(true, OptDescs), O);
- return true;
- }
- else if (TestName == "any_empty") {
- EmitMultipleArgumentTest(d, "||", EmitEmptyTest(false, OptDescs), O);
- return true;
- }
- else if (TestName == "not_empty") {
- EmitMultipleArgumentTest(d, "&&", EmitEmptyTest(true, OptDescs), O);
- return true;
- }
- else if (TestName == "empty") {
- EmitMultipleArgumentTest(d, "&&", EmitEmptyTest(false, OptDescs), O);
- return true;
- }
-
- return false;
-}
-
-/// EmitCaseTest1Arg - Helper function used by EmitCaseTest1OrMoreArgs()
-bool EmitCaseTest1Arg (const std::string& TestName,
- const DagInit& d,
- const OptionDescriptions& OptDescs,
- raw_ostream& O) {
- const std::string& Arg = InitPtrToString(d.getArg(0));
-
- if (TestName == "input_languages_contain") {
- O << "InLangs.count(\"" << Arg << "\") != 0";
- return true;
- }
- else if (TestName == "in_language") {
- // This works only for single-argument Tool::GenerateAction. Join
- // tools can process several files in different languages simultaneously.
-
- // TODO: make this work with Edge::Weight (if possible).
- O << "LangMap.GetLanguage(inFile) == \"" << Arg << '\"';
- return true;
- }
-
- return false;
-}
-
-/// EmitCaseTest1OrMoreArgs - Helper function used by
-/// EmitCaseConstructHandler()
-bool EmitCaseTest1OrMoreArgs(const std::string& TestName,
- const DagInit& d,
- const OptionDescriptions& OptDescs,
- raw_ostream& O) {
- CheckNumberOfArguments(d, 1);
- return EmitCaseTest1Arg(TestName, d, OptDescs, O) ||
- EmitCaseTestMultipleArgs(TestName, d, OptDescs, O);
-}
-
-/// EmitCaseTest2Args - Helper function used by EmitCaseConstructHandler().
-bool EmitCaseTest2Args(const std::string& TestName,
- const DagInit& d,
- unsigned IndentLevel,
- const OptionDescriptions& OptDescs,
- raw_ostream& O) {
- CheckNumberOfArguments(d, 2);
- const std::string& OptName = InitPtrToString(d.getArg(0));
- const std::string& OptArg = InitPtrToString(d.getArg(1));
-
- if (TestName == "parameter_equals") {
- const OptionDescription& OptDesc = OptDescs.FindParameter(OptName);
- O << OptDesc.GenVariableName() << " == \"" << OptArg << "\"";
- return true;
- }
- else if (TestName == "element_in_list") {
- const OptionDescription& OptDesc = OptDescs.FindParameterList(OptName);
- const std::string& VarName = OptDesc.GenVariableName();
- O << "std::find(" << VarName << ".begin(),\n";
- O.indent(IndentLevel + Indent1)
- << VarName << ".end(), \""
- << OptArg << "\") != " << VarName << ".end()";
- return true;
- }
-
- return false;
-}
-
-// Forward declaration.
-// EmitLogicalOperationTest and EmitCaseTest are mutually recursive.
-void EmitCaseTest(const DagInit& d, unsigned IndentLevel,
- const OptionDescriptions& OptDescs,
- raw_ostream& O);
-
-/// EmitLogicalOperationTest - Helper function used by
-/// EmitCaseConstructHandler.
-void EmitLogicalOperationTest(const DagInit& d, const char* LogicOp,
- unsigned IndentLevel,
- const OptionDescriptions& OptDescs,
- raw_ostream& O) {
- O << '(';
- for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) {
- const DagInit& InnerTest = InitPtrToDag(d.getArg(i));
- EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
- if (i != NumArgs - 1) {
- O << ")\n";
- O.indent(IndentLevel + Indent1) << ' ' << LogicOp << " (";
- }
- else {
- O << ')';
- }
- }
-}
-
-void EmitLogicalNot(const DagInit& d, unsigned IndentLevel,
- const OptionDescriptions& OptDescs, raw_ostream& O)
-{
- CheckNumberOfArguments(d, 1);
- const DagInit& InnerTest = InitPtrToDag(d.getArg(0));
- O << "! (";
- EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
- O << ")";
-}
-
-/// EmitCaseTest - Helper function used by EmitCaseConstructHandler.
-void EmitCaseTest(const DagInit& d, unsigned IndentLevel,
- const OptionDescriptions& OptDescs,
- raw_ostream& O) {
- const std::string& TestName = GetOperatorName(d);
-
- if (TestName == "and")
- EmitLogicalOperationTest(d, "&&", IndentLevel, OptDescs, O);
- else if (TestName == "or")
- EmitLogicalOperationTest(d, "||", IndentLevel, OptDescs, O);
- else if (TestName == "not")
- EmitLogicalNot(d, IndentLevel, OptDescs, O);
- else if (EmitCaseTest0Args(TestName, O))
- return;
- else if (EmitCaseTest1OrMoreArgs(TestName, d, OptDescs, O))
- return;
- else if (EmitCaseTest2Args(TestName, d, IndentLevel, OptDescs, O))
- return;
- else
- throw "Unknown test '" + TestName + "' used in the 'case' construct!";
-}
-
-
-/// EmitCaseTestCallback - Callback used by EmitCaseConstructHandler.
-class EmitCaseTestCallback {
- bool EmitElseIf_;
- const OptionDescriptions& OptDescs_;
- raw_ostream& O_;
-public:
-
- EmitCaseTestCallback(bool EmitElseIf,
- const OptionDescriptions& OptDescs, raw_ostream& O)
- : EmitElseIf_(EmitElseIf), OptDescs_(OptDescs), O_(O)
- {}
-
- void operator()(const DagInit& Test, unsigned IndentLevel, bool FirstTest)
- {
- if (GetOperatorName(Test) == "default") {
- O_.indent(IndentLevel) << "else {\n";
- }
- else {
- O_.indent(IndentLevel)
- << ((!FirstTest && EmitElseIf_) ? "else if (" : "if (");
- EmitCaseTest(Test, IndentLevel, OptDescs_, O_);
- O_ << ") {\n";
- }
- }
-};
-
-/// EmitCaseStatementCallback - Callback used by EmitCaseConstructHandler.
-template <typename F>
-class EmitCaseStatementCallback {
- F Callback_;
- raw_ostream& O_;
-public:
-
- EmitCaseStatementCallback(F Callback, raw_ostream& O)
- : Callback_(Callback), O_(O)
- {}
-
- void operator() (const Init* Statement, unsigned IndentLevel) {
- // Is this a nested 'case'?
- bool IsCase = dynamic_cast<const DagInit*>(Statement) &&
- GetOperatorName(static_cast<const DagInit&>(*Statement)) == "case";
-
- // If so, ignore it, it is handled by our caller, WalkCase.
- if (!IsCase) {
- if (typeid(*Statement) == typeid(ListInit)) {
- const ListInit& DagList = *static_cast<const ListInit*>(Statement);
- for (ListInit::const_iterator B = DagList.begin(), E = DagList.end();
- B != E; ++B)
- Callback_(*B, (IndentLevel + Indent1), O_);
- }
- else {
- Callback_(Statement, (IndentLevel + Indent1), O_);
- }
- }
- O_.indent(IndentLevel) << "}\n";
- }
-
-};
-
-/// EmitCaseConstructHandler - Emit code that handles the 'case'
-/// construct. Takes a function object that should emit code for every case
-/// clause. Implemented on top of WalkCase.
-/// Callback's type is void F(const Init* Statement, unsigned IndentLevel,
-/// raw_ostream& O).
-/// EmitElseIf parameter controls the type of condition that is emitted ('if
-/// (..) {..} else if (..) {} .. else {..}' vs. 'if (..) {..} if(..) {..}
-/// .. else {..}').
-template <typename F>
-void EmitCaseConstructHandler(const Init* Case, unsigned IndentLevel,
- F Callback, bool EmitElseIf,
- const OptionDescriptions& OptDescs,
- raw_ostream& O) {
- WalkCase(Case, EmitCaseTestCallback(EmitElseIf, OptDescs, O),
- EmitCaseStatementCallback<F>(Callback, O), IndentLevel);
-}
-
-/// TokenizeCmdLine - converts from
-/// "$CALL(HookName, 'Arg1', 'Arg2')/path -arg1 -arg2" to
-/// ["$CALL(", "HookName", "Arg1", "Arg2", ")/path", "-arg1", "-arg2"].
-void TokenizeCmdLine(const std::string& CmdLine, StrVector& Out) {
- const char* Delimiters = " \t\n\v\f\r";
- enum TokenizerState
- { Normal, SpecialCommand, InsideSpecialCommand, InsideQuotationMarks }
- cur_st = Normal;
-
- if (CmdLine.empty())
- return;
- Out.push_back("");
-
- std::string::size_type B = CmdLine.find_first_not_of(Delimiters),
- E = CmdLine.size();
-
- for (; B != E; ++B) {
- char cur_ch = CmdLine[B];
-
- switch (cur_st) {
- case Normal:
- if (cur_ch == '$') {
- cur_st = SpecialCommand;
- break;
- }
- if (OneOf(Delimiters, cur_ch)) {
- // Skip whitespace
- B = CmdLine.find_first_not_of(Delimiters, B);
- if (B == std::string::npos) {
- B = E-1;
- continue;
- }
- --B;
- Out.push_back("");
- continue;
- }
- break;
-
-
- case SpecialCommand:
- if (OneOf(Delimiters, cur_ch)) {
- cur_st = Normal;
- Out.push_back("");
- continue;
- }
- if (cur_ch == '(') {
- Out.push_back("");
- cur_st = InsideSpecialCommand;
- continue;
- }
- break;
-
- case InsideSpecialCommand:
- if (OneOf(Delimiters, cur_ch)) {
- continue;
- }
- if (cur_ch == '\'') {
- cur_st = InsideQuotationMarks;
- Out.push_back("");
- continue;
- }
- if (cur_ch == ')') {
- cur_st = Normal;
- Out.push_back("");
- }
- if (cur_ch == ',') {
- continue;
- }
-
- break;
-
- case InsideQuotationMarks:
- if (cur_ch == '\'') {
- cur_st = InsideSpecialCommand;
- continue;
- }
- break;
- }
-
- Out.back().push_back(cur_ch);
- }
-}
-
-/// SubstituteCall - Given "$CALL(HookName, [Arg1 [, Arg2 [...]]])", output
-/// "hooks::HookName([Arg1 [, Arg2 [, ...]]])". Helper function used by
-/// SubstituteSpecialCommands().
-StrVector::const_iterator
-SubstituteCall (StrVector::const_iterator Pos,
- StrVector::const_iterator End,
- bool IsJoin, raw_ostream& O)
-{
- const char* errorMessage = "Syntax error in $CALL invocation!";
- CheckedIncrement(Pos, End, errorMessage);
- const std::string& CmdName = *Pos;
-
- if (CmdName == ")")
- throw "$CALL invocation: empty argument list!";
-
- O << "hooks::";
- O << CmdName << "(";
-
-
- bool firstIteration = true;
- while (true) {
- CheckedIncrement(Pos, End, errorMessage);
- const std::string& Arg = *Pos;
- assert(Arg.size() != 0);
-
- if (Arg[0] == ')')
- break;
-
- if (firstIteration)
- firstIteration = false;
- else
- O << ", ";
-
- if (Arg == "$INFILE") {
- if (IsJoin)
- throw "$CALL(Hook, $INFILE) can't be used with a Join tool!";
- else
- O << "inFile.c_str()";
- }
- else {
- O << '"' << Arg << '"';
- }
- }
-
- O << ')';
-
- return Pos;
-}
-
-/// SubstituteEnv - Given '$ENV(VAR_NAME)', output 'getenv("VAR_NAME")'. Helper
-/// function used by SubstituteSpecialCommands().
-StrVector::const_iterator
-SubstituteEnv (StrVector::const_iterator Pos,
- StrVector::const_iterator End, raw_ostream& O)
-{
- const char* errorMessage = "Syntax error in $ENV invocation!";
- CheckedIncrement(Pos, End, errorMessage);
- const std::string& EnvName = *Pos;
-
- if (EnvName == ")")
- throw "$ENV invocation: empty argument list!";
-
- O << "checkCString(std::getenv(\"";
- O << EnvName;
- O << "\"))";
-
- CheckedIncrement(Pos, End, errorMessage);
-
- return Pos;
-}
-
-/// SubstituteSpecialCommands - Given an invocation of $CALL or $ENV, output
-/// handler code. Helper function used by EmitCmdLineVecFill().
-StrVector::const_iterator
-SubstituteSpecialCommands (StrVector::const_iterator Pos,
- StrVector::const_iterator End,
- bool IsJoin, raw_ostream& O)
-{
-
- const std::string& cmd = *Pos;
-
- // Perform substitution.
- if (cmd == "$CALL") {
- Pos = SubstituteCall(Pos, End, IsJoin, O);
- }
- else if (cmd == "$ENV") {
- Pos = SubstituteEnv(Pos, End, O);
- }
- else {
- throw "Unknown special command: " + cmd;
- }
-
- // Handle '$CMD(ARG)/additional/text'.
- const std::string& Leftover = *Pos;
- assert(Leftover.at(0) == ')');
- if (Leftover.size() != 1)
- O << " + std::string(\"" << (Leftover.c_str() + 1) << "\")";
-
- return Pos;
-}
-
-/// EmitCmdLineVecFill - Emit code that fills in the command line
-/// vector. Helper function used by EmitGenerateActionMethod().
-void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName,
- bool IsJoin, unsigned IndentLevel,
- raw_ostream& O) {
- StrVector StrVec;
- TokenizeCmdLine(InitPtrToString(CmdLine), StrVec);
-
- if (StrVec.empty())
- throw "Tool '" + ToolName + "' has empty command line!";
-
- StrVector::const_iterator B = StrVec.begin(), E = StrVec.end();
-
- // Emit the command itself.
- assert(!StrVec[0].empty());
- O.indent(IndentLevel) << "cmd = ";
- if (StrVec[0][0] == '$') {
- B = SubstituteSpecialCommands(B, E, IsJoin, O);
- ++B;
- }
- else {
- O << '"' << StrVec[0] << '"';
- ++B;
- }
- O << ";\n";
-
- // Go through the command arguments.
- assert(B <= E);
- for (; B != E; ++B) {
- const std::string& cmd = *B;
-
- assert(!cmd.empty());
- O.indent(IndentLevel);
-
- if (cmd.at(0) == '$') {
- O << "vec.push_back(std::make_pair(0, ";
- B = SubstituteSpecialCommands(B, E, IsJoin, O);
- O << "));\n";
- }
- else {
- O << "vec.push_back(std::make_pair(0, \"" << cmd << "\"));\n";
- }
- }
-
-}
-
-/// EmitForEachListElementCycleHeader - Emit common code for iterating through
-/// all elements of a list. Helper function used by
-/// EmitForwardOptionPropertyHandlingCode.
-void EmitForEachListElementCycleHeader (const OptionDescription& D,
- unsigned IndentLevel,
- raw_ostream& O) {
- unsigned IndentLevel1 = IndentLevel + Indent1;
-
- O.indent(IndentLevel)
- << "for (" << D.GenTypeDeclaration()
- << "::iterator B = " << D.GenVariableName() << ".begin(),\n";
- O.indent(IndentLevel)
- << "E = " << D.GenVariableName() << ".end(); B != E;) {\n";
- O.indent(IndentLevel1) << "unsigned pos = " << D.GenVariableName()
- << ".getPosition(B - " << D.GenVariableName()
- << ".begin());\n";
-}
-
-/// EmitForwardOptionPropertyHandlingCode - Helper function used to
-/// implement EmitActionHandler. Emits code for
-/// handling the (forward) and (forward_as) option properties.
-void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
- unsigned IndentLevel,
- const std::string& NewName,
- raw_ostream& O) {
- const std::string& Name = NewName.empty()
- ? ("-" + D.Name)
- : NewName;
- unsigned IndentLevel1 = IndentLevel + Indent1;
-
- switch (D.Type) {
- case OptionType::Switch:
- O.indent(IndentLevel)
- << "vec.push_back(std::make_pair(" << D.GenVariableName()
- << ".getPosition(), \"" << Name << "\"));\n";
- break;
- case OptionType::Parameter:
- O.indent(IndentLevel) << "vec.push_back(std::make_pair("
- << D.GenVariableName()
- <<".getPosition(), \"" << Name;
-
- if (!D.isForwardNotSplit()) {
- O << "\"));\n";
- O.indent(IndentLevel) << "vec.push_back(std::make_pair("
- << D.GenVariableName() << ".getPosition(), "
- << D.GenVariableName() << "));\n";
- }
- else {
- O << "=\" + " << D.GenVariableName() << "));\n";
- }
- break;
- case OptionType::Prefix:
- O.indent(IndentLevel) << "vec.push_back(std::make_pair("
- << D.GenVariableName() << ".getPosition(), \""
- << Name << "\" + "
- << D.GenVariableName() << "));\n";
- break;
- case OptionType::PrefixList:
- EmitForEachListElementCycleHeader(D, IndentLevel, O);
- O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
- << Name << "\" + " << "*B));\n";
- O.indent(IndentLevel1) << "++B;\n";
-
- for (int i = 1, j = D.MultiVal; i < j; ++i) {
- O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, *B));\n";
- O.indent(IndentLevel1) << "++B;\n";
- }
-
- O.indent(IndentLevel) << "}\n";
- break;
- case OptionType::ParameterList:
- EmitForEachListElementCycleHeader(D, IndentLevel, O);
- O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
- << Name << "\"));\n";
-
- for (int i = 0, j = D.MultiVal; i < j; ++i) {
- O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, *B));\n";
- O.indent(IndentLevel1) << "++B;\n";
- }
-
- O.indent(IndentLevel) << "}\n";
- break;
- case OptionType::SwitchList:
- EmitForEachListElementCycleHeader(D, IndentLevel, O);
- O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
- << Name << "\"));\n";
- O.indent(IndentLevel1) << "++B;\n";
- O.indent(IndentLevel) << "}\n";
- break;
- case OptionType::Alias:
- default:
- throw "Aliases are not allowed in tool option descriptions!";
- }
-}
-
-/// ActionHandlingCallbackBase - Base class of EmitActionHandlersCallback and
-/// EmitPreprocessOptionsCallback.
-struct ActionHandlingCallbackBase
-{
-
- void onErrorDag(const DagInit& d,
- unsigned IndentLevel, raw_ostream& O) const
- {
- O.indent(IndentLevel)
- << "PrintError(\""
- << (d.getNumArgs() >= 1 ? InitPtrToString(d.getArg(0)) : "Unknown error!")
- << "\");\n";
- O.indent(IndentLevel) << "return 1;\n";
- }
-
- void onWarningDag(const DagInit& d,
- unsigned IndentLevel, raw_ostream& O) const
- {
- CheckNumberOfArguments(d, 1);
- O.indent(IndentLevel) << "llvm::errs() << \""
- << InitPtrToString(d.getArg(0)) << "\";\n";
- }
-
-};
-
-/// EmitActionHandlersCallback - Emit code that handles actions. Used by
-/// EmitGenerateActionMethod() as an argument to EmitCaseConstructHandler().
-class EmitActionHandlersCallback;
-
-typedef void (EmitActionHandlersCallback::* EmitActionHandlersCallbackHandler)
-(const DagInit&, unsigned, raw_ostream&) const;
-
-class EmitActionHandlersCallback :
- public ActionHandlingCallbackBase,
- public HandlerTable<EmitActionHandlersCallbackHandler>
-{
- typedef EmitActionHandlersCallbackHandler Handler;
-
- const OptionDescriptions& OptDescs;
-
- /// EmitHookInvocation - Common code for hook invocation from actions. Used by
- /// onAppendCmd and onOutputSuffix.
- void EmitHookInvocation(const std::string& Str,
- const char* BlockOpen, const char* BlockClose,
- unsigned IndentLevel, raw_ostream& O) const
- {
- StrVector Out;
- TokenizeCmdLine(Str, Out);
-
- for (StrVector::const_iterator B = Out.begin(), E = Out.end();
- B != E; ++B) {
- const std::string& cmd = *B;
-
- O.indent(IndentLevel) << BlockOpen;
-
- if (cmd.at(0) == '$')
- B = SubstituteSpecialCommands(B, E, /* IsJoin = */ true, O);
- else
- O << '"' << cmd << '"';
-
- O << BlockClose;
- }
- }
-
- void onAppendCmd (const DagInit& Dag,
- unsigned IndentLevel, raw_ostream& O) const
- {
- CheckNumberOfArguments(Dag, 1);
- this->EmitHookInvocation(InitPtrToString(Dag.getArg(0)),
- "vec.push_back(std::make_pair(65536, ", "));\n",
- IndentLevel, O);
- }
-
- void onForward (const DagInit& Dag,
- unsigned IndentLevel, raw_ostream& O) const
- {
- CheckNumberOfArguments(Dag, 1);
- const std::string& Name = InitPtrToString(Dag.getArg(0));
- EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name),
- IndentLevel, "", O);
- }
-
- void onForwardAs (const DagInit& Dag,
- unsigned IndentLevel, raw_ostream& O) const
- {
- CheckNumberOfArguments(Dag, 2);
- const std::string& Name = InitPtrToString(Dag.getArg(0));
- const std::string& NewName = InitPtrToString(Dag.getArg(1));
- EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name),
- IndentLevel, NewName, O);
- }
-
- void onForwardValue (const DagInit& Dag,
- unsigned IndentLevel, raw_ostream& O) const
- {
- CheckNumberOfArguments(Dag, 1);
- const std::string& Name = InitPtrToString(Dag.getArg(0));
- const OptionDescription& D = OptDescs.FindParameterListOrParameter(Name);
-
- if (D.isSwitchList()) {
- throw std::runtime_error
- ("forward_value is not allowed with switch_list");
- }
-
- if (D.isParameter()) {
- O.indent(IndentLevel) << "vec.push_back(std::make_pair("
- << D.GenVariableName() << ".getPosition(), "
- << D.GenVariableName() << "));\n";
- }
- else {
- O.indent(IndentLevel) << "for (" << D.GenTypeDeclaration()
- << "::iterator B = " << D.GenVariableName()
- << ".begin(), \n";
- O.indent(IndentLevel + Indent1) << " E = " << D.GenVariableName()
- << ".end(); B != E; ++B)\n";
- O.indent(IndentLevel) << "{\n";
- O.indent(IndentLevel + Indent1)
- << "unsigned pos = " << D.GenVariableName()
- << ".getPosition(B - " << D.GenVariableName()
- << ".begin());\n";
- O.indent(IndentLevel + Indent1)
- << "vec.push_back(std::make_pair(pos, *B));\n";
- O.indent(IndentLevel) << "}\n";
- }
- }
-
- void onForwardTransformedValue (const DagInit& Dag,
- unsigned IndentLevel, raw_ostream& O) const
- {
- CheckNumberOfArguments(Dag, 2);
- const std::string& Name = InitPtrToString(Dag.getArg(0));
- const std::string& Hook = InitPtrToString(Dag.getArg(1));
- const OptionDescription& D = OptDescs.FindParameterListOrParameter(Name);
-
- O.indent(IndentLevel) << "vec.push_back(std::make_pair("
- << D.GenVariableName() << ".getPosition("
- << (D.isList() ? "0" : "") << "), "
- << "hooks::" << Hook << "(" << D.GenVariableName()
- << (D.isParameter() ? ".c_str()" : "") << ")));\n";
- }
-
- void onNoOutFile (const DagInit& Dag,
- unsigned IndentLevel, raw_ostream& O) const
- {
- CheckNumberOfArguments(Dag, 0);
- O.indent(IndentLevel) << "no_out_file = true;\n";
- }
-
- void onOutputSuffix (const DagInit& Dag,
- unsigned IndentLevel, raw_ostream& O) const
- {
- CheckNumberOfArguments(Dag, 1);
- this->EmitHookInvocation(InitPtrToString(Dag.getArg(0)),
- "output_suffix = ", ";\n", IndentLevel, O);
- }
-
- void onStopCompilation (const DagInit& Dag,
- unsigned IndentLevel, raw_ostream& O) const
- {
- O.indent(IndentLevel) << "stop_compilation = true;\n";
- }
-
-
- void onUnpackValues (const DagInit& Dag,
- unsigned IndentLevel, raw_ostream& O) const
- {
- throw "'unpack_values' is deprecated. "
- "Use 'comma_separated' + 'forward_value' instead!";
- }
-
- public:
-
- explicit EmitActionHandlersCallback(const OptionDescriptions& OD)
- : OptDescs(OD)
- {
- if (!staticMembersInitialized_) {
- AddHandler("error", &EmitActionHandlersCallback::onErrorDag);
- AddHandler("warning", &EmitActionHandlersCallback::onWarningDag);
- AddHandler("append_cmd", &EmitActionHandlersCallback::onAppendCmd);
- AddHandler("forward", &EmitActionHandlersCallback::onForward);
- AddHandler("forward_as", &EmitActionHandlersCallback::onForwardAs);
- AddHandler("forward_value", &EmitActionHandlersCallback::onForwardValue);
- AddHandler("forward_transformed_value",
- &EmitActionHandlersCallback::onForwardTransformedValue);
- AddHandler("no_out_file",
- &EmitActionHandlersCallback::onNoOutFile);
- AddHandler("output_suffix", &EmitActionHandlersCallback::onOutputSuffix);
- AddHandler("stop_compilation",
- &EmitActionHandlersCallback::onStopCompilation);
- AddHandler("unpack_values",
- &EmitActionHandlersCallback::onUnpackValues);
-
-
- staticMembersInitialized_ = true;
- }
- }
-
- void operator()(const Init* I,
- unsigned IndentLevel, raw_ostream& O) const
- {
- InvokeDagInitHandler(this, I, IndentLevel, O);
- }
-};
-
-void EmitGenerateActionMethodHeader(const ToolDescription& D,
- bool IsJoin, bool Naked,
- raw_ostream& O)
-{
- O.indent(Indent1) << "int GenerateAction(Action& Out,\n";
-
- if (IsJoin)
- O.indent(Indent2) << "const PathVector& inFiles,\n";
- else
- O.indent(Indent2) << "const sys::Path& inFile,\n";
-
- O.indent(Indent2) << "const bool HasChildren,\n";
- O.indent(Indent2) << "const llvm::sys::Path& TempDir,\n";
- O.indent(Indent2) << "const InputLanguagesSet& InLangs,\n";
- O.indent(Indent2) << "const LanguageMap& LangMap) const\n";
- O.indent(Indent1) << "{\n";
-
- if (!Naked) {
- O.indent(Indent2) << "std::string cmd;\n";
- O.indent(Indent2) << "std::string out_file;\n";
- O.indent(Indent2)
- << "std::vector<std::pair<unsigned, std::string> > vec;\n";
- O.indent(Indent2) << "bool stop_compilation = !HasChildren;\n";
- O.indent(Indent2) << "bool no_out_file = false;\n";
- O.indent(Indent2) << "std::string output_suffix(\""
- << D.OutputSuffix << "\");\n";
- }
-}
-
-// EmitGenerateActionMethod - Emit either a normal or a "join" version of the
-// Tool::GenerateAction() method.
-void EmitGenerateActionMethod (const ToolDescription& D,
- const OptionDescriptions& OptDescs,
- bool IsJoin, raw_ostream& O) {
-
- EmitGenerateActionMethodHeader(D, IsJoin, /* Naked = */ false, O);
-
- if (!D.CmdLine)
- throw "Tool " + D.Name + " has no cmd_line property!";
-
- // Process the 'command' property.
- O << '\n';
- EmitCmdLineVecFill(D.CmdLine, D.Name, IsJoin, Indent2, O);
- O << '\n';
-
- // Process the 'actions' list of this tool.
- if (D.Actions)
- EmitCaseConstructHandler(D.Actions, Indent2,
- EmitActionHandlersCallback(OptDescs),
- false, OptDescs, O);
- O << '\n';
-
- // Input file (s)
- if (!D.InFileOption.empty()) {
- O.indent(Indent2)
- << "vec.push_back(std::make_pair(InputFilenames.getPosition(0), \""
- << D.InFileOption << "\");\n";
- }
-
- if (IsJoin) {
- O.indent(Indent2)
- << "for (PathVector::const_iterator B = inFiles.begin(),\n";
- O.indent(Indent3) << "E = inFiles.end(); B != E; ++B)\n";
- O.indent(Indent2) << "{\n";
- O.indent(Indent3) << "vec.push_back(std::make_pair("
- << "InputFilenames.getPosition(B - inFiles.begin()), "
- << "B->str()));\n";
- O.indent(Indent2) << "}\n";
- }
- else {
- O.indent(Indent2) << "vec.push_back(std::make_pair("
- << "InputFilenames.getPosition(0), inFile.str()));\n";
- }
-
- // Output file
- O.indent(Indent2) << "if (!no_out_file) {\n";
- if (!D.OutFileOption.empty())
- O.indent(Indent3) << "vec.push_back(std::make_pair(65536, \""
- << D.OutFileOption << "\"));\n";
-
- O.indent(Indent3) << "out_file = this->OutFilename("
- << (IsJoin ? "sys::Path(),\n" : "inFile,\n");
- O.indent(Indent4) <<
- "TempDir, stop_compilation, output_suffix.c_str()).str();\n\n";
- O.indent(Indent3) << "vec.push_back(std::make_pair(65536, out_file));\n";
-
- O.indent(Indent2) << "}\n\n";
-
- // Handle the Sink property.
- std::string SinkOption("autogenerated::");
- SinkOption += SinkOptionName;
- if (D.isSink()) {
- O.indent(Indent2) << "if (!" << SinkOption << ".empty()) {\n";
- O.indent(Indent3) << "for (cl::list<std::string>::iterator B = "
- << SinkOption << ".begin(), E = " << SinkOption
- << ".end(); B != E; ++B)\n";
- O.indent(Indent4) << "vec.push_back(std::make_pair(" << SinkOption
- << ".getPosition(B - " << SinkOption
- << ".begin()), *B));\n";
- O.indent(Indent2) << "}\n";
- }
-
- O.indent(Indent2) << "Out.Construct(cmd, this->SortArgs(vec), "
- << "stop_compilation, out_file);\n";
- O.indent(Indent2) << "return 0;\n";
- O.indent(Indent1) << "}\n\n";
-}
-
-/// EmitGenerateActionMethods - Emit two GenerateAction() methods for
-/// a given Tool class.
-void EmitGenerateActionMethods (const ToolDescription& ToolDesc,
- const OptionDescriptions& OptDescs,
- raw_ostream& O) {
- if (!ToolDesc.isJoin()) {
- EmitGenerateActionMethodHeader(ToolDesc, /* IsJoin = */ true,
- /* Naked = */ true, O);
- O.indent(Indent2) << "PrintError(\"" << ToolDesc.Name
- << " is not a Join tool!\");\n";
- O.indent(Indent2) << "return -1;\n";
- O.indent(Indent1) << "}\n\n";
- }
- else {
- EmitGenerateActionMethod(ToolDesc, OptDescs, true, O);
- }
-
- EmitGenerateActionMethod(ToolDesc, OptDescs, false, O);
-}
-
-/// EmitInOutLanguageMethods - Emit the [Input,Output]Language()
-/// methods for a given Tool class.
-void EmitInOutLanguageMethods (const ToolDescription& D, raw_ostream& O) {
- O.indent(Indent1) << "const char** InputLanguages() const {\n";
- O.indent(Indent2) << "return InputLanguages_;\n";
- O.indent(Indent1) << "}\n\n";
-
- O.indent(Indent1) << "const char** OutputLanguages() const {\n";
- O.indent(Indent2) << "return OutputLanguages_;\n";
- O.indent(Indent1) << "}\n\n";
-}
-
-/// EmitNameMethod - Emit the Name() method for a given Tool class.
-void EmitNameMethod (const ToolDescription& D, raw_ostream& O) {
- O.indent(Indent1) << "const char* Name() const {\n";
- O.indent(Indent2) << "return \"" << D.Name << "\";\n";
- O.indent(Indent1) << "}\n\n";
-}
-
-/// EmitIsJoinMethod - Emit the IsJoin() method for a given Tool
-/// class.
-void EmitIsJoinMethod (const ToolDescription& D, raw_ostream& O) {
- O.indent(Indent1) << "bool IsJoin() const {\n";
- if (D.isJoin())
- O.indent(Indent2) << "return true;\n";
- else
- O.indent(Indent2) << "return false;\n";
- O.indent(Indent1) << "}\n\n";
-}
-
-/// EmitWorksOnEmptyCallback - Callback used by EmitWorksOnEmptyMethod in
-/// conjunction with EmitCaseConstructHandler.
-void EmitWorksOnEmptyCallback (const Init* Value,
- unsigned IndentLevel, raw_ostream& O) {
- CheckBooleanConstant(Value);
- O.indent(IndentLevel) << "return " << Value->getAsString() << ";\n";
-}
-
-/// EmitWorksOnEmptyMethod - Emit the WorksOnEmpty() method for a given Tool
-/// class.
-void EmitWorksOnEmptyMethod (const ToolDescription& D,
- const OptionDescriptions& OptDescs,
- raw_ostream& O)
-{
- O.indent(Indent1) << "bool WorksOnEmpty() const {\n";
- if (D.OnEmpty == 0)
- O.indent(Indent2) << "return false;\n";
- else
- EmitCaseConstructHandler(D.OnEmpty, Indent2, EmitWorksOnEmptyCallback,
- /*EmitElseIf = */ true, OptDescs, O);
- O.indent(Indent1) << "}\n\n";
-}
-
-/// EmitStrArray - Emit definition of a 'const char**' static member
-/// variable. Helper used by EmitStaticMemberDefinitions();
-void EmitStrArray(const std::string& Name, const std::string& VarName,
- const StrVector& StrVec, raw_ostream& O) {
- O << "const char* " << Name << "::" << VarName << "[] = {";
- for (StrVector::const_iterator B = StrVec.begin(), E = StrVec.end();
- B != E; ++B)
- O << '\"' << *B << "\", ";
- O << "0};\n";
-}
-
-/// EmitStaticMemberDefinitions - Emit static member definitions for a
-/// given Tool class.
-void EmitStaticMemberDefinitions(const ToolDescription& D, raw_ostream& O) {
- if (D.InLanguage.empty())
- throw "Tool " + D.Name + " has no 'in_language' property!";
- if (D.OutLanguage.empty())
- throw "Tool " + D.Name + " has no 'out_language' property!";
-
- EmitStrArray(D.Name, "InputLanguages_", D.InLanguage, O);
- EmitStrArray(D.Name, "OutputLanguages_", D.OutLanguage, O);
- O << '\n';
-}
-
-/// EmitToolClassDefinition - Emit a Tool class definition.
-void EmitToolClassDefinition (const ToolDescription& D,
- const OptionDescriptions& OptDescs,
- raw_ostream& O) {
- if (D.Name == "root")
- return;
-
- // Header
- O << "class " << D.Name << " : public ";
- if (D.isJoin())
- O << "JoinTool";
- else
- O << "Tool";
-
- O << " {\nprivate:\n";
- O.indent(Indent1) << "static const char* InputLanguages_[];\n";
- O.indent(Indent1) << "static const char* OutputLanguages_[];\n\n";
-
- O << "public:\n";
- EmitNameMethod(D, O);
- EmitInOutLanguageMethods(D, O);
- EmitIsJoinMethod(D, O);
- EmitWorksOnEmptyMethod(D, OptDescs, O);
- EmitGenerateActionMethods(D, OptDescs, O);
-
- // Close class definition
- O << "};\n";
-
- EmitStaticMemberDefinitions(D, O);
-
-}
-
-/// EmitOptionDefinitions - Iterate over a list of option descriptions
-/// and emit registration code.
-void EmitOptionDefinitions (const OptionDescriptions& descs,
- bool HasSink, raw_ostream& O)
-{
- std::vector<OptionDescription> Aliases;
-
- // Emit static cl::Option variables.
- for (OptionDescriptions::const_iterator B = descs.begin(),
- E = descs.end(); B!=E; ++B) {
- const OptionDescription& val = B->second;
-
- if (val.Type == OptionType::Alias) {
- Aliases.push_back(val);
- continue;
- }
-
- O << val.GenTypeDeclaration() << ' '
- << val.GenPlainVariableName();
-
- O << "(\"" << val.Name << "\"\n";
-
- if (val.Type == OptionType::Prefix || val.Type == OptionType::PrefixList)
- O << ", cl::Prefix";
-
- if (val.isRequired()) {
- if (val.isList() && !val.isMultiVal())
- O << ", cl::OneOrMore";
- else
- O << ", cl::Required";
- }
-
- if (val.isOptional())
- O << ", cl::Optional";
-
- if (val.isOneOrMore())
- O << ", cl::OneOrMore";
-
- if (val.isZeroOrMore())
- O << ", cl::ZeroOrMore";
-
- if (val.isReallyHidden())
- O << ", cl::ReallyHidden";
- else if (val.isHidden())
- O << ", cl::Hidden";
-
- if (val.isCommaSeparated())
- O << ", cl::CommaSeparated";
-
- if (val.MultiVal > 1)
- O << ", cl::multi_val(" << val.MultiVal << ')';
-
- if (val.InitVal) {
- const std::string& str = val.InitVal->getAsString();
- O << ", cl::init(" << str << ')';
- }
-
- if (!val.Help.empty())
- O << ", cl::desc(\"" << val.Help << "\")";
-
- O << ");\n\n";
- }
-
- // Emit the aliases (they should go after all the 'proper' options).
- for (std::vector<OptionDescription>::const_iterator
- B = Aliases.begin(), E = Aliases.end(); B != E; ++B) {
- const OptionDescription& val = *B;
-
- O << val.GenTypeDeclaration() << ' '
- << val.GenPlainVariableName()
- << "(\"" << val.Name << '\"';
-
- const OptionDescription& D = descs.FindOption(val.Help);
- O << ", cl::aliasopt(" << D.GenVariableName() << ")";
-
- O << ", cl::desc(\"" << "An alias for -" + val.Help << "\"));\n";
- }
-
- // Emit the sink option.
- if (HasSink)
- O << "cl::list<std::string> " << SinkOptionName << "(cl::Sink);\n";
-
- O << '\n';
-}
-
-/// EmitPreprocessOptionsCallback - Helper function passed to
-/// EmitCaseConstructHandler() by EmitPreprocessOptions().
-
-class EmitPreprocessOptionsCallback;
-
-typedef void
-(EmitPreprocessOptionsCallback::* EmitPreprocessOptionsCallbackHandler)
-(const DagInit&, unsigned, raw_ostream&) const;
-
-class EmitPreprocessOptionsCallback :
- public ActionHandlingCallbackBase,
- public HandlerTable<EmitPreprocessOptionsCallbackHandler>
-{
- typedef EmitPreprocessOptionsCallbackHandler Handler;
- typedef void
- (EmitPreprocessOptionsCallback::* HandlerImpl)
- (const Init*, unsigned, raw_ostream&) const;
-
- const OptionDescriptions& OptDescs_;
-
- void onEachArgument(const DagInit& d, HandlerImpl h,
- unsigned IndentLevel, raw_ostream& O) const
- {
- CheckNumberOfArguments(d, 1);
-
- for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) {
- ((this)->*(h))(d.getArg(i), IndentLevel, O);
- }
- }
-
- void onUnsetOptionImpl(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() << " = false;\n";
- }
- else if (OptDesc.isParameter()) {
- O.indent(IndentLevel) << OptDesc.GenVariableName() << " = \"\";\n";
- }
- else if (OptDesc.isList()) {
- O.indent(IndentLevel) << OptDesc.GenVariableName() << ".clear();\n";
- }
- else {
- throw "Can't apply 'unset_option' to alias option '" + OptName + "'!";
- }
- }
-
- void onUnsetOption(const DagInit& d,
- unsigned IndentLevel, raw_ostream& O) const
- {
- this->onEachArgument(d, &EmitPreprocessOptionsCallback::onUnsetOptionImpl,
- IndentLevel, O);
- }
-
- void onSetOptionImpl(const DagInit& D,
- unsigned IndentLevel, raw_ostream& O) const {
- CheckNumberOfArguments(D, 2);
-
- const std::string& OptName = InitPtrToString(D.getArg(0));
- const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
- const Init* Value = D.getArg(1);
-
- if (OptDesc.isList()) {
- const ListInit& List = InitPtrToList(Value);
-
- O.indent(IndentLevel) << OptDesc.GenVariableName() << ".clear();\n";
- for (ListInit::const_iterator B = List.begin(), E = List.end();
- B != E; ++B) {
- const Init* CurElem = *B;
- if (OptDesc.isSwitchList())
- CheckBooleanConstant(CurElem);
-
- O.indent(IndentLevel)
- << OptDesc.GenVariableName() << ".push_back(\""
- << (OptDesc.isSwitchList() ? CurElem->getAsString()
- : InitPtrToString(CurElem))
- << "\");\n";
- }
- }
- else if (OptDesc.isSwitch()) {
- CheckBooleanConstant(Value);
- O.indent(IndentLevel) << OptDesc.GenVariableName()
- << " = " << Value->getAsString() << ";\n";
- }
- else if (OptDesc.isParameter()) {
- const std::string& Str = InitPtrToString(Value);
- O.indent(IndentLevel) << OptDesc.GenVariableName()
- << " = \"" << Str << "\";\n";
- }
- else {
- throw "Can't apply 'set_option' to alias option '" + OptName + "'!";
- }
- }
-
- 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";
- O << "}\n\n";
-}
-
-class DoEmitPopulateLanguageMap;
-typedef void (DoEmitPopulateLanguageMap::* DoEmitPopulateLanguageMapHandler)
-(const DagInit& D);
-
-class DoEmitPopulateLanguageMap
-: public HandlerTable<DoEmitPopulateLanguageMapHandler>
-{
-private:
- raw_ostream& O_;
-
-public:
-
- explicit DoEmitPopulateLanguageMap (raw_ostream& O) : O_(O) {
- if (!staticMembersInitialized_) {
- AddHandler("lang_to_suffixes",
- &DoEmitPopulateLanguageMap::onLangToSuffixes);
-
- staticMembersInitialized_ = true;
- }
- }
-
- void operator() (Init* I) {
- InvokeDagInitHandler(this, I);
- }
-
-private:
-
- void onLangToSuffixes (const DagInit& d) {
- CheckNumberOfArguments(d, 2);
-
- const std::string& Lang = InitPtrToString(d.getArg(0));
- Init* Suffixes = d.getArg(1);
-
- // Second argument to lang_to_suffixes is either a single string...
- if (typeid(*Suffixes) == typeid(StringInit)) {
- O_.indent(Indent1) << "langMap[\"" << InitPtrToString(Suffixes)
- << "\"] = \"" << Lang << "\";\n";
- }
- // ...or a list of strings.
- else {
- const ListInit& Lst = InitPtrToList(Suffixes);
- assert(Lst.size() != 0);
- for (ListInit::const_iterator B = Lst.begin(), E = Lst.end();
- B != E; ++B) {
- O_.indent(Indent1) << "langMap[\"" << InitPtrToString(*B)
- << "\"] = \"" << Lang << "\";\n";
- }
- }
- }
-
-};
-
-/// EmitPopulateLanguageMap - Emit the PopulateLanguageMap() function.
-void EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O)
-{
- O << "int PopulateLanguageMap (LanguageMap& langMap) {\n";
-
- // For each LanguageMap:
- const RecordVector& LangMaps =
- Records.getAllDerivedDefinitions("LanguageMap");
-
- // Call DoEmitPopulateLanguageMap.
- for (RecordVector::const_iterator B = LangMaps.begin(),
- E = LangMaps.end(); B!=E; ++B) {
- ListInit* LangMap = (*B)->getValueAsListInit("map");
- std::for_each(LangMap->begin(), LangMap->end(),
- DoEmitPopulateLanguageMap(O));
- }
-
- O << '\n';
- O.indent(Indent1) << "return 0;\n";
- O << "}\n\n";
-}
-
-/// EmitEdgePropertyHandlerCallback - Emits code that handles edge
-/// properties. Helper function passed to EmitCaseConstructHandler() by
-/// EmitEdgeClass().
-void EmitEdgePropertyHandlerCallback (const Init* i, unsigned IndentLevel,
- raw_ostream& O) {
- const DagInit& d = InitPtrToDag(i);
- const std::string& OpName = GetOperatorName(d);
-
- if (OpName == "inc_weight") {
- O.indent(IndentLevel) << "ret += ";
- }
- else if (OpName == "error") {
- CheckNumberOfArguments(d, 1);
- O.indent(IndentLevel) << "PrintError(\""
- << InitPtrToString(d.getArg(0))
- << "\");\n";
- O.indent(IndentLevel) << "return -1;\n";
- return;
- }
- else {
- throw "Unknown operator in edge properties list: '" + OpName + "'!"
- "\nOnly 'inc_weight', 'dec_weight' and 'error' are allowed.";
- }
-
- if (d.getNumArgs() > 0)
- O << InitPtrToInt(d.getArg(0)) << ";\n";
- else
- O << "2;\n";
-
-}
-
-/// EmitEdgeClass - Emit a single Edge# class.
-void EmitEdgeClass (unsigned N, const std::string& Target,
- const DagInit& Case, const OptionDescriptions& OptDescs,
- raw_ostream& O) {
-
- // Class constructor.
- O << "class Edge" << N << ": public Edge {\n"
- << "public:\n";
- O.indent(Indent1) << "Edge" << N << "() : Edge(\"" << Target
- << "\") {}\n\n";
-
- // Function Weight().
- O.indent(Indent1)
- << "int Weight(const InputLanguagesSet& InLangs) const {\n";
- O.indent(Indent2) << "unsigned ret = 0;\n";
-
- // Handle the 'case' construct.
- EmitCaseConstructHandler(&Case, Indent2, EmitEdgePropertyHandlerCallback,
- false, OptDescs, O);
-
- O.indent(Indent2) << "return ret;\n";
- O.indent(Indent1) << "}\n\n};\n\n";
-}
-
-/// EmitEdgeClasses - Emit Edge* classes that represent graph edges.
-void EmitEdgeClasses (const DagVector& EdgeVector,
- const OptionDescriptions& OptDescs,
- raw_ostream& O) {
- int i = 0;
- for (DagVector::const_iterator B = EdgeVector.begin(),
- E = EdgeVector.end(); B != E; ++B) {
- const DagInit& Edge = **B;
- const std::string& Name = GetOperatorName(Edge);
-
- if (Name == "optional_edge") {
- assert(IsOptionalEdge(Edge));
- const std::string& NodeB = InitPtrToString(Edge.getArg(1));
-
- const DagInit& Weight = InitPtrToDag(Edge.getArg(2));
- EmitEdgeClass(i, NodeB, Weight, OptDescs, O);
- }
- else if (Name != "edge") {
- throw "Unknown edge class: '" + Name + "'!";
- }
-
- ++i;
- }
-}
-
-/// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraph() function.
-void EmitPopulateCompilationGraph (const DagVector& EdgeVector,
- const ToolDescriptions& ToolDescs,
- raw_ostream& O)
-{
- O << "int PopulateCompilationGraph (CompilationGraph& G) {\n";
-
- for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
- E = ToolDescs.end(); B != E; ++B)
- O.indent(Indent1) << "G.insertNode(new " << (*B)->Name << "());\n";
-
- O << '\n';
-
- // Insert edges.
-
- int i = 0;
- 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));
-
- O.indent(Indent1) << "if (int ret = G.insertEdge(\"" << NodeA << "\", ";
-
- if (IsOptionalEdge(Edge))
- O << "new Edge" << i << "()";
- else
- O << "new SimpleEdge(\"" << NodeB << "\")";
-
- O << "))\n";
- O.indent(Indent2) << "return ret;\n";
-
- ++i;
- }
-
- O << '\n';
- O.indent(Indent1) << "return 0;\n";
- O << "}\n\n";
-}
-
-/// HookInfo - Information about the hook type and number of arguments.
-struct HookInfo {
-
- // A hook can either have a single parameter of type std::vector<std::string>,
- // or NumArgs parameters of type const char*.
- enum HookType { ListHook, ArgHook };
-
- HookType Type;
- unsigned NumArgs;
-
- HookInfo() : Type(ArgHook), NumArgs(1)
- {}
-
- HookInfo(HookType T) : Type(T), NumArgs(1)
- {}
-
- HookInfo(unsigned N) : Type(ArgHook), NumArgs(N)
- {}
-};
-
-typedef llvm::StringMap<HookInfo> HookInfoMap;
-
-/// ExtractHookNames - Extract the hook names from all instances of
-/// $CALL(HookName) in the provided command line string/action. Helper
-/// function used by FillInHookNames().
-class ExtractHookNames {
- HookInfoMap& HookNames_;
- const OptionDescriptions& OptDescs_;
-public:
- ExtractHookNames(HookInfoMap& HookNames, const OptionDescriptions& OptDescs)
- : HookNames_(HookNames), OptDescs_(OptDescs)
- {}
-
- void onAction (const DagInit& Dag) {
- const std::string& Name = GetOperatorName(Dag);
-
- if (Name == "forward_transformed_value") {
- CheckNumberOfArguments(Dag, 2);
- const std::string& OptName = InitPtrToString(Dag.getArg(0));
- const std::string& HookName = InitPtrToString(Dag.getArg(1));
- const OptionDescription& D =
- OptDescs_.FindParameterListOrParameter(OptName);
-
- HookNames_[HookName] = HookInfo(D.isList() ? HookInfo::ListHook
- : HookInfo::ArgHook);
- }
- else if (Name == "append_cmd" || Name == "output_suffix") {
- CheckNumberOfArguments(Dag, 1);
- this->onCmdLine(InitPtrToString(Dag.getArg(0)));
- }
- }
-
- void onCmdLine(const std::string& Cmd) {
- StrVector cmds;
- TokenizeCmdLine(Cmd, cmds);
-
- for (StrVector::const_iterator B = cmds.begin(), E = cmds.end();
- B != E; ++B) {
- const std::string& cmd = *B;
-
- if (cmd == "$CALL") {
- unsigned NumArgs = 0;
- CheckedIncrement(B, E, "Syntax error in $CALL invocation!");
- const std::string& HookName = *B;
-
- if (HookName.at(0) == ')')
- throw "$CALL invoked with no arguments!";
-
- while (++B != E && B->at(0) != ')') {
- ++NumArgs;
- }
-
- HookInfoMap::const_iterator H = HookNames_.find(HookName);
-
- if (H != HookNames_.end() && H->second.NumArgs != NumArgs &&
- H->second.Type != HookInfo::ArgHook)
- throw "Overloading of hooks is not allowed. Overloaded hook: "
- + HookName;
- else
- HookNames_[HookName] = HookInfo(NumArgs);
- }
- }
- }
-
- void operator()(const Init* Arg) {
-
- // We're invoked on an action (either a dag or a dag list).
- if (typeid(*Arg) == typeid(DagInit)) {
- const DagInit& Dag = InitPtrToDag(Arg);
- this->onAction(Dag);
- return;
- }
- else if (typeid(*Arg) == typeid(ListInit)) {
- const ListInit& List = InitPtrToList(Arg);
- for (ListInit::const_iterator B = List.begin(), E = List.end(); B != E;
- ++B) {
- const DagInit& Dag = InitPtrToDag(*B);
- this->onAction(Dag);
- }
- return;
- }
-
- // We're invoked on a command line string.
- this->onCmdLine(InitPtrToString(Arg));
- }
-
- void operator()(const Init* Statement, unsigned) {
- this->operator()(Statement);
- }
-};
-
-/// FillInHookNames - Actually extract the hook names from all command
-/// line strings. Helper function used by EmitHookDeclarations().
-void FillInHookNames(const ToolDescriptions& ToolDescs,
- const OptionDescriptions& OptDescs,
- HookInfoMap& HookNames)
-{
- // For all tool descriptions:
- for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
- E = ToolDescs.end(); B != E; ++B) {
- const ToolDescription& D = *(*B);
-
- // Look for 'forward_transformed_value' in 'actions'.
- if (D.Actions)
- WalkCase(D.Actions, Id(), ExtractHookNames(HookNames, OptDescs));
-
- // Look for hook invocations in 'cmd_line'.
- if (!D.CmdLine)
- continue;
- if (dynamic_cast<StringInit*>(D.CmdLine))
- // This is a string.
- ExtractHookNames(HookNames, OptDescs).operator()(D.CmdLine);
- else
- // This is a 'case' construct.
- WalkCase(D.CmdLine, Id(), ExtractHookNames(HookNames, OptDescs));
- }
-}
-
-/// EmitHookDeclarations - Parse CmdLine fields of all the tool
-/// property records and emit hook function declaration for each
-/// instance of $CALL(HookName).
-void EmitHookDeclarations(const ToolDescriptions& ToolDescs,
- const OptionDescriptions& OptDescs, raw_ostream& O) {
- HookInfoMap HookNames;
-
- FillInHookNames(ToolDescs, OptDescs, HookNames);
- if (HookNames.empty())
- return;
-
- for (HookInfoMap::const_iterator B = HookNames.begin(),
- E = HookNames.end(); B != E; ++B) {
- StringRef HookName = B->first();
- const HookInfo &Info = B->second;
-
- O.indent(Indent1) << "std::string " << HookName << "(";
-
- if (Info.Type == HookInfo::ArgHook) {
- for (unsigned i = 0, j = Info.NumArgs; i < j; ++i) {
- O << "const char* Arg" << i << (i+1 == j ? "" : ", ");
- }
- }
- else {
- O << "const std::vector<std::string>& Arg";
- }
-
- O <<");\n";
- }
-}
-
-/// EmitIncludes - Emit necessary #include directives and some
-/// additional declarations.
-void EmitIncludes(raw_ostream& O) {
- O << "#include \"llvm/CompilerDriver/BuiltinOptions.h\"\n"
- << "#include \"llvm/CompilerDriver/CompilationGraph.h\"\n"
- << "#include \"llvm/CompilerDriver/Error.h\"\n"
- << "#include \"llvm/CompilerDriver/Tool.h\"\n\n"
-
- << "#include \"llvm/Support/CommandLine.h\"\n"
- << "#include \"llvm/Support/raw_ostream.h\"\n\n"
-
- << "#include <algorithm>\n"
- << "#include <cstdlib>\n"
- << "#include <iterator>\n"
- << "#include <stdexcept>\n\n"
-
- << "using namespace llvm;\n"
- << "using namespace llvmc;\n\n"
-
- << "inline const char* checkCString(const char* s)\n"
- << "{ return s == NULL ? \"\" : s; }\n\n";
-}
-
-
-/// DriverData - Holds all information about the driver.
-struct DriverData {
- OptionDescriptions OptDescs;
- ToolDescriptions ToolDescs;
- DagVector Edges;
- bool HasSink;
-};
-
-/// HasSink - Go through the list of tool descriptions and check if
-/// there are any with the 'sink' property set.
-bool HasSink(const ToolDescriptions& ToolDescs) {
- for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
- E = ToolDescs.end(); B != E; ++B)
- if ((*B)->isSink())
- return true;
-
- return false;
-}
-
-/// CollectDriverData - Collect compilation graph edges, tool properties and
-/// option properties from the parse tree.
-void CollectDriverData (const RecordKeeper& Records, DriverData& Data) {
- // Collect option properties.
- const RecordVector& OptionLists =
- Records.getAllDerivedDefinitions("OptionList");
- CollectOptionDescriptions(OptionLists, Data.OptDescs);
-
- // Collect tool properties.
- const RecordVector& Tools = Records.getAllDerivedDefinitions("Tool");
- CollectToolDescriptions(Tools, Data.ToolDescs);
- Data.HasSink = HasSink(Data.ToolDescs);
-
- // Collect compilation graph edges.
- const RecordVector& CompilationGraphs =
- Records.getAllDerivedDefinitions("CompilationGraph");
- FillInEdgeVector(CompilationGraphs, Data.Edges);
-}
-
-/// CheckDriverData - Perform some sanity checks on the collected data.
-void CheckDriverData(DriverData& Data) {
- // Filter out all tools not mentioned in the compilation graph.
- FilterNotInGraph(Data.Edges, Data.ToolDescs);
-
- // Typecheck the compilation graph.
- // TODO: use a genuine graph representation instead of a vector and check for
- // multiple edges.
- TypecheckGraph(Data.Edges, Data.ToolDescs);
-
- // Check that there are no options without side effects (specified
- // only in the OptionList).
- CheckForSuperfluousOptions(Data.Edges, Data.ToolDescs, Data.OptDescs);
-}
-
-void EmitDriverCode(const DriverData& Data,
- raw_ostream& O, RecordKeeper &Records) {
- // Emit file header.
- EmitIncludes(O);
-
- // Emit global option registration code.
- O << "namespace llvmc {\n"
- << "namespace autogenerated {\n\n";
- EmitOptionDefinitions(Data.OptDescs, Data.HasSink, O);
- O << "} // End namespace autogenerated.\n"
- << "} // End namespace llvmc.\n\n";
-
- // Emit hook declarations.
- O << "namespace hooks {\n";
- EmitHookDeclarations(Data.ToolDescs, Data.OptDescs, O);
- O << "} // End namespace hooks.\n\n";
-
- O << "namespace {\n\n";
- O << "using namespace llvmc::autogenerated;\n\n";
-
- // Emit Tool classes.
- for (ToolDescriptions::const_iterator B = Data.ToolDescs.begin(),
- E = Data.ToolDescs.end(); B!=E; ++B)
- EmitToolClassDefinition(*(*B), Data.OptDescs, O);
-
- // Emit Edge# classes.
- EmitEdgeClasses(Data.Edges, Data.OptDescs, O);
-
- O << "} // End anonymous namespace.\n\n";
-
- O << "namespace llvmc {\n";
- O << "namespace autogenerated {\n\n";
-
- // Emit PreprocessOptions() function.
- EmitPreprocessOptions(Records, Data.OptDescs, O);
-
- // Emit PopulateLanguageMap() function
- // (language map maps from file extensions to language names).
- EmitPopulateLanguageMap(Records, O);
-
- // Emit PopulateCompilationGraph() function.
- EmitPopulateCompilationGraph(Data.Edges, Data.ToolDescs, O);
-
- O << "} // End namespace autogenerated.\n";
- O << "} // End namespace llvmc.\n\n";
-
- // EOF
-}
-
-
-// End of anonymous namespace
-}
-
-/// run - The back-end entry point.
-void LLVMCConfigurationEmitter::run (raw_ostream &O) {
- try {
- DriverData Data;
-
- CollectDriverData(Records, Data);
- CheckDriverData(Data);
-
- this->EmitSourceFileHeader("llvmc-based driver: auto-generated code", O);
- EmitDriverCode(Data, O, Records);
-
- } catch (std::exception& Error) {
- throw Error.what() + std::string(" - usually this means a syntax error.");
- }
-}
diff --git a/utils/TableGen/LLVMCConfigurationEmitter.h b/utils/TableGen/LLVMCConfigurationEmitter.h
deleted file mode 100644
index 0f2ff37196..0000000000
--- a/utils/TableGen/LLVMCConfigurationEmitter.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===- LLVMCConfigurationEmitter.cpp - Generate LLVMCC 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 LLVMCC configuration code.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_UTILS_TABLEGEN_LLVMCCONF_EMITTER_H
-#define LLVM_UTILS_TABLEGEN_LLVMCCONF_EMITTER_H
-
-#include "TableGenBackend.h"
-
-namespace llvm {
-
- /// LLVMCConfigurationEmitter - TableGen backend that generates
- /// configuration code for LLVMC.
- class LLVMCConfigurationEmitter : public TableGenBackend {
- RecordKeeper &Records;
- public:
- explicit LLVMCConfigurationEmitter(RecordKeeper &records) :
- Records(records) {}
-
- // run - Output the asmwriter, returning true on failure.
- void run(raw_ostream &o);
- };
-}
-
-#endif //LLVM_UTILS_TABLEGEN_LLVMCCONF_EMITTER_H
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index 4b0f91a873..f060711200 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -30,7 +30,6 @@
#include "FastISelEmitter.h"
#include "InstrInfoEmitter.h"
#include "IntrinsicEmitter.h"
-#include "LLVMCConfigurationEmitter.h"
#include "NeonEmitter.h"
#include "OptParserEmitter.h"
#include "PseudoLoweringEmitter.h"
@@ -81,7 +80,6 @@ enum ActionType {
GenSubtarget,
GenIntrinsic,
GenTgtIntrinsic,
- GenLLVMCConf,
GenEDInfo,
GenArmNeon,
GenArmNeonSema,
@@ -156,8 +154,6 @@ namespace {
"Generate Clang AST statement nodes"),
clEnumValN(GenClangSACheckers, "gen-clang-sa-checkers",
"Generate Clang Static Analyzer checkers"),
- clEnumValN(GenLLVMCConf, "gen-llvmc",
- "Generate LLVMC configuration library"),
clEnumValN(GenEDInfo, "gen-enhanced-disassembly-info",
"Generate enhanced disassembly info"),
clEnumValN(GenArmNeon, "gen-arm-neon",
@@ -349,9 +345,6 @@ int main(int argc, char **argv) {
case GenTgtIntrinsic:
IntrinsicEmitter(Records, true).run(Out.os());
break;
- case GenLLVMCConf:
- LLVMCConfigurationEmitter(Records).run(Out.os());
- break;
case GenEDInfo:
EDEmitter(Records).run(Out.os());
break;