summaryrefslogtreecommitdiff
path: root/utils/TableGen/LLVMCConfigurationEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/LLVMCConfigurationEmitter.cpp')
-rw-r--r--utils/TableGen/LLVMCConfigurationEmitter.cpp646
1 files changed, 341 insertions, 305 deletions
diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp
index da2d54f5439b9..8b81e14cc26a2 100644
--- a/utils/TableGen/LLVMCConfigurationEmitter.cpp
+++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp
@@ -33,6 +33,7 @@ namespace {
/// Typedefs
typedef std::vector<Record*> RecordVector;
+typedef std::vector<const DagInit*> DagVector;
typedef std::vector<std::string> StrVector;
//===----------------------------------------------------------------------===//
@@ -49,7 +50,7 @@ const unsigned Indent4 = TabWidth*4;
const char * const DefaultHelpString = "NO HELP MESSAGE PROVIDED";
// Name for the "sink" option.
-const char * const SinkOptionName = "AutoGeneratedSinkOption";
+const char * const SinkOptionName = "SinkOption";
//===----------------------------------------------------------------------===//
/// Helper functions
@@ -109,11 +110,6 @@ void CheckNumberOfArguments (const DagInit& d, unsigned minArgs) {
throw GetOperatorName(d) + ": too few arguments!";
}
-// IsDagEmpty - is this DAG marked with an empty marker?
-bool IsDagEmpty (const DagInit& d) {
- return GetOperatorName(d) == "empty_dag_marker";
-}
-
// 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).
@@ -188,21 +184,25 @@ void apply(F Fun, T0& Arg0, T1& Arg1) {
/// documentation for detailed description of differences.
namespace OptionType {
- enum OptionType { Alias, Switch, Parameter, ParameterList,
- Prefix, PrefixList};
+ enum OptionType { Alias, Switch, SwitchList,
+ Parameter, ParameterList, Prefix, PrefixList };
bool IsAlias(OptionType t) {
return (t == Alias);
}
bool IsList (OptionType t) {
- return (t == ParameterList || t == PrefixList);
+ 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);
}
@@ -214,6 +214,8 @@ OptionType::OptionType stringToOptionType(const std::string& T) {
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")
@@ -228,10 +230,9 @@ OptionType::OptionType stringToOptionType(const std::string& T) {
namespace OptionDescriptionFlags {
enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2,
- ReallyHidden = 0x4, Extern = 0x8,
- OneOrMore = 0x10, Optional = 0x20,
- CommaSeparated = 0x40, ForwardNotSplit = 0x80,
- ZeroOrMore = 0x100 };
+ ReallyHidden = 0x4, OneOrMore = 0x8,
+ Optional = 0x10, CommaSeparated = 0x20,
+ ForwardNotSplit = 0x40, ZeroOrMore = 0x80 };
}
/// OptionDescription - Represents data contained in a single
@@ -256,7 +257,13 @@ struct OptionDescription {
/// GenVariableName - Returns the variable name used in the
/// generated C++ code.
- std::string GenVariableName() const;
+ 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);
@@ -273,9 +280,6 @@ struct OptionDescription {
bool isCommaSeparated() const;
void setCommaSeparated();
- bool isExtern() const;
- void setExtern();
-
bool isForwardNotSplit() const;
void setForwardNotSplit();
@@ -300,12 +304,23 @@ struct OptionDescription {
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 {
@@ -359,13 +374,6 @@ void OptionDescription::setForwardNotSplit() {
Flags |= OptionDescriptionFlags::ForwardNotSplit;
}
-bool OptionDescription::isExtern() const {
- return Flags & OptionDescriptionFlags::Extern;
-}
-void OptionDescription::setExtern() {
- Flags |= OptionDescriptionFlags::Extern;
-}
-
bool OptionDescription::isRequired() const {
return Flags & OptionDescriptionFlags::Required;
}
@@ -417,6 +425,8 @@ const char* OptionDescription::GenTypeDeclaration() const {
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:
@@ -424,20 +434,21 @@ const char* OptionDescription::GenTypeDeclaration() const {
}
}
-std::string OptionDescription::GenVariableName() const {
- const std::string& EscapedName = EscapeVariableName(Name);
+std::string OptionDescription::GenOptionType() const {
switch (Type) {
case OptionType::Alias:
- return "AutoGeneratedAlias_" + EscapedName;
+ return "Alias_";
case OptionType::PrefixList:
case OptionType::ParameterList:
- return "AutoGeneratedList_" + EscapedName;
+ return "List_";
case OptionType::Switch:
- return "AutoGeneratedSwitch_" + EscapedName;
+ return "Switch_";
+ case OptionType::SwitchList:
+ return "SwitchList_";
case OptionType::Prefix:
case OptionType::Parameter:
default:
- return "AutoGeneratedParameter_" + EscapedName;
+ return "Parameter_";
}
}
@@ -457,9 +468,11 @@ public:
// wrong type.
const OptionDescription& FindSwitch(const std::string& OptName) const;
const OptionDescription& FindParameter(const std::string& OptName) const;
- const OptionDescription& FindList(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
@@ -489,10 +502,10 @@ OptionDescriptions::FindSwitch(const std::string& OptName) const {
}
const OptionDescription&
-OptionDescriptions::FindList(const std::string& OptName) const {
+OptionDescriptions::FindParameterList(const std::string& OptName) const {
const OptionDescription& OptDesc = this->FindOption(OptName);
- if (!OptDesc.isList())
- throw OptName + ": incorrect option type - should be a list!";
+ if (!OptDesc.isList() || OptDesc.isSwitchList())
+ throw OptName + ": incorrect option type - should be a parameter list!";
return OptDesc;
}
@@ -513,6 +526,16 @@ OptionDescriptions::FindListOrParameter(const std::string& OptName) const {
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()) {
@@ -586,7 +609,6 @@ void InvokeDagInitHandler(const FunctionObject* const Obj,
((Obj)->*(h))(Dag, IndentLevel, O);
}
-
template <typename H>
typename HandlerTable<H>::HandlerMap HandlerTable<H>::Handlers_;
@@ -615,7 +637,6 @@ public:
: optDesc_(OD)
{
if (!staticMembersInitialized_) {
- AddHandler("extern", &CollectOptionProperties::onExtern);
AddHandler("help", &CollectOptionProperties::onHelp);
AddHandler("hidden", &CollectOptionProperties::onHidden);
AddHandler("init", &CollectOptionProperties::onInit);
@@ -644,11 +665,6 @@ private:
/// Option property handlers --
/// Methods that handle option properties such as (help) or (hidden).
- void onExtern (const DagInit& d) {
- CheckNumberOfArguments(d, 0);
- optDesc_.setExtern();
- }
-
void onHelp (const DagInit& d) {
CheckNumberOfArguments(d, 1);
optDesc_.Help = EscapeQuotes(InitPtrToString(d.getArg(0)));
@@ -666,8 +682,8 @@ private:
void onCommaSeparated (const DagInit& d) {
CheckNumberOfArguments(d, 0);
- if (!optDesc_.isList())
- throw "'comma_separated' is valid only on list options!";
+ if (!optDesc_.isParameterList())
+ throw "'comma_separated' is valid only on parameter list options!";
optDesc_.setCommaSeparated();
}
@@ -709,7 +725,7 @@ private:
void onZeroOrMore (const DagInit& d) {
CheckNumberOfArguments(d, 0);
- if (OptionType::IsList(optDesc_.Type))
+ if (optDesc_.isList())
llvm::errs() << "Warning: specifying the 'zero_or_more' property "
"on a list option has no effect.\n";
@@ -720,7 +736,7 @@ private:
void onOptional (const DagInit& d) {
CheckNumberOfArguments(d, 0);
- if (!OptionType::IsList(optDesc_.Type))
+ if (!optDesc_.isList())
llvm::errs() << "Warning: specifying the 'optional' property"
"on a non-list option has no effect.\n";
@@ -734,7 +750,7 @@ private:
if (val < 2)
throw "Error in the 'multi_val' property: "
"the value must be greater than 1!";
- if (!OptionType::IsList(optDesc_.Type))
+ if (!optDesc_.isParameterList())
throw "The multi_val property is valid only on list options!";
optDesc_.MultiVal = val;
}
@@ -761,16 +777,16 @@ public:
OptionDescription OD(Type, Name);
- if (!OD.isExtern())
- CheckNumberOfArguments(d, 2);
+ CheckNumberOfArguments(d, 2);
if (OD.isAlias()) {
// Aliases store the aliased option name in the 'Help' field.
OD.Help = InitPtrToString(d.getArg(1));
}
- else if (!OD.isExtern()) {
+ else {
processOptionProperties(d, OD);
}
+
OptDescs_.InsertDescription(OD);
}
@@ -789,15 +805,14 @@ private:
/// CollectOptionDescriptions - Collects option properties from all
/// OptionLists.
-void CollectOptionDescriptions (RecordVector::const_iterator B,
- RecordVector::const_iterator E,
+void CollectOptionDescriptions (const RecordVector& V,
OptionDescriptions& OptDescs)
{
// For every OptionList:
- for (; B!=E; ++B) {
- RecordVector::value_type T = *B;
+ for (RecordVector::const_iterator B = V.begin(),
+ E = V.end(); B!=E; ++B) {
// Throws an exception if the value does not exist.
- ListInit* PropList = T->getValueAsListInit("options");
+ ListInit* PropList = (*B)->getValueAsListInit("options");
// For every option description in this list:
// collect the information and
@@ -831,11 +846,7 @@ struct ToolDescription : public RefCountedBase<ToolDescription> {
// Default ctor here is needed because StringMap can only store
// DefaultConstructible objects
- ToolDescription ()
- : CmdLine(0), Actions(0), OutFileOption("-o"),
- Flags(0), OnEmpty(0)
- {}
- ToolDescription (const std::string& n)
+ ToolDescription (const std::string &n = "")
: Name(n), CmdLine(0), Actions(0), OutFileOption("-o"),
Flags(0), OnEmpty(0)
{}
@@ -974,12 +985,12 @@ private:
/// CollectToolDescriptions - Gather information about tool properties
/// from the parsed TableGen data (basically a wrapper for the
/// CollectToolProperties function object).
-void CollectToolDescriptions (RecordVector::const_iterator B,
- RecordVector::const_iterator E,
+void CollectToolDescriptions (const RecordVector& Tools,
ToolDescriptions& ToolDescs)
{
// Iterate over a properties list of every Tool definition
- for (;B!=E;++B) {
+ 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");
@@ -995,30 +1006,17 @@ void CollectToolDescriptions (RecordVector::const_iterator B,
/// FillInEdgeVector - Merge all compilation graph definitions into
/// one single edge list.
-void FillInEdgeVector(RecordVector::const_iterator B,
- RecordVector::const_iterator E, RecordVector& Out) {
- for (; B != E; ++B) {
- const ListInit* edges = (*B)->getValueAsListInit("edges");
-
- for (unsigned i = 0; i < edges->size(); ++i)
- Out.push_back(edges->getElementAsRecord(i));
- }
-}
-
-/// CalculatePriority - Calculate the priority of this plugin.
-int CalculatePriority(RecordVector::const_iterator B,
- RecordVector::const_iterator E) {
- int priority = 0;
+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");
- if (B != E) {
- priority = static_cast<int>((*B)->getValueAsInt("priority"));
-
- if (++B != E)
- throw "More than one 'PluginPriority' instance found: "
- "most probably an error!";
+ for (ListInit::const_iterator B = Edges->begin(),
+ E = Edges->end(); B != E; ++B) {
+ Out.push_back(&InitPtrToDag(*B));
+ }
}
-
- return priority;
}
/// NotInGraph - Helper function object for FilterNotInGraph.
@@ -1038,18 +1036,18 @@ public:
/// FilterNotInGraph - Filter out from ToolDescs all Tools not
/// mentioned in the compilation graph definition.
-void FilterNotInGraph (const RecordVector& EdgeVector,
+void FilterNotInGraph (const DagVector& EdgeVector,
ToolDescriptions& ToolDescs) {
// List all tools mentioned in the graph.
llvm::StringSet<> ToolsInGraph;
- for (RecordVector::const_iterator B = EdgeVector.begin(),
+ for (DagVector::const_iterator B = EdgeVector.begin(),
E = EdgeVector.end(); B != E; ++B) {
- const Record* Edge = *B;
- const std::string& NodeA = Edge->getValueAsString("a");
- const std::string& NodeB = Edge->getValueAsString("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);
@@ -1079,10 +1077,8 @@ void FillInToolToLang (const ToolDescriptions& ToolDescs,
}
/// TypecheckGraph - Check that names for output and input languages
-/// on all edges do match. This doesn't do much when the information
-/// about the whole graph is not available (i.e. when compiling most
-/// plugins).
-void TypecheckGraph (const RecordVector& EdgeVector,
+/// on all edges do match.
+void TypecheckGraph (const DagVector& EdgeVector,
const ToolDescriptions& ToolDescs) {
StringMap<StringSet<> > ToolToInLang;
StringMap<std::string> ToolToOutLang;
@@ -1091,11 +1087,11 @@ void TypecheckGraph (const RecordVector& EdgeVector,
StringMap<std::string>::iterator IAE = ToolToOutLang.end();
StringMap<StringSet<> >::iterator IBE = ToolToInLang.end();
- for (RecordVector::const_iterator B = EdgeVector.begin(),
+ for (DagVector::const_iterator B = EdgeVector.begin(),
E = EdgeVector.end(); B != E; ++B) {
- const Record* Edge = *B;
- const std::string& NodeA = Edge->getValueAsString("a");
- const std::string& NodeB = Edge->getValueAsString("b");
+ const DagInit* Edge = *B;
+ const std::string& NodeA = InitPtrToString(Edge->getArg(0));
+ const std::string& NodeB = InitPtrToString(Edge->getArg(1));
StringMap<std::string>::iterator IA = ToolToOutLang.find(NodeA);
StringMap<StringSet<> >::iterator IB = ToolToInLang.find(NodeB);
@@ -1234,10 +1230,15 @@ public:
}
};
+/// 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 RecordVector& Edges,
+void CheckForSuperfluousOptions (const DagVector& EdgeVector,
const ToolDescriptions& ToolDescs,
const OptionDescriptions& OptDescs) {
llvm::StringSet<> nonSuperfluousOptions;
@@ -1255,13 +1256,13 @@ void CheckForSuperfluousOptions (const RecordVector& Edges,
// Add all options mentioned in the 'case' clauses of the
// OptionalEdges of the compilation graph to the set of
// non-superfluous options.
- for (RecordVector::const_iterator B = Edges.begin(), E = Edges.end();
- B != E; ++B) {
- const Record* Edge = *B;
- DagInit& Weight = *Edge->getValueAsDag("weight");
-
- if (!IsDagEmpty(Weight))
+ 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
@@ -1440,7 +1441,7 @@ bool EmitCaseTest2Args(const std::string& TestName,
return true;
}
else if (TestName == "element_in_list") {
- const OptionDescription& OptDesc = OptDescs.FindList(OptName);
+ const OptionDescription& OptDesc = OptDescs.FindParameterList(OptName);
const std::string& VarName = OptDesc.GenVariableName();
O << "std::find(" << VarName << ".begin(),\n";
O.indent(IndentLevel + Indent1)
@@ -1815,6 +1816,24 @@ void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName,
}
+/// 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.
@@ -1855,14 +1874,7 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
<< D.GenVariableName() << "));\n";
break;
case OptionType::PrefixList:
- 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";
+ EmitForEachListElementCycleHeader(D, IndentLevel, O);
O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
<< Name << "\" + " << "*B));\n";
O.indent(IndentLevel1) << "++B;\n";
@@ -1875,14 +1887,7 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
O.indent(IndentLevel) << "}\n";
break;
case OptionType::ParameterList:
- 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";
+ EmitForEachListElementCycleHeader(D, IndentLevel, O);
O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
<< Name << "\"));\n";
@@ -1893,6 +1898,13 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
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!";
@@ -1908,10 +1920,10 @@ struct ActionHandlingCallbackBase
unsigned IndentLevel, raw_ostream& O) const
{
O.indent(IndentLevel)
- << "throw std::runtime_error(\"" <<
- (d.getNumArgs() >= 1 ? InitPtrToString(d.getArg(0))
- : "Unknown error!")
+ << "PrintError(\""
+ << (d.getNumArgs() >= 1 ? InitPtrToString(d.getArg(0)) : "Unknown error!")
<< "\");\n";
+ O.indent(IndentLevel) << "return 1;\n";
}
void onWarningDag(const DagInit& d,
@@ -1926,7 +1938,6 @@ struct ActionHandlingCallbackBase
/// EmitActionHandlersCallback - Emit code that handles actions. Used by
/// EmitGenerateActionMethod() as an argument to EmitCaseConstructHandler().
-
class EmitActionHandlersCallback;
typedef void (EmitActionHandlersCallback::* EmitActionHandlersCallbackHandler)
@@ -1997,7 +2008,12 @@ class EmitActionHandlersCallback :
{
CheckNumberOfArguments(Dag, 1);
const std::string& Name = InitPtrToString(Dag.getArg(0));
- const OptionDescription& D = OptDescs.FindListOrParameter(Name);
+ 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("
@@ -2005,8 +2021,9 @@ class EmitActionHandlersCallback :
<< D.GenVariableName() << "));\n";
}
else {
- O.indent(IndentLevel) << "for (cl::list<std::string>::iterator B = "
- << D.GenVariableName() << ".begin(), \n";
+ 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";
@@ -2026,7 +2043,7 @@ class EmitActionHandlersCallback :
CheckNumberOfArguments(Dag, 2);
const std::string& Name = InitPtrToString(Dag.getArg(0));
const std::string& Hook = InitPtrToString(Dag.getArg(1));
- const OptionDescription& D = OptDescs.FindListOrParameter(Name);
+ const OptionDescription& D = OptDescs.FindParameterListOrParameter(Name);
O.indent(IndentLevel) << "vec.push_back(std::make_pair("
<< D.GenVariableName() << ".getPosition("
@@ -2099,25 +2116,32 @@ class EmitActionHandlersCallback :
};
void EmitGenerateActionMethodHeader(const ToolDescription& D,
- bool IsJoin, raw_ostream& O)
+ bool IsJoin, bool Naked,
+ raw_ostream& O)
{
+ O.indent(Indent1) << "int GenerateAction(Action& Out,\n";
+
if (IsJoin)
- O.indent(Indent1) << "Action GenerateAction(const PathVector& inFiles,\n";
+ O.indent(Indent2) << "const PathVector& inFiles,\n";
else
- O.indent(Indent1) << "Action GenerateAction(const sys::Path& inFile,\n";
+ O.indent(Indent2) << "const sys::Path& inFile,\n";
- O.indent(Indent2) << "bool HasChildren,\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";
- 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) << "const char* output_suffix = \""
- << D.OutputSuffix << "\";\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
@@ -2126,7 +2150,7 @@ void EmitGenerateActionMethod (const ToolDescription& D,
const OptionDescriptions& OptDescs,
bool IsJoin, raw_ostream& O) {
- EmitGenerateActionMethodHeader(D, IsJoin, O);
+ EmitGenerateActionMethodHeader(D, IsJoin, /* Naked = */ false, O);
if (!D.CmdLine)
throw "Tool " + D.Name + " has no cmd_line property!";
@@ -2173,25 +2197,29 @@ void EmitGenerateActionMethod (const ToolDescription& D,
O.indent(Indent3) << "out_file = this->OutFilename("
<< (IsJoin ? "sys::Path(),\n" : "inFile,\n");
- O.indent(Indent4) << "TempDir, stop_compilation, output_suffix).str();\n\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 (!" << SinkOptionName << ".empty()) {\n";
+ O.indent(Indent2) << "if (!" << SinkOption << ".empty()) {\n";
O.indent(Indent3) << "for (cl::list<std::string>::iterator B = "
- << SinkOptionName << ".begin(), E = " << SinkOptionName
+ << SinkOption << ".begin(), E = " << SinkOption
<< ".end(); B != E; ++B)\n";
- O.indent(Indent4) << "vec.push_back(std::make_pair(" << SinkOptionName
- << ".getPosition(B - " << SinkOptionName
+ O.indent(Indent4) << "vec.push_back(std::make_pair(" << SinkOption
+ << ".getPosition(B - " << SinkOption
<< ".begin()), *B));\n";
O.indent(Indent2) << "}\n";
}
- O.indent(Indent2) << "return Action(cmd, this->SortArgs(vec), "
+ 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";
}
@@ -2201,14 +2229,11 @@ void EmitGenerateActionMethods (const ToolDescription& ToolDesc,
const OptionDescriptions& OptDescs,
raw_ostream& O) {
if (!ToolDesc.isJoin()) {
- O.indent(Indent1) << "Action GenerateAction(const PathVector& inFiles,\n";
- O.indent(Indent2) << "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";
- O.indent(Indent2) << "throw std::runtime_error(\"" << ToolDesc.Name
+ 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 {
@@ -2321,8 +2346,7 @@ void EmitToolClassDefinition (const ToolDescription& D,
/// EmitOptionDefinitions - Iterate over a list of option descriptions
/// and emit registration code.
void EmitOptionDefinitions (const OptionDescriptions& descs,
- bool HasSink, bool HasExterns,
- raw_ostream& O)
+ bool HasSink, raw_ostream& O)
{
std::vector<OptionDescription> Aliases;
@@ -2336,16 +2360,8 @@ void EmitOptionDefinitions (const OptionDescriptions& descs,
continue;
}
- if (val.isExtern())
- O << "extern ";
-
O << val.GenTypeDeclaration() << ' '
- << val.GenVariableName();
-
- if (val.isExtern()) {
- O << ";\n";
- continue;
- }
+ << val.GenPlainVariableName();
O << "(\"" << val.Name << "\"\n";
@@ -2396,7 +2412,7 @@ void EmitOptionDefinitions (const OptionDescriptions& descs,
const OptionDescription& val = *B;
O << val.GenTypeDeclaration() << ' '
- << val.GenVariableName()
+ << val.GenPlainVariableName()
<< "(\"" << val.Name << '\"';
const OptionDescription& D = descs.FindOption(val.Help);
@@ -2407,9 +2423,7 @@ void EmitOptionDefinitions (const OptionDescriptions& descs,
// Emit the sink option.
if (HasSink)
- O << (HasExterns ? "extern cl" : "cl")
- << "::list<std::string> " << SinkOptionName
- << (HasExterns ? ";\n" : "(cl::Sink);\n");
+ O << "cl::list<std::string> " << SinkOptionName << "(cl::Sink);\n";
O << '\n';
}
@@ -2492,8 +2506,15 @@ class EmitPreprocessOptionsCallback :
O.indent(IndentLevel) << OptDesc.GenVariableName() << ".clear();\n";
for (ListInit::const_iterator B = List.begin(), E = List.end();
B != E; ++B) {
- O.indent(IndentLevel) << OptDesc.GenVariableName() << ".push_back(\""
- << InitPtrToString(*B) << "\");\n";
+ 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()) {
@@ -2561,11 +2582,11 @@ public:
};
-/// EmitPreprocessOptions - Emit the PreprocessOptionsLocal() function.
+/// EmitPreprocessOptions - Emit the PreprocessOptions() function.
void EmitPreprocessOptions (const RecordKeeper& Records,
const OptionDescriptions& OptDecs, raw_ostream& O)
{
- O << "void PreprocessOptionsLocal() {\n";
+ O << "int PreprocessOptions () {\n";
const RecordVector& OptionPreprocessors =
Records.getAllDerivedDefinitions("OptionPreprocessor");
@@ -2578,58 +2599,101 @@ void EmitPreprocessOptions (const RecordKeeper& Records,
false, OptDecs, O);
}
+ O << '\n';
+ O.indent(Indent1) << "return 0;\n";
O << "}\n\n";
}
-/// EmitPopulateLanguageMap - Emit the PopulateLanguageMapLocal() function.
-void EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O)
+class DoEmitPopulateLanguageMap;
+typedef void (DoEmitPopulateLanguageMap::* DoEmitPopulateLanguageMapHandler)
+(const DagInit& D);
+
+class DoEmitPopulateLanguageMap
+: public HandlerTable<DoEmitPopulateLanguageMapHandler>
{
- O << "void PopulateLanguageMapLocal(LanguageMap& langMap) {\n";
+private:
+ raw_ostream& O_;
- // Get the relevant field out of RecordKeeper
- const Record* LangMapRecord = Records.getDef("LanguageMap");
+public:
+
+ explicit DoEmitPopulateLanguageMap (raw_ostream& O) : O_(O) {
+ if (!staticMembersInitialized_) {
+ AddHandler("lang_to_suffixes",
+ &DoEmitPopulateLanguageMap::onLangToSuffixes);
+
+ staticMembersInitialized_ = true;
+ }
+ }
- // It is allowed for a plugin to have no language map.
- if (LangMapRecord) {
+ void operator() (Init* I) {
+ InvokeDagInitHandler(this, I);
+ }
- ListInit* LangsToSuffixesList = LangMapRecord->getValueAsListInit("map");
- if (!LangsToSuffixesList)
- throw "Error in the language map definition!";
+private:
- for (unsigned i = 0; i < LangsToSuffixesList->size(); ++i) {
- const Record* LangToSuffixes = LangsToSuffixesList->getElementAsRecord(i);
+ void onLangToSuffixes (const DagInit& d) {
+ CheckNumberOfArguments(d, 2);
- const std::string& Lang = LangToSuffixes->getValueAsString("lang");
- const ListInit* Suffixes = LangToSuffixes->getValueAsListInit("suffixes");
+ const std::string& Lang = InitPtrToString(d.getArg(0));
+ Init* Suffixes = d.getArg(1);
- for (unsigned i = 0; i < Suffixes->size(); ++i)
- O.indent(Indent1) << "langMap[\""
- << InitPtrToString(Suffixes->getElement(i))
- << "\"] = \"" << Lang << "\";\n";
+ // 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 LangMap:
+ const RecordVector& LangMaps =
+ Records.getAllDerivedDefinitions("LanguageMap");
+
+ 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";
}
-/// IncDecWeight - Helper function passed to EmitCaseConstructHandler()
-/// by EmitEdgeClass().
-void IncDecWeight (const Init* i, unsigned IndentLevel,
- raw_ostream& O) {
+/// 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 == "dec_weight") {
- O.indent(IndentLevel) << "ret -= ";
- }
else if (OpName == "error") {
CheckNumberOfArguments(d, 1);
- O.indent(IndentLevel) << "throw std::runtime_error(\""
+ O.indent(IndentLevel) << "PrintError(\""
<< InitPtrToString(d.getArg(0))
<< "\");\n";
+ O.indent(IndentLevel) << "return -1;\n";
return;
}
else {
@@ -2646,7 +2710,7 @@ void IncDecWeight (const Init* i, unsigned IndentLevel,
/// EmitEdgeClass - Emit a single Edge# class.
void EmitEdgeClass (unsigned N, const std::string& Target,
- DagInit* Case, const OptionDescriptions& OptDescs,
+ const DagInit& Case, const OptionDescriptions& OptDescs,
raw_ostream& O) {
// Class constructor.
@@ -2657,40 +2721,48 @@ void EmitEdgeClass (unsigned N, const std::string& Target,
// Function Weight().
O.indent(Indent1)
- << "unsigned Weight(const InputLanguagesSet& InLangs) const {\n";
+ << "int Weight(const InputLanguagesSet& InLangs) const {\n";
O.indent(Indent2) << "unsigned ret = 0;\n";
// Handle the 'case' construct.
- EmitCaseConstructHandler(Case, Indent2, IncDecWeight, false, OptDescs, O);
+ 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 RecordVector& EdgeVector,
+void EmitEdgeClasses (const DagVector& EdgeVector,
const OptionDescriptions& OptDescs,
raw_ostream& O) {
int i = 0;
- for (RecordVector::const_iterator B = EdgeVector.begin(),
+ for (DagVector::const_iterator B = EdgeVector.begin(),
E = EdgeVector.end(); B != E; ++B) {
- const Record* Edge = *B;
- const std::string& NodeB = Edge->getValueAsString("b");
- DagInit& Weight = *Edge->getValueAsDag("weight");
+ 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 + "'!";
+ }
- if (!IsDagEmpty(Weight))
- EmitEdgeClass(i, NodeB, &Weight, OptDescs, O);
++i;
}
}
-/// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraphLocal()
-/// function.
-void EmitPopulateCompilationGraph (const RecordVector& EdgeVector,
+/// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraph() function.
+void EmitPopulateCompilationGraph (const DagVector& EdgeVector,
const ToolDescriptions& ToolDescs,
raw_ostream& O)
{
- O << "void PopulateCompilationGraphLocal(CompilationGraph& G) {\n";
+ O << "int PopulateCompilationGraph (CompilationGraph& G) {\n";
for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
E = ToolDescs.end(); B != E; ++B)
@@ -2701,24 +2773,27 @@ void EmitPopulateCompilationGraph (const RecordVector& EdgeVector,
// Insert edges.
int i = 0;
- for (RecordVector::const_iterator B = EdgeVector.begin(),
+ for (DagVector::const_iterator B = EdgeVector.begin(),
E = EdgeVector.end(); B != E; ++B) {
- const Record* Edge = *B;
- const std::string& NodeA = Edge->getValueAsString("a");
- const std::string& NodeB = Edge->getValueAsString("b");
- DagInit& Weight = *Edge->getValueAsDag("weight");
+ const DagInit& Edge = **B;
+ const std::string& NodeA = InitPtrToString(Edge.getArg(0));
+ const std::string& NodeB = InitPtrToString(Edge.getArg(1));
- O.indent(Indent1) << "G.insertEdge(\"" << NodeA << "\", ";
+ O.indent(Indent1) << "if (int ret = G.insertEdge(\"" << NodeA << "\", ";
- if (IsDagEmpty(Weight))
- O << "new SimpleEdge(\"" << NodeB << "\")";
- else
+ if (IsOptionalEdge(Edge))
O << "new Edge" << i << "()";
+ else
+ O << "new SimpleEdge(\"" << NodeB << "\")";
+
+ O << "))\n";
+ O.indent(Indent2) << "return ret;\n";
- O << ");\n";
++i;
}
+ O << '\n';
+ O.indent(Indent1) << "return 0;\n";
O << "}\n\n";
}
@@ -2762,7 +2837,8 @@ public:
CheckNumberOfArguments(Dag, 2);
const std::string& OptName = InitPtrToString(Dag.getArg(0));
const std::string& HookName = InitPtrToString(Dag.getArg(1));
- const OptionDescription& D = OptDescs_.FindOption(OptName);
+ const OptionDescription& D =
+ OptDescs_.FindParameterListOrParameter(OptName);
HookNames_[HookName] = HookInfo(D.isList() ? HookInfo::ListHook
: HookInfo::ArgHook);
@@ -2827,9 +2903,6 @@ public:
this->onCmdLine(InitPtrToString(Arg));
}
- void operator()(const DagInit* Test, unsigned, bool) {
- this->operator()(Test);
- }
void operator()(const Init* Statement, unsigned) {
this->operator()(Statement);
}
@@ -2873,7 +2946,6 @@ void EmitHookDeclarations(const ToolDescriptions& ToolDescs,
if (HookNames.empty())
return;
- O << "namespace hooks {\n";
for (HookInfoMap::const_iterator B = HookNames.begin(),
E = HookNames.end(); B != E; ++B) {
const char* HookName = B->first();
@@ -2892,23 +2964,6 @@ void EmitHookDeclarations(const ToolDescriptions& ToolDescs,
O <<");\n";
}
- O << "}\n\n";
-}
-
-/// EmitRegisterPlugin - Emit code to register this plugin.
-void EmitRegisterPlugin(int Priority, raw_ostream& O) {
- O << "struct Plugin : public llvmc::BasePlugin {\n\n";
- O.indent(Indent1) << "int Priority() const { return "
- << Priority << "; }\n\n";
- O.indent(Indent1) << "void PreprocessOptions() const\n";
- O.indent(Indent1) << "{ PreprocessOptionsLocal(); }\n\n";
- O.indent(Indent1) << "void PopulateLanguageMap(LanguageMap& langMap) const\n";
- O.indent(Indent1) << "{ PopulateLanguageMapLocal(langMap); }\n\n";
- O.indent(Indent1)
- << "void PopulateCompilationGraph(CompilationGraph& graph) const\n";
- O.indent(Indent1) << "{ PopulateCompilationGraphLocal(graph); }\n"
- << "};\n\n"
- << "static llvmc::RegisterPlugin<Plugin> RP;\n\n";
}
/// EmitIncludes - Emit necessary #include directives and some
@@ -2916,8 +2971,7 @@ void EmitRegisterPlugin(int Priority, raw_ostream& O) {
void EmitIncludes(raw_ostream& O) {
O << "#include \"llvm/CompilerDriver/BuiltinOptions.h\"\n"
<< "#include \"llvm/CompilerDriver/CompilationGraph.h\"\n"
- << "#include \"llvm/CompilerDriver/ForceLinkageMacros.h\"\n"
- << "#include \"llvm/CompilerDriver/Plugin.h\"\n"
+ << "#include \"llvm/CompilerDriver/Error.h\"\n"
<< "#include \"llvm/CompilerDriver/Tool.h\"\n\n"
<< "#include \"llvm/Support/CommandLine.h\"\n"
@@ -2931,21 +2985,17 @@ void EmitIncludes(raw_ostream& O) {
<< "using namespace llvm;\n"
<< "using namespace llvmc;\n\n"
- << "extern cl::opt<std::string> OutputFilename;\n\n"
-
<< "inline const char* checkCString(const char* s)\n"
<< "{ return s == NULL ? \"\" : s; }\n\n";
}
-/// PluginData - Holds all information about a plugin.
-struct PluginData {
+/// DriverData - Holds all information about the driver.
+struct DriverData {
OptionDescriptions OptDescs;
- bool HasSink;
- bool HasExterns;
ToolDescriptions ToolDescs;
- RecordVector Edges;
- int Priority;
+ DagVector Edges;
+ bool HasSink;
};
/// HasSink - Go through the list of tool descriptions and check if
@@ -2959,46 +3009,27 @@ bool HasSink(const ToolDescriptions& ToolDescs) {
return false;
}
-/// HasExterns - Go through the list of option descriptions and check
-/// if there are any external options.
-bool HasExterns(const OptionDescriptions& OptDescs) {
- for (OptionDescriptions::const_iterator B = OptDescs.begin(),
- E = OptDescs.end(); B != E; ++B)
- if (B->second.isExtern())
- return true;
-
- return false;
-}
-
-/// CollectPluginData - Collect tool and option properties,
-/// compilation graph edges and plugin priority from the parse tree.
-void CollectPluginData (const RecordKeeper& Records, PluginData& Data) {
+/// 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.begin(), OptionLists.end(),
- Data.OptDescs);
+ CollectOptionDescriptions(OptionLists, Data.OptDescs);
// Collect tool properties.
const RecordVector& Tools = Records.getAllDerivedDefinitions("Tool");
- CollectToolDescriptions(Tools.begin(), Tools.end(), Data.ToolDescs);
+ CollectToolDescriptions(Tools, Data.ToolDescs);
Data.HasSink = HasSink(Data.ToolDescs);
- Data.HasExterns = HasExterns(Data.OptDescs);
// Collect compilation graph edges.
const RecordVector& CompilationGraphs =
Records.getAllDerivedDefinitions("CompilationGraph");
- FillInEdgeVector(CompilationGraphs.begin(), CompilationGraphs.end(),
- Data.Edges);
-
- // Calculate the priority of this plugin.
- const RecordVector& Priorities =
- Records.getAllDerivedDefinitions("PluginPriority");
- Data.Priority = CalculatePriority(Priorities.begin(), Priorities.end());
+ FillInEdgeVector(CompilationGraphs, Data.Edges);
}
-/// CheckPluginData - Perform some sanity checks on the collected data.
-void CheckPluginData(PluginData& Data) {
+/// 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);
@@ -3010,24 +3041,24 @@ void CheckPluginData(PluginData& Data) {
CheckForSuperfluousOptions(Data.Edges, Data.ToolDescs, Data.OptDescs);
}
-void EmitPluginCode(const PluginData& Data, raw_ostream& O) {
+void EmitDriverCode(const DriverData& Data, raw_ostream& O) {
// Emit file header.
EmitIncludes(O);
// Emit global option registration code.
- EmitOptionDefinitions(Data.OptDescs, Data.HasSink, Data.HasExterns, O);
+ 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";
-
- // Emit PreprocessOptionsLocal() function.
- EmitPreprocessOptions(Records, Data.OptDescs, O);
-
- // Emit PopulateLanguageMapLocal() function
- // (language map maps from file extensions to language names).
- EmitPopulateLanguageMap(Records, O);
+ O << "using namespace llvmc::autogenerated;\n\n";
// Emit Tool classes.
for (ToolDescriptions::const_iterator B = Data.ToolDescs.begin(),
@@ -3037,18 +3068,23 @@ void EmitPluginCode(const PluginData& Data, raw_ostream& O) {
// Emit Edge# classes.
EmitEdgeClasses(Data.Edges, Data.OptDescs, O);
- // Emit PopulateCompilationGraphLocal() function.
- EmitPopulateCompilationGraph(Data.Edges, Data.ToolDescs, O);
-
- // Emit code for plugin registration.
- EmitRegisterPlugin(Data.Priority, O);
-
O << "} // End anonymous namespace.\n\n";
- // Force linkage magic.
O << "namespace llvmc {\n";
- O << "LLVMC_FORCE_LINKAGE_DECL(LLVMC_PLUGIN_NAME) {}\n";
- O << "}\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
}
@@ -3060,13 +3096,13 @@ void EmitPluginCode(const PluginData& Data, raw_ostream& O) {
/// run - The back-end entry point.
void LLVMCConfigurationEmitter::run (raw_ostream &O) {
try {
- PluginData Data;
+ DriverData Data;
- CollectPluginData(Records, Data);
- CheckPluginData(Data);
+ CollectDriverData(Records, Data);
+ CheckDriverData(Data);
- this->EmitSourceFileHeader("LLVMC Configuration Library", O);
- EmitPluginCode(Data, O);
+ this->EmitSourceFileHeader("llvmc-based driver: auto-generated code", O);
+ EmitDriverCode(Data, O);
} catch (std::exception& Error) {
throw Error.what() + std::string(" - usually this means a syntax error.");