//===----------------------------------------------------------------------===//
/// Constants
-// Indentation strings
+// Indentation strings.
const char * Indent1 = " ";
const char * Indent2 = " ";
const char * Indent3 = " ";
const char * Indent4 = " ";
-// Default help string
+// Default help string.
const char * DefaultHelpString = "NO HELP MESSAGE PROVIDED";
-// Name for the "sink" option
+// Name for the "sink" option.
const char * SinkOptionName = "AutoGeneratedSinkOption";
//===----------------------------------------------------------------------===//
return val.getValue();
}
-// Ensure that the number of args in d is <= min_arguments,
-// throw exception otherwise
+int InitPtrToInt(Init* ptr) {
+ IntInit& val = dynamic_cast<IntInit&>(*ptr);
+ return val.getValue();
+}
+
+const DagInit& InitPtrToDagInitRef(Init* ptr) {
+ DagInit& val = dynamic_cast<DagInit&>(*ptr);
+ return val;
+}
+
+
+// checkNumberOfArguments - Ensure that the number of args in d is
+// less than or equal to min_arguments, otherwise throw an exception .
void checkNumberOfArguments (const DagInit* d, unsigned min_arguments) {
if (d->getNumArgs() < min_arguments)
throw "Property " + d->getOperator()->getAsString()
// the option registration code, while ToolOptionDescriptions are used
// to generate tool-specific code.
-// Base class for option descriptions
-
+/// OptionDescription - Base class for option descriptions.
struct OptionDescription {
OptionType::OptionType Type;
std::string Name;
};
-// Global option description
+// Global option description.
namespace GlobalOptionDescriptionFlags {
enum GlobalOptionDescriptionFlags { Required = 0x1 };
std::string Help;
unsigned Flags;
- // We need t provide a default constructor since
- // StringMap can only store DefaultConstructible objects
+ // We need to provide a default constructor because
+ // StringMap can only store DefaultConstructible objects.
GlobalOptionDescription() : OptionDescription(), Flags(0)
{}
Flags |= GlobalOptionDescriptionFlags::Required;
}
- // Merge two option descriptions
+ /// Merge - Merge two option descriptions.
void Merge (const GlobalOptionDescription& other)
{
if (other.Type != Type)
throw "Conflicting definitions for the option " + Name + "!";
- if (Help.empty() && !other.Help.empty())
+ if (Help == DefaultHelpString)
Help = other.Help;
- else if (!Help.empty() && !other.Help.empty())
- cerr << "Warning: more than one help string defined for option "
+ else if (other.Help != DefaultHelpString) {
+ llvm::cerr << "Warning: more than one help string defined for option "
+ Name + "\n";
+ }
Flags |= other.Flags;
}
};
-// A GlobalOptionDescription array
-// + some flags affecting generation of option declarations
+/// GlobalOptionDescriptions - A GlobalOptionDescription array
+/// together with some flags affecting generation of option
+/// declarations.
struct GlobalOptionDescriptions {
typedef StringMap<GlobalOptionDescription> container_type;
typedef container_type::const_iterator const_iterator;
- // A list of GlobalOptionDescriptions
+ /// Descriptions - A list of GlobalOptionDescriptions.
container_type Descriptions;
- // Should the emitter generate a "cl::sink" option?
+ /// HasSink - Should the emitter generate a "cl::sink" option?
bool HasSink;
const GlobalOptionDescription& FindOption(const std::string& OptName) const {
};
-// Tool-local option description
+// Tool-local option description.
-// Properties without arguments are implemented as flags
+// Properties without arguments are implemented as flags.
namespace ToolOptionDescriptionFlags {
enum ToolOptionDescriptionFlags { StopCompilation = 0x1,
Forward = 0x2, UnpackValues = 0x4};
// Default ctor here is needed because StringMap can only store
// DefaultConstructible objects
- ToolProperties() {}
- ToolProperties (const std::string& n) : Name(n) {}
+ ToolProperties() : Flags(0) {}
+ ToolProperties (const std::string& n) : Name(n), Flags(0) {}
};
-// A list of Tool information records
-// IntrusiveRefCntPtrs are used because StringMap has no copy constructor
-// (and we want to avoid copying ToolProperties anyway)
+/// ToolPropertiesList - A list of Tool information records
+/// IntrusiveRefCntPtrs are used here because StringMap has no copy
+/// constructor (and we want to avoid copying ToolProperties anyway).
typedef std::vector<IntrusiveRefCntPtr<ToolProperties> > ToolPropertiesList;
-// Function object for iterating over a list of tool property records
+/// CollectProperties - Function object for iterating over a list of
+/// tool property records.
class CollectProperties {
private:
/// Implementation details
- // "Property handler" - a function that extracts information
- // about a given tool property from its DAG representation
- typedef void (CollectProperties::*PropertyHandler)(DagInit*);
+ /// PropertyHandler - a function that extracts information
+ /// about a given tool property from its DAG representation
+ typedef void (CollectProperties::*PropertyHandler)(const DagInit*);
- // Map from property names -> property handlers
+ /// PropertyHandlerMap - A map from property names to property
+ /// handlers.
typedef StringMap<PropertyHandler> PropertyHandlerMap;
- // "Option property handler" - a function that extracts information
- // about a given option property from its DAG representation
- typedef void (CollectProperties::*
- OptionPropertyHandler)(DagInit*, GlobalOptionDescription &);
+ /// OptionPropertyHandler - a function that extracts information
+ /// about a given option property from its DAG representation.
+ typedef void (CollectProperties::* OptionPropertyHandler)
+ (const DagInit*, GlobalOptionDescription &);
- // Map from option property names -> option property handlers
+ /// OptionPropertyHandlerMap - A map from option property names to
+ /// option property handlers
typedef StringMap<OptionPropertyHandler> OptionPropertyHandlerMap;
// Static maps from strings to CollectProperties methods("handlers")
/// This is where the information is stored
- // Current Tool properties
+ /// toolProps_ - Properties of the current Tool.
ToolProperties& toolProps_;
- // OptionDescriptions table(used to register options globally)
+ /// optDescs_ - OptionDescriptions table (used to register options
+ /// globally).
GlobalOptionDescriptions& optDescs_;
public:
}
}
- // Gets called for every tool property;
- // Just forwards to the corresponding property handler.
+ /// operator() - Gets called for every tool property; Just forwards
+ /// to the corresponding property handler.
void operator() (Init* i) {
- DagInit& d = dynamic_cast<DagInit&>(*i);
+ const DagInit& d = InitPtrToDagInitRef(i);
const std::string& property_name = d.getOperator()->getAsString();
PropertyHandlerMap::iterator method
= propertyHandlers_.find(property_name);
/// Functions that extract information about tool properties from
/// DAG representation.
- void onCmdLine (DagInit* d) {
+ void onCmdLine (const DagInit* d) {
checkNumberOfArguments(d, 1);
SplitString(InitPtrToString(d->getArg(0)), toolProps_.CmdLine);
if (toolProps_.CmdLine.empty())
throw "Tool " + toolProps_.Name + " has empty command line!";
}
- void onInLanguage (DagInit* d) {
+ void onInLanguage (const DagInit* d) {
checkNumberOfArguments(d, 1);
toolProps_.InLanguage = InitPtrToString(d->getArg(0));
}
- void onJoin (DagInit* d) {
+ void onJoin (const DagInit* d) {
checkNumberOfArguments(d, 0);
toolProps_.setJoin();
}
- void onOutLanguage (DagInit* d) {
+ void onOutLanguage (const DagInit* d) {
checkNumberOfArguments(d, 1);
toolProps_.OutLanguage = InitPtrToString(d->getArg(0));
}
- void onOutputSuffix (DagInit* d) {
+ void onOutputSuffix (const DagInit* d) {
checkNumberOfArguments(d, 1);
toolProps_.OutputSuffix = InitPtrToString(d->getArg(0));
}
- void onSink (DagInit* d) {
+ void onSink (const DagInit* d) {
checkNumberOfArguments(d, 0);
optDescs_.HasSink = true;
toolProps_.setSink();
}
- void onSwitch (DagInit* d) { addOption(d, OptionType::Switch); }
- void onParameter (DagInit* d) { addOption(d, OptionType::Parameter); }
- void onParameterList (DagInit* d) { addOption(d, OptionType::ParameterList); }
- void onPrefix (DagInit* d) { addOption(d, OptionType::Prefix); }
- void onPrefixList (DagInit* d) { addOption(d, OptionType::PrefixList); }
+ void onSwitch (const DagInit* d) {
+ addOption(d, OptionType::Switch);
+ }
+
+ void onParameter (const DagInit* d) {
+ addOption(d, OptionType::Parameter);
+ }
+
+ void onParameterList (const DagInit* d) {
+ addOption(d, OptionType::ParameterList);
+ }
+
+ void onPrefix (const DagInit* d) {
+ addOption(d, OptionType::Prefix);
+ }
+
+ void onPrefixList (const DagInit* d) {
+ addOption(d, OptionType::PrefixList);
+ }
/// Option property handlers --
/// Methods that handle properties that are common for all types of
/// options (like append_cmd, stop_compilation)
- void onAppendCmd (DagInit* d, GlobalOptionDescription& o) {
+ void onAppendCmd (const DagInit* d, GlobalOptionDescription& o) {
checkNumberOfArguments(d, 1);
std::string const& cmd = InitPtrToString(d->getArg(0));
toolProps_.OptDescs[o.Name].AddProperty(OptionPropertyType::AppendCmd, cmd);
}
- void onForward (DagInit* d, GlobalOptionDescription& o) {
+ void onForward (const DagInit* d, GlobalOptionDescription& o) {
checkNumberOfArguments(d, 0);
toolProps_.OptDescs[o.Name].setForward();
}
- void onHelp (DagInit* d, GlobalOptionDescription& o) {
+ void onHelp (const DagInit* d, GlobalOptionDescription& o) {
checkNumberOfArguments(d, 1);
const std::string& help_message = InitPtrToString(d->getArg(0));
o.Help = help_message;
}
- void onRequired (DagInit* d, GlobalOptionDescription& o) {
+ void onRequired (const DagInit* d, GlobalOptionDescription& o) {
checkNumberOfArguments(d, 0);
o.setRequired();
}
- void onStopCompilation (DagInit* d, GlobalOptionDescription& o) {
+ void onStopCompilation (const DagInit* d, GlobalOptionDescription& o) {
checkNumberOfArguments(d, 0);
if (o.Type != OptionType::Switch)
throw std::string("Only options of type Switch can stop compilation!");
toolProps_.OptDescs[o.Name].setStopCompilation();
}
- void onUnpackValues (DagInit* d, GlobalOptionDescription& o) {
+ void onUnpackValues (const DagInit* d, GlobalOptionDescription& o) {
checkNumberOfArguments(d, 0);
toolProps_.OptDescs[o.Name].setUnpackValues();
}
/// Helper functions
// Add an option of type t
- void addOption (DagInit* d, OptionType::OptionType t) {
+ void addOption (const DagInit* d, OptionType::OptionType t) {
checkNumberOfArguments(d, 2);
const std::string& name = InitPtrToString(d->getArg(0));
}
}
- // Go through the list of option properties and call a corresponding
- // handler for each.
- //
- // Parameters:
- // name - option name
- // d - option property list
- void processOptionProperties (DagInit* d, GlobalOptionDescription& o) {
+ /// processOptionProperties - Go through the list of option
+ /// properties and call a corresponding handler for each.
+ ///
+ /// Parameters:
+ /// name - option name
+ /// d - option property list
+ void processOptionProperties (const DagInit* d, GlobalOptionDescription& o) {
// First argument is option name
checkNumberOfArguments(d, 2);
for (unsigned B = 1, E = d->getNumArgs(); B!=E; ++B) {
- DagInit& option_property
- = dynamic_cast<DagInit&>(*d->getArg(B));
+ const DagInit& option_property
+ = InitPtrToDagInitRef(d->getArg(B));
const std::string& option_property_name
= option_property.getOperator()->getAsString();
OptionPropertyHandlerMap::iterator method
bool CollectProperties::staticMembersInitialized_ = false;
-// Gather information from the parsed TableGen data
-// (Basically a wrapper for CollectProperties)
+/// CollectToolProperties - Gather information from the parsed
+/// TableGen data (basically a wrapper for the CollectProperties
+/// function object).
void CollectToolProperties (RecordVector::const_iterator B,
RecordVector::const_iterator E,
ToolPropertiesList& TPList,
}
}
-// Used by EmitGenerateActionMethod
+/// EmitForwardOptionPropertyHandlingCode - Helper function used to
+/// implement EmitOptionPropertyHandlingCode(). Emits code for
+/// handling the (forward) option property.
+void EmitForwardOptionPropertyHandlingCode (const ToolOptionDescription& D,
+ std::ostream& O) {
+ switch (D.Type) {
+ case OptionType::Switch:
+ O << Indent3 << "vec.push_back(\"-" << D.Name << "\");\n";
+ break;
+ case OptionType::Parameter:
+ O << Indent3 << "vec.push_back(\"-" << D.Name << "\");\n";
+ O << Indent3 << "vec.push_back(" << D.GenVariableName() << ");\n";
+ break;
+ case OptionType::Prefix:
+ O << Indent3 << "vec.push_back(\"-" << D.Name << "\" + "
+ << D.GenVariableName() << ");\n";
+ break;
+ case OptionType::PrefixList:
+ O << Indent3 << "for (" << D.GenTypeDeclaration()
+ << "::iterator B = " << D.GenVariableName() << ".begin(),\n"
+ << Indent3 << "E = " << D.GenVariableName() << ".end(); B != E; ++B)\n"
+ << Indent4 << "vec.push_back(\"-" << D.Name << "\" + "
+ << "*B);\n";
+ break;
+ case OptionType::ParameterList:
+ O << Indent3 << "for (" << D.GenTypeDeclaration()
+ << "::iterator B = " << D.GenVariableName() << ".begin(),\n"
+ << Indent3 << "E = " << D.GenVariableName()
+ << ".end() ; B != E; ++B) {\n"
+ << Indent4 << "vec.push_back(\"-" << D.Name << "\");\n"
+ << Indent4 << "vec.push_back(*B);\n"
+ << Indent3 << "}\n";
+ break;
+ }
+}
+
+/// EmitOptionPropertyHandlingCode - Helper function used by
+/// EmitGenerateActionMethod(). Emits code that handles option
+/// properties.
void EmitOptionPropertyHandlingCode (const ToolProperties& P,
const ToolOptionDescription& D,
std::ostream& O)
{
- // if clause
+ // Start of the if-clause.
O << Indent2 << "if (";
if (D.Type == OptionType::Switch)
O << D.GenVariableName();
O <<") {\n";
- // Handle option properties that take an argument
+ // Handle option properties that take an argument.
for (OptionPropertyList::const_iterator B = D.Props.begin(),
E = D.Props.end(); B!=E; ++B) {
const OptionProperty& val = *B;
// Handle flags
// (forward) property
- if (D.isForward()) {
- switch (D.Type) {
- case OptionType::Switch:
- O << Indent3 << "vec.push_back(\"-" << D.Name << "\");\n";
- break;
- case OptionType::Parameter:
- O << Indent3 << "vec.push_back(\"-" << D.Name << "\");\n";
- O << Indent3 << "vec.push_back(" << D.GenVariableName() << ");\n";
- break;
- case OptionType::Prefix:
- O << Indent3 << "vec.push_back(\"-" << D.Name << "\" + "
- << D.GenVariableName() << ");\n";
- break;
- case OptionType::PrefixList:
- O << Indent3 << "for (" << D.GenTypeDeclaration()
- << "::iterator B = " << D.GenVariableName() << ".begin(),\n"
- << Indent3 << "E = " << D.GenVariableName() << ".end(); B != E; ++B)\n"
- << Indent4 << "vec.push_back(\"-" << D.Name << "\" + "
- << "*B);\n";
- break;
- case OptionType::ParameterList:
- O << Indent3 << "for (" << D.GenTypeDeclaration()
- << "::iterator B = " << D.GenVariableName() << ".begin(),\n"
- << Indent3 << "E = " << D.GenVariableName()
- << ".end() ; B != E; ++B) {\n"
- << Indent4 << "vec.push_back(\"-" << D.Name << "\");\n"
- << Indent4 << "vec.push_back(*B);\n"
- << Indent3 << "}\n";
- break;
- }
- }
+ if (D.isForward())
+ HandleForwardPropertyy(O);
// (unpack_values) property
if (D.isUnpackValues()) {
<< "::iterator B = " << D.GenVariableName() << ".begin(),\n"
<< Indent3 << "E = " << D.GenVariableName()
<< ".end(); B != E; ++B)\n"
- << Indent4 << "Tool::UnpackValues(*B, vec);\n";
+ << Indent4 << "llvm::SplitString(*B, vec, \",\");\n";
}
else if (D.Type == OptionType::Prefix || D.Type == OptionType::Parameter){
- O << Indent3 << "Tool::UnpackValues("
- << D.GenVariableName() << ", vec);\n";
+ O << Indent3 << "llvm::SplitString("
+ << D.GenVariableName() << ", vec, \",\");\n";
}
else {
// TOFIX: move this to the type-checking phase
}
}
- // close if clause
+ // End of the if-clause.
O << Indent2 << "}\n";
}
-// Emite one of two versions of GenerateAction method
-void EmitGenerateActionMethod (const ToolProperties& P, int V, std::ostream& O)
+// EmitGenerateActionMethod - Emit one of two versions of the
+// Tool::GenerateAction() method.
+void EmitGenerateActionMethod (const ToolProperties& P, bool V, std::ostream& O)
{
- assert(V==1 || V==2);
- if (V==1)
+ if (V)
O << Indent1 << "Action GenerateAction(const PathVector& inFiles,\n";
else
O << Indent1 << "Action GenerateAction(const sys::Path& inFile,\n";
const std::string& cmd = *I;
O << Indent2;
if (cmd == "$INFILE") {
- if (V==1)
+ if (V)
O << "for (PathVector::const_iterator B = inFiles.begin()"
<< ", E = inFiles.end();\n"
<< Indent2 << "B != E; ++B)\n"
}
}
- // For every understood option, emit handling code
+ // For every understood option, emit handling code.
for (ToolOptionDescriptions::const_iterator B = P.OptDescs.begin(),
E = P.OptDescs.end(); B != E; ++B) {
const ToolOptionDescription& val = B->second;
EmitOptionPropertyHandlingCode(P, val, O);
}
- // Handle Sink property
+ // Handle the Sink property.
if (P.isSink()) {
O << Indent2 << "if (!" << SinkOptionName << ".empty()) {\n"
<< Indent3 << "vec.insert(vec.end(), "
<< Indent1 << "}\n\n";
}
-// Emit GenerateAction methods for Tool classes
+/// EmitGenerateActionMethods - Emit two GenerateAction() methods for
+/// a given Tool class.
void EmitGenerateActionMethods (const ToolProperties& P, std::ostream& O) {
if (!P.isJoin())
EmitGenerateActionMethod(P, 2, O);
}
-// Emit IsLast() method for Tool classes
+/// EmitIsLastMethod - Emit the IsLast() method for a given Tool
+/// class.
void EmitIsLastMethod (const ToolProperties& P, std::ostream& O) {
O << Indent1 << "bool IsLast() const {\n"
<< Indent2 << "bool last = false;\n";
<< Indent1 << "}\n\n";
}
-// Emit static [Input,Output]Language() methods for Tool classes
+/// EmitInOutLanguageMethods - Emit the [Input,Output]Language()
+/// methods for a given Tool class.
void EmitInOutLanguageMethods (const ToolProperties& P, std::ostream& O) {
O << Indent1 << "const char* InputLanguage() const {\n"
<< Indent2 << "return \"" << P.InLanguage << "\";\n"
<< Indent1 << "}\n\n";
}
-// Emit static [Input,Output]Language() methods for Tool classes
+/// EmitOutputSuffixMethod - Emit the OutputSuffix() method for a
+/// given Tool class.
void EmitOutputSuffixMethod (const ToolProperties& P, std::ostream& O) {
O << Indent1 << "const char* OutputSuffix() const {\n"
<< Indent2 << "return \"" << P.OutputSuffix << "\";\n"
<< Indent1 << "}\n\n";
}
-// Emit static Name() method for Tool classes
+/// EmitNameMethod - Emit the Name() method for a given Tool class.
void EmitNameMethod (const ToolProperties& P, std::ostream& O) {
O << Indent1 << "const char* Name() const {\n"
<< Indent2 << "return \"" << P.Name << "\";\n"
<< Indent1 << "}\n\n";
}
-// Emit static Name() method for Tool classes
+/// EmitIsJoinMethod - Emit the IsJoin() method for a given Tool
+/// class.
void EmitIsJoinMethod (const ToolProperties& P, std::ostream& O) {
O << Indent1 << "bool IsJoin() const {\n";
if (P.isJoin())
O << Indent1 << "}\n\n";
}
-// Emit a Tool class definition
+/// EmitToolClassDefinition - Emit a Tool class definition.
void EmitToolClassDefinition (const ToolProperties& P, std::ostream& O) {
if(P.Name == "root")
O << "};\n\n";
}
-// Iterate over a list of option descriptions and emit registration code
+/// EmitOptionDescriptions - Iterate over a list of option
+/// descriptions and emit registration code.
void EmitOptionDescriptions (const GlobalOptionDescriptions& descs,
std::ostream& O)
{
O << '\n';
}
+/// EmitPopulateLanguageMap - Emit the PopulateLanguageMap() function.
void EmitPopulateLanguageMap (const RecordKeeper& Records, std::ostream& O)
{
// Get the relevant field out of RecordKeeper
O << "}\n\n";
}
-// Fills in two tables that map tool names to (input, output) languages.
-// Used by the typechecker.
+/// FillInToolToLang - Fills in two tables that map tool names to
+/// (input, output) languages. Used by the typechecker.
void FillInToolToLang (const ToolPropertiesList& TPList,
StringMap<std::string>& ToolToInLang,
StringMap<std::string>& ToolToOutLang) {
}
}
-// Check that all output and input language names match.
+/// TypecheckGraph - Check that names for output and input languages
+/// on all edges do match.
// TOFIX: check for cycles.
// TOFIX: check for multiple default edges.
void TypecheckGraph (Record* CompilationGraph,
}
}
-// Helper function used by EmitEdgePropertyTest.
-void EmitEdgePropertyTest1Arg(const DagInit& Prop,
+/// EmitEdgePropertyTest1Arg - Helper function used by
+/// EmitEdgePropertyTest.
+bool EmitEdgePropertyTest1Arg(const std::string& PropName,
+ const DagInit& Prop,
const GlobalOptionDescriptions& OptDescs,
std::ostream& O) {
checkNumberOfArguments(&Prop, 1);
const std::string& OptName = InitPtrToString(Prop.getArg(0));
- const GlobalOptionDescription& OptDesc = OptDescs.FindOption(OptName);
- if (OptDesc.Type != OptionType::Switch)
- throw OptName + ": incorrect option type!";
- O << OptDesc.GenVariableName();
+ if (PropName == "switch_on") {
+ const GlobalOptionDescription& OptDesc = OptDescs.FindOption(OptName);
+ if (OptDesc.Type != OptionType::Switch)
+ throw OptName + ": incorrect option type!";
+ O << OptDesc.GenVariableName();
+ return true;
+ } else if (PropName == "if_input_languages_contain") {
+ O << "InLangs.count(\"" << OptName << "\") != 0";
+ return true;
+ }
+
+ return false;
}
-// Helper function used by EmitEdgePropertyTest.
-void EmitEdgePropertyTest2Args(const std::string& PropName,
+/// EmitEdgePropertyTest2Args - Helper function used by
+/// EmitEdgePropertyTest.
+bool EmitEdgePropertyTest2Args(const std::string& PropName,
const DagInit& Prop,
const GlobalOptionDescriptions& OptDescs,
std::ostream& O) {
&& OptDesc.Type != OptionType::Prefix)
throw OptName + ": incorrect option type!";
O << OptDesc.GenVariableName() << " == \"" << OptArg << "\"";
+ return true;
}
else if (PropName == "element_in_list") {
if (OptDesc.Type != OptionType::ParameterList
O << "std::find(" << VarName << ".begin(),\n"
<< Indent3 << VarName << ".end(), \""
<< OptArg << "\") != " << VarName << ".end()";
+ return true;
}
- else
- throw PropName + ": unknown edge property!";
+
+ return false;
}
-// Helper function used by EmitEdgeClass.
-void EmitEdgePropertyTest(const std::string& PropName,
- const DagInit& Prop,
+// Forward declaration.
+void EmitEdgePropertyTest(const DagInit& Prop,
+ const GlobalOptionDescriptions& OptDescs,
+ std::ostream& O);
+
+/// EmitLogicalOperationTest - Helper function used by
+/// EmitEdgePropertyTest.
+void EmitLogicalOperationTest(const DagInit& Prop, const char* LogicOp,
+ const GlobalOptionDescriptions& OptDescs,
+ std::ostream& O) {
+ O << '(';
+ for (unsigned j = 0, NumArgs = Prop.getNumArgs(); j < NumArgs; ++j) {
+ const DagInit& InnerProp = InitPtrToDagInitRef(Prop.getArg(j));
+ EmitEdgePropertyTest(InnerProp, OptDescs, O);
+ if (j != NumArgs - 1)
+ O << ")\n" << Indent3 << ' ' << LogicOp << " (";
+ else
+ O << ')';
+ }
+}
+
+/// EmitEdgePropertyTest - Helper function used by EmitEdgeClass.
+void EmitEdgePropertyTest(const DagInit& Prop,
const GlobalOptionDescriptions& OptDescs,
std::ostream& O) {
- if (PropName == "switch_on")
- EmitEdgePropertyTest1Arg(Prop, OptDescs, O);
+ const std::string& PropName = Prop.getOperator()->getAsString();
+
+ if (PropName == "and")
+ EmitLogicalOperationTest(Prop, "&&", OptDescs, O);
+ else if (PropName == "or")
+ EmitLogicalOperationTest(Prop, "||", OptDescs, O);
+ else if (EmitEdgePropertyTest1Arg(PropName, Prop, OptDescs, O))
+ return;
+ else if (EmitEdgePropertyTest2Args(PropName, Prop, OptDescs, O))
+ return;
else
- EmitEdgePropertyTest2Args(PropName, Prop, OptDescs, O);
+ throw PropName + ": unknown edge property!";
}
-// Emit a single Edge* class.
+/// EmitEdgeClass - Emit a single Edge# class.
void EmitEdgeClass(unsigned N, const std::string& Target,
ListInit* Props, const GlobalOptionDescriptions& OptDescs,
std::ostream& O) {
- bool IsDefault = false;
// Class constructor.
O << "class Edge" << N << ": public Edge {\n"
<< Indent1 << "Edge" << N << "() : Edge(\"" << Target
<< "\") {}\n\n"
- // Function isEnabled().
- << Indent1 << "bool isEnabled() const {\n"
- << Indent2 << "bool ret = false;\n";
+ // Function Weight().
+ << Indent1 << "unsigned Weight(const InputLanguagesSet& InLangs) const {\n"
+ << Indent2 << "unsigned ret = 0;\n";
+ // Emit tests for every edge property.
for (size_t i = 0, PropsSize = Props->size(); i < PropsSize; ++i) {
- const DagInit& Prop = dynamic_cast<DagInit&>(*Props->getElement(i));
+ const DagInit& Prop = InitPtrToDagInitRef(Props->getElement(i));
const std::string& PropName = Prop.getOperator()->getAsString();
+ unsigned N = 2;
- if (PropName == "default")
- IsDefault = true;
-
- O << Indent2 << "if (ret || (";
- if (PropName == "and") {
- O << '(';
- for (unsigned j = 0, NumArgs = Prop.getNumArgs(); j < NumArgs; ++j) {
- const DagInit& InnerProp = dynamic_cast<DagInit&>(*Prop.getArg(j));
- const std::string& InnerPropName =
- InnerProp.getOperator()->getAsString();
- EmitEdgePropertyTest(InnerPropName, InnerProp, OptDescs, O);
- if (j != NumArgs - 1)
- O << ")\n" << Indent3 << " && (";
- else
- O << ')';
- }
+ O << Indent2 << "if (";
+
+ if (PropName == "weight") {
+ checkNumberOfArguments(&Prop, 2);
+ N = InitPtrToInt(Prop.getArg(0));
+ const DagInit& InnerProp = InitPtrToDagInitRef(Prop.getArg(1));
+ EmitEdgePropertyTest(InnerProp, OptDescs, O);
}
else {
- EmitEdgePropertyTest(PropName, Prop, OptDescs, O);
+ EmitEdgePropertyTest(Prop, OptDescs, O);
}
- O << "))\n" << Indent3 << "ret = true;\n";
+
+ O << ")\n" << Indent3 << "ret += " << N << ";\n";
}
O << Indent2 << "return ret;\n"
- << Indent1 << "};\n\n"
-
- // Function isDefault().
- << Indent1 << "bool isDefault() const { return ";
- if (IsDefault)
- O << "true";
- else
- O << "false";
- O <<"; }\n};\n\n";
+ << Indent1 << "};\n\n};\n\n";
}
// Emit Edge* classes that represent graph edges.
}
}
+/// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraph()
+/// function.
void EmitPopulateCompilationGraph (Record* CompilationGraph,
std::ostream& O)
{
// End of anonymous namespace
}
-// Back-end entry point
+/// run - The back-end entry point.
void LLVMCConfigurationEmitter::run (std::ostream &O) {
- // Emit file header
+
+ // Emit file header.
EmitSourceFileHeader("LLVMC Configuration Library", O);
- // Get a list of all defined Tools
+ // Get a list of all defined Tools.
RecordVector Tools = Records.getAllDerivedDefinitions("Tool");
if (Tools.empty())
throw std::string("No tool definitions found!");
- // Gather information from the Tool descriptions
+ // Gather information from the Tool description dags.
ToolPropertiesList tool_props;
GlobalOptionDescriptions opt_descs;
CollectToolProperties(Tools.begin(), Tools.end(), tool_props, opt_descs);
- // Emit global option registration code
+ // Emit global option registration code.
EmitOptionDescriptions(opt_descs, O);
- // Emit PopulateLanguageMap function
- // (a language map maps from file extensions to language names)
+ // Emit PopulateLanguageMap() function
+ // (a language map maps from file extensions to language names).
EmitPopulateLanguageMap(Records, O);
- // Emit Tool classes
+ // Emit Tool classes.
for (ToolPropertiesList::const_iterator B = tool_props.begin(),
E = tool_props.end(); B!=E; ++B)
EmitToolClassDefinition(*(*B), O);
// Typecheck the compilation graph.
TypecheckGraph(CompilationGraphRecord, tool_props);
- // Emit Edge* classes.
+ // Emit Edge# classes.
EmitEdgeClasses(CompilationGraphRecord, opt_descs, O);
- // Emit PopulateCompilationGraph function
+ // Emit PopulateCompilationGraph() function.
EmitPopulateCompilationGraph(CompilationGraphRecord, O);
// EOF