Home | History | Annotate | Download | only in TableGen
      1 //===- LLVMCConfigurationEmitter.cpp - Generate LLVMC config ----*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open
      6 // Source License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This tablegen backend is responsible for emitting LLVMC configuration code.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "LLVMCConfigurationEmitter.h"
     15 #include "Record.h"
     16 
     17 #include "llvm/ADT/IntrusiveRefCntPtr.h"
     18 #include "llvm/ADT/StringMap.h"
     19 #include "llvm/ADT/StringSet.h"
     20 
     21 #include <algorithm>
     22 #include <cassert>
     23 #include <functional>
     24 #include <stdexcept>
     25 #include <string>
     26 #include <typeinfo>
     27 
     28 
     29 using namespace llvm;
     30 
     31 namespace {
     32 
     33 //===----------------------------------------------------------------------===//
     34 /// Typedefs
     35 
     36 typedef std::vector<Record*> RecordVector;
     37 typedef std::vector<const DagInit*> DagVector;
     38 typedef std::vector<std::string> StrVector;
     39 
     40 //===----------------------------------------------------------------------===//
     41 /// Constants
     42 
     43 // Indentation.
     44 const unsigned TabWidth = 4;
     45 const unsigned Indent1  = TabWidth*1;
     46 const unsigned Indent2  = TabWidth*2;
     47 const unsigned Indent3  = TabWidth*3;
     48 const unsigned Indent4  = TabWidth*4;
     49 
     50 // Default help string.
     51 const char * const DefaultHelpString = "NO HELP MESSAGE PROVIDED";
     52 
     53 // Name for the "sink" option.
     54 const char * const SinkOptionName = "SinkOption";
     55 
     56 //===----------------------------------------------------------------------===//
     57 /// Helper functions
     58 
     59 /// Id - An 'identity' function object.
     60 struct Id {
     61   template<typename T0>
     62   void operator()(const T0&) const {
     63   }
     64   template<typename T0, typename T1>
     65   void operator()(const T0&, const T1&) const {
     66   }
     67   template<typename T0, typename T1, typename T2>
     68   void operator()(const T0&, const T1&, const T2&) const {
     69   }
     70 };
     71 
     72 int InitPtrToInt(const Init* ptr) {
     73   const IntInit& val = dynamic_cast<const IntInit&>(*ptr);
     74   return val.getValue();
     75 }
     76 
     77 bool InitPtrToBool(const Init* ptr) {
     78   bool ret = false;
     79   const DefInit& val = dynamic_cast<const DefInit&>(*ptr);
     80   const std::string& str = val.getAsString();
     81 
     82   if (str == "true") {
     83     ret = true;
     84   }
     85   else if (str == "false") {
     86     ret = false;
     87   }
     88   else {
     89     throw "Incorrect boolean value: '" + str +
     90       "': must be either 'true' or 'false'";
     91   }
     92 
     93   return ret;
     94 }
     95 
     96 const std::string& InitPtrToString(const Init* ptr) {
     97   const StringInit& val = dynamic_cast<const StringInit&>(*ptr);
     98   return val.getValue();
     99 }
    100 
    101 const ListInit& InitPtrToList(const Init* ptr) {
    102   const ListInit& val = dynamic_cast<const ListInit&>(*ptr);
    103   return val;
    104 }
    105 
    106 const DagInit& InitPtrToDag(const Init* ptr) {
    107   const DagInit& val = dynamic_cast<const DagInit&>(*ptr);
    108   return val;
    109 }
    110 
    111 const std::string GetOperatorName(const DagInit& D) {
    112   return D.getOperator()->getAsString();
    113 }
    114 
    115 /// CheckBooleanConstant - Check that the provided value is a boolean constant.
    116 void CheckBooleanConstant(const Init* I) {
    117   InitPtrToBool(I);
    118 }
    119 
    120 // CheckNumberOfArguments - Ensure that the number of args in d is
    121 // greater than or equal to min_arguments, otherwise throw an exception.
    122 void CheckNumberOfArguments (const DagInit& d, unsigned minArgs) {
    123   if (d.getNumArgs() < minArgs)
    124     throw GetOperatorName(d) + ": too few arguments!";
    125 }
    126 
    127 // EscapeVariableName - Escape commas and other symbols not allowed
    128 // in the C++ variable names. Makes it possible to use options named
    129 // like "Wa," (useful for prefix options).
    130 std::string EscapeVariableName (const std::string& Var) {
    131   std::string ret;
    132   for (unsigned i = 0; i != Var.size(); ++i) {
    133     char cur_char = Var[i];
    134     if (cur_char == ',') {
    135       ret += "_comma_";
    136     }
    137     else if (cur_char == '+') {
    138       ret += "_plus_";
    139     }
    140     else if (cur_char == '-') {
    141       ret += "_dash_";
    142     }
    143     else {
    144       ret.push_back(cur_char);
    145     }
    146   }
    147   return ret;
    148 }
    149 
    150 /// EscapeQuotes - Replace '"' with '\"'.
    151 std::string EscapeQuotes (const std::string& Var) {
    152   std::string ret;
    153   for (unsigned i = 0; i != Var.size(); ++i) {
    154     char cur_char = Var[i];
    155     if (cur_char == '"') {
    156       ret += "\\\"";
    157     }
    158     else {
    159       ret.push_back(cur_char);
    160     }
    161   }
    162   return ret;
    163 }
    164 
    165 /// OneOf - Does the input string contain this character?
    166 bool OneOf(const char* lst, char c) {
    167   while (*lst) {
    168     if (*lst++ == c)
    169       return true;
    170   }
    171   return false;
    172 }
    173 
    174 template <class I, class S>
    175 void CheckedIncrement(I& P, I E, S ErrorString) {
    176   ++P;
    177   if (P == E)
    178     throw ErrorString;
    179 }
    180 
    181 //===----------------------------------------------------------------------===//
    182 /// Back-end specific code
    183 
    184 
    185 /// OptionType - One of six different option types. See the
    186 /// documentation for detailed description of differences.
    187 namespace OptionType {
    188 
    189   enum OptionType { Alias, Switch, SwitchList,
    190                     Parameter, ParameterList, Prefix, PrefixList };
    191 
    192   bool IsAlias(OptionType t) {
    193     return (t == Alias);
    194   }
    195 
    196   bool IsList (OptionType t) {
    197     return (t == SwitchList || t == ParameterList || t == PrefixList);
    198   }
    199 
    200   bool IsSwitch (OptionType t) {
    201     return (t == Switch);
    202   }
    203 
    204   bool IsSwitchList (OptionType t) {
    205     return (t == SwitchList);
    206   }
    207 
    208   bool IsParameter (OptionType t) {
    209     return (t == Parameter || t == Prefix);
    210   }
    211 
    212 }
    213 
    214 OptionType::OptionType stringToOptionType(const std::string& T) {
    215   if (T == "alias_option")
    216     return OptionType::Alias;
    217   else if (T == "switch_option")
    218     return OptionType::Switch;
    219   else if (T == "switch_list_option")
    220     return OptionType::SwitchList;
    221   else if (T == "parameter_option")
    222     return OptionType::Parameter;
    223   else if (T == "parameter_list_option")
    224     return OptionType::ParameterList;
    225   else if (T == "prefix_option")
    226     return OptionType::Prefix;
    227   else if (T == "prefix_list_option")
    228     return OptionType::PrefixList;
    229   else
    230     throw "Unknown option type: " + T + '!';
    231 }
    232 
    233 namespace OptionDescriptionFlags {
    234   enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2,
    235                                 ReallyHidden = 0x4, OneOrMore = 0x8,
    236                                 Optional = 0x10, CommaSeparated = 0x20,
    237                                 ForwardNotSplit = 0x40, ZeroOrMore = 0x80 };
    238 }
    239 
    240 /// OptionDescription - Represents data contained in a single
    241 /// OptionList entry.
    242 struct OptionDescription {
    243   OptionType::OptionType Type;
    244   std::string Name;
    245   unsigned Flags;
    246   std::string Help;
    247   unsigned MultiVal;
    248   Init* InitVal;
    249 
    250   OptionDescription(OptionType::OptionType t = OptionType::Switch,
    251                     const std::string& n = "",
    252                     const std::string& h = DefaultHelpString)
    253     : Type(t), Name(n), Flags(0x0), Help(h), MultiVal(1), InitVal(0)
    254   {}
    255 
    256   /// GenTypeDeclaration - Returns the C++ variable type of this
    257   /// option.
    258   const char* GenTypeDeclaration() const;
    259 
    260   /// GenVariableName - Returns the variable name used in the
    261   /// generated C++ code.
    262   std::string GenVariableName() const
    263   { return "autogenerated::" + GenOptionType() + EscapeVariableName(Name); }
    264 
    265   /// GenPlainVariableName - Returns the variable name without the namespace
    266   /// prefix.
    267   std::string GenPlainVariableName() const
    268   { return GenOptionType() + EscapeVariableName(Name); }
    269 
    270   /// Merge - Merge two option descriptions.
    271   void Merge (const OptionDescription& other);
    272 
    273   /// CheckConsistency - Check that the flags are consistent.
    274   void CheckConsistency() const;
    275 
    276   // Misc convenient getters/setters.
    277 
    278   bool isAlias() const;
    279 
    280   bool isMultiVal() const;
    281 
    282   bool isCommaSeparated() const;
    283   void setCommaSeparated();
    284 
    285   bool isForwardNotSplit() const;
    286   void setForwardNotSplit();
    287 
    288   bool isRequired() const;
    289   void setRequired();
    290 
    291   bool isOneOrMore() const;
    292   void setOneOrMore();
    293 
    294   bool isZeroOrMore() const;
    295   void setZeroOrMore();
    296 
    297   bool isOptional() const;
    298   void setOptional();
    299 
    300   bool isHidden() const;
    301   void setHidden();
    302 
    303   bool isReallyHidden() const;
    304   void setReallyHidden();
    305 
    306   bool isSwitch() const
    307   { return OptionType::IsSwitch(this->Type); }
    308 
    309   bool isSwitchList() const
    310   { return OptionType::IsSwitchList(this->Type); }
    311 
    312   bool isParameter() const
    313   { return OptionType::IsParameter(this->Type); }
    314 
    315   bool isList() const
    316   { return OptionType::IsList(this->Type); }
    317 
    318   bool isParameterList() const
    319   { return (OptionType::IsList(this->Type)
    320             && !OptionType::IsSwitchList(this->Type)); }
    321 
    322 private:
    323 
    324   // GenOptionType - Helper function used by GenVariableName().
    325   std::string GenOptionType() const;
    326 };
    327 
    328 void OptionDescription::CheckConsistency() const {
    329   unsigned i = 0;
    330 
    331   i += this->isRequired();
    332   i += this->isOptional();
    333   i += this->isOneOrMore();
    334   i += this->isZeroOrMore();
    335 
    336   if (i > 1) {
    337     throw "Only one of (required), (optional), (one_or_more) or "
    338       "(zero_or_more) properties is allowed!";
    339   }
    340 }
    341 
    342 void OptionDescription::Merge (const OptionDescription& other)
    343 {
    344   if (other.Type != Type)
    345     throw "Conflicting definitions for the option " + Name + "!";
    346 
    347   if (Help == other.Help || Help == DefaultHelpString)
    348     Help = other.Help;
    349   else if (other.Help != DefaultHelpString) {
    350     llvm::errs() << "Warning: several different help strings"
    351       " defined for option " + Name + "\n";
    352   }
    353 
    354   Flags |= other.Flags;
    355 }
    356 
    357 bool OptionDescription::isAlias() const {
    358   return OptionType::IsAlias(this->Type);
    359 }
    360 
    361 bool OptionDescription::isMultiVal() const {
    362   return MultiVal > 1;
    363 }
    364 
    365 bool OptionDescription::isCommaSeparated() const {
    366   return Flags & OptionDescriptionFlags::CommaSeparated;
    367 }
    368 void OptionDescription::setCommaSeparated() {
    369   Flags |= OptionDescriptionFlags::CommaSeparated;
    370 }
    371 
    372 bool OptionDescription::isForwardNotSplit() const {
    373   return Flags & OptionDescriptionFlags::ForwardNotSplit;
    374 }
    375 void OptionDescription::setForwardNotSplit() {
    376   Flags |= OptionDescriptionFlags::ForwardNotSplit;
    377 }
    378 
    379 bool OptionDescription::isRequired() const {
    380   return Flags & OptionDescriptionFlags::Required;
    381 }
    382 void OptionDescription::setRequired() {
    383   Flags |= OptionDescriptionFlags::Required;
    384 }
    385 
    386 bool OptionDescription::isOneOrMore() const {
    387   return Flags & OptionDescriptionFlags::OneOrMore;
    388 }
    389 void OptionDescription::setOneOrMore() {
    390   Flags |= OptionDescriptionFlags::OneOrMore;
    391 }
    392 
    393 bool OptionDescription::isZeroOrMore() const {
    394   return Flags & OptionDescriptionFlags::ZeroOrMore;
    395 }
    396 void OptionDescription::setZeroOrMore() {
    397   Flags |= OptionDescriptionFlags::ZeroOrMore;
    398 }
    399 
    400 bool OptionDescription::isOptional() const {
    401   return Flags & OptionDescriptionFlags::Optional;
    402 }
    403 void OptionDescription::setOptional() {
    404   Flags |= OptionDescriptionFlags::Optional;
    405 }
    406 
    407 bool OptionDescription::isHidden() const {
    408   return Flags & OptionDescriptionFlags::Hidden;
    409 }
    410 void OptionDescription::setHidden() {
    411   Flags |= OptionDescriptionFlags::Hidden;
    412 }
    413 
    414 bool OptionDescription::isReallyHidden() const {
    415   return Flags & OptionDescriptionFlags::ReallyHidden;
    416 }
    417 void OptionDescription::setReallyHidden() {
    418   Flags |= OptionDescriptionFlags::ReallyHidden;
    419 }
    420 
    421 const char* OptionDescription::GenTypeDeclaration() const {
    422   switch (Type) {
    423   case OptionType::Alias:
    424     return "cl::alias";
    425   case OptionType::PrefixList:
    426   case OptionType::ParameterList:
    427     return "cl::list<std::string>";
    428   case OptionType::Switch:
    429     return "cl::opt<bool>";
    430   case OptionType::SwitchList:
    431     return "cl::list<bool>";
    432   case OptionType::Parameter:
    433   case OptionType::Prefix:
    434   default:
    435     return "cl::opt<std::string>";
    436   }
    437 }
    438 
    439 std::string OptionDescription::GenOptionType() const {
    440   switch (Type) {
    441   case OptionType::Alias:
    442     return "Alias_";
    443   case OptionType::PrefixList:
    444   case OptionType::ParameterList:
    445     return "List_";
    446   case OptionType::Switch:
    447     return "Switch_";
    448   case OptionType::SwitchList:
    449     return "SwitchList_";
    450   case OptionType::Prefix:
    451   case OptionType::Parameter:
    452   default:
    453     return "Parameter_";
    454   }
    455 }
    456 
    457 /// OptionDescriptions - An OptionDescription array plus some helper
    458 /// functions.
    459 class OptionDescriptions {
    460   typedef StringMap<OptionDescription> container_type;
    461 
    462   /// Descriptions - A list of OptionDescriptions.
    463   container_type Descriptions;
    464 
    465 public:
    466   /// FindOption - exception-throwing wrapper for find().
    467   const OptionDescription& FindOption(const std::string& OptName) const;
    468 
    469   // Wrappers for FindOption that throw an exception in case the option has a
    470   // wrong type.
    471   const OptionDescription& FindSwitch(const std::string& OptName) const;
    472   const OptionDescription& FindParameter(const std::string& OptName) const;
    473   const OptionDescription& FindParameterList(const std::string& OptName) const;
    474   const OptionDescription&
    475   FindListOrParameter(const std::string& OptName) const;
    476   const OptionDescription&
    477   FindParameterListOrParameter(const std::string& OptName) const;
    478 
    479   /// insertDescription - Insert new OptionDescription into
    480   /// OptionDescriptions list
    481   void InsertDescription (const OptionDescription& o);
    482 
    483   // Support for STL-style iteration
    484   typedef container_type::const_iterator const_iterator;
    485   const_iterator begin() const { return Descriptions.begin(); }
    486   const_iterator end() const { return Descriptions.end(); }
    487 };
    488 
    489 const OptionDescription&
    490 OptionDescriptions::FindOption(const std::string& OptName) const {
    491   const_iterator I = Descriptions.find(OptName);
    492   if (I != Descriptions.end())
    493     return I->second;
    494   else
    495     throw OptName + ": no such option!";
    496 }
    497 
    498 const OptionDescription&
    499 OptionDescriptions::FindSwitch(const std::string& OptName) const {
    500   const OptionDescription& OptDesc = this->FindOption(OptName);
    501   if (!OptDesc.isSwitch())
    502     throw OptName + ": incorrect option type - should be a switch!";
    503   return OptDesc;
    504 }
    505 
    506 const OptionDescription&
    507 OptionDescriptions::FindParameterList(const std::string& OptName) const {
    508   const OptionDescription& OptDesc = this->FindOption(OptName);
    509   if (!OptDesc.isList() || OptDesc.isSwitchList())
    510     throw OptName + ": incorrect option type - should be a parameter list!";
    511   return OptDesc;
    512 }
    513 
    514 const OptionDescription&
    515 OptionDescriptions::FindParameter(const std::string& OptName) const {
    516   const OptionDescription& OptDesc = this->FindOption(OptName);
    517   if (!OptDesc.isParameter())
    518     throw OptName + ": incorrect option type - should be a parameter!";
    519   return OptDesc;
    520 }
    521 
    522 const OptionDescription&
    523 OptionDescriptions::FindListOrParameter(const std::string& OptName) const {
    524   const OptionDescription& OptDesc = this->FindOption(OptName);
    525   if (!OptDesc.isList() && !OptDesc.isParameter())
    526     throw OptName
    527       + ": incorrect option type - should be a list or parameter!";
    528   return OptDesc;
    529 }
    530 
    531 const OptionDescription&
    532 OptionDescriptions::FindParameterListOrParameter
    533 (const std::string& OptName) const {
    534   const OptionDescription& OptDesc = this->FindOption(OptName);
    535   if ((!OptDesc.isList() && !OptDesc.isParameter()) || OptDesc.isSwitchList())
    536     throw OptName
    537       + ": incorrect option type - should be a parameter list or parameter!";
    538   return OptDesc;
    539 }
    540 
    541 void OptionDescriptions::InsertDescription (const OptionDescription& o) {
    542   container_type::iterator I = Descriptions.find(o.Name);
    543   if (I != Descriptions.end()) {
    544     OptionDescription& D = I->second;
    545     D.Merge(o);
    546   }
    547   else {
    548     Descriptions[o.Name] = o;
    549   }
    550 }
    551 
    552 /// HandlerTable - A base class for function objects implemented as
    553 /// 'tables of handlers'.
    554 template <typename Handler>
    555 class HandlerTable {
    556 protected:
    557   // Implementation details.
    558 
    559   /// HandlerMap - A map from property names to property handlers
    560   typedef StringMap<Handler> HandlerMap;
    561 
    562   static HandlerMap Handlers_;
    563   static bool staticMembersInitialized_;
    564 
    565 public:
    566 
    567   Handler GetHandler (const std::string& HandlerName) const {
    568     typename HandlerMap::iterator method = Handlers_.find(HandlerName);
    569 
    570     if (method != Handlers_.end()) {
    571       Handler h = method->second;
    572       return h;
    573     }
    574     else {
    575       throw "No handler found for property " + HandlerName + "!";
    576     }
    577   }
    578 
    579   void AddHandler(const char* Property, Handler H) {
    580     Handlers_[Property] = H;
    581   }
    582 
    583 };
    584 
    585 template <class Handler, class FunctionObject>
    586 Handler GetHandler(FunctionObject* Obj, const DagInit& Dag) {
    587   const std::string& HandlerName = GetOperatorName(Dag);
    588   return Obj->GetHandler(HandlerName);
    589 }
    590 
    591 template <class FunctionObject>
    592 void InvokeDagInitHandler(FunctionObject* Obj, Init* I) {
    593   typedef void (FunctionObject::*Handler) (const DagInit&);
    594 
    595   const DagInit& Dag = InitPtrToDag(I);
    596   Handler h = GetHandler<Handler>(Obj, Dag);
    597 
    598   ((Obj)->*(h))(Dag);
    599 }
    600 
    601 template <class FunctionObject>
    602 void InvokeDagInitHandler(const FunctionObject* const Obj,
    603                           const Init* I, unsigned IndentLevel, raw_ostream& O)
    604 {
    605   typedef void (FunctionObject::*Handler)
    606     (const DagInit&, unsigned IndentLevel, raw_ostream& O) const;
    607 
    608   const DagInit& Dag = InitPtrToDag(I);
    609   Handler h = GetHandler<Handler>(Obj, Dag);
    610 
    611   ((Obj)->*(h))(Dag, IndentLevel, O);
    612 }
    613 
    614 template <typename H>
    615 typename HandlerTable<H>::HandlerMap HandlerTable<H>::Handlers_;
    616 
    617 template <typename H>
    618 bool HandlerTable<H>::staticMembersInitialized_ = false;
    619 
    620 
    621 /// CollectOptionProperties - Function object for iterating over an
    622 /// option property list.
    623 class CollectOptionProperties;
    624 typedef void (CollectOptionProperties::* CollectOptionPropertiesHandler)
    625 (const DagInit&);
    626 
    627 class CollectOptionProperties
    628 : public HandlerTable<CollectOptionPropertiesHandler>
    629 {
    630 private:
    631 
    632   /// optDescs_ - OptionDescriptions table. This is where the
    633   /// information is stored.
    634   OptionDescription& optDesc_;
    635 
    636 public:
    637 
    638   explicit CollectOptionProperties(OptionDescription& OD)
    639     : optDesc_(OD)
    640   {
    641     if (!staticMembersInitialized_) {
    642       AddHandler("help", &CollectOptionProperties::onHelp);
    643       AddHandler("hidden", &CollectOptionProperties::onHidden);
    644       AddHandler("init", &CollectOptionProperties::onInit);
    645       AddHandler("multi_val", &CollectOptionProperties::onMultiVal);
    646       AddHandler("one_or_more", &CollectOptionProperties::onOneOrMore);
    647       AddHandler("zero_or_more", &CollectOptionProperties::onZeroOrMore);
    648       AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden);
    649       AddHandler("required", &CollectOptionProperties::onRequired);
    650       AddHandler("optional", &CollectOptionProperties::onOptional);
    651       AddHandler("comma_separated", &CollectOptionProperties::onCommaSeparated);
    652       AddHandler("forward_not_split",
    653                  &CollectOptionProperties::onForwardNotSplit);
    654 
    655       staticMembersInitialized_ = true;
    656     }
    657   }
    658 
    659   /// operator() - Just forwards to the corresponding property
    660   /// handler.
    661   void operator() (Init* I) {
    662     InvokeDagInitHandler(this, I);
    663   }
    664 
    665 private:
    666 
    667   /// Option property handlers --
    668   /// Methods that handle option properties such as (help) or (hidden).
    669 
    670   void onHelp (const DagInit& d) {
    671     CheckNumberOfArguments(d, 1);
    672     optDesc_.Help = EscapeQuotes(InitPtrToString(d.getArg(0)));
    673   }
    674 
    675   void onHidden (const DagInit& d) {
    676     CheckNumberOfArguments(d, 0);
    677     optDesc_.setHidden();
    678   }
    679 
    680   void onReallyHidden (const DagInit& d) {
    681     CheckNumberOfArguments(d, 0);
    682     optDesc_.setReallyHidden();
    683   }
    684 
    685   void onCommaSeparated (const DagInit& d) {
    686     CheckNumberOfArguments(d, 0);
    687     if (!optDesc_.isParameterList())
    688       throw "'comma_separated' is valid only on parameter list options!";
    689     optDesc_.setCommaSeparated();
    690   }
    691 
    692   void onForwardNotSplit (const DagInit& d) {
    693     CheckNumberOfArguments(d, 0);
    694     if (!optDesc_.isParameter())
    695       throw "'forward_not_split' is valid only for parameter options!";
    696     optDesc_.setForwardNotSplit();
    697   }
    698 
    699   void onRequired (const DagInit& d) {
    700     CheckNumberOfArguments(d, 0);
    701 
    702     optDesc_.setRequired();
    703     optDesc_.CheckConsistency();
    704   }
    705 
    706   void onInit (const DagInit& d) {
    707     CheckNumberOfArguments(d, 1);
    708     Init* i = d.getArg(0);
    709     const std::string& str = i->getAsString();
    710 
    711     bool correct = optDesc_.isParameter() && dynamic_cast<StringInit*>(i);
    712     correct |= (optDesc_.isSwitch() && (str == "true" || str == "false"));
    713 
    714     if (!correct)
    715       throw "Incorrect usage of the 'init' option property!";
    716 
    717     optDesc_.InitVal = i;
    718   }
    719 
    720   void onOneOrMore (const DagInit& d) {
    721     CheckNumberOfArguments(d, 0);
    722 
    723     optDesc_.setOneOrMore();
    724     optDesc_.CheckConsistency();
    725   }
    726 
    727   void onZeroOrMore (const DagInit& d) {
    728     CheckNumberOfArguments(d, 0);
    729 
    730     if (optDesc_.isList())
    731       llvm::errs() << "Warning: specifying the 'zero_or_more' property "
    732         "on a list option has no effect.\n";
    733 
    734     optDesc_.setZeroOrMore();
    735     optDesc_.CheckConsistency();
    736   }
    737 
    738   void onOptional (const DagInit& d) {
    739     CheckNumberOfArguments(d, 0);
    740 
    741     if (!optDesc_.isList())
    742       llvm::errs() << "Warning: specifying the 'optional' property"
    743         "on a non-list option has no effect.\n";
    744 
    745     optDesc_.setOptional();
    746     optDesc_.CheckConsistency();
    747   }
    748 
    749   void onMultiVal (const DagInit& d) {
    750     CheckNumberOfArguments(d, 1);
    751     int val = InitPtrToInt(d.getArg(0));
    752     if (val < 2)
    753       throw "Error in the 'multi_val' property: "
    754         "the value must be greater than 1!";
    755     if (!optDesc_.isParameterList())
    756       throw "The multi_val property is valid only on list options!";
    757     optDesc_.MultiVal = val;
    758   }
    759 
    760 };
    761 
    762 /// AddOption - A function object that is applied to every option
    763 /// description. Used by CollectOptionDescriptions.
    764 class AddOption {
    765 private:
    766   OptionDescriptions& OptDescs_;
    767 
    768 public:
    769   explicit AddOption(OptionDescriptions& OD) : OptDescs_(OD)
    770   {}
    771 
    772   void operator()(const Init* i) {
    773     const DagInit& d = InitPtrToDag(i);
    774     CheckNumberOfArguments(d, 1);
    775 
    776     const OptionType::OptionType Type =
    777       stringToOptionType(GetOperatorName(d));
    778     const std::string& Name = InitPtrToString(d.getArg(0));
    779 
    780     OptionDescription OD(Type, Name);
    781 
    782     CheckNumberOfArguments(d, 2);
    783 
    784     // Alias option store the aliased option name in the 'Help' field and do not
    785     // have any properties.
    786     if (OD.isAlias()) {
    787       OD.Help = InitPtrToString(d.getArg(1));
    788     }
    789     else {
    790       processOptionProperties(d, OD);
    791     }
    792 
    793     // Switch options are ZeroOrMore by default.
    794     if (OD.isSwitch()) {
    795       if (!(OD.isOptional() || OD.isOneOrMore() || OD.isRequired()))
    796         OD.setZeroOrMore();
    797     }
    798 
    799     OptDescs_.InsertDescription(OD);
    800   }
    801 
    802 private:
    803   /// processOptionProperties - Go through the list of option
    804   /// properties and call a corresponding handler for each.
    805   static void processOptionProperties (const DagInit& d, OptionDescription& o) {
    806     CheckNumberOfArguments(d, 2);
    807     DagInit::const_arg_iterator B = d.arg_begin();
    808     // Skip the first argument: it's always the option name.
    809     ++B;
    810     std::for_each(B, d.arg_end(), CollectOptionProperties(o));
    811   }
    812 
    813 };
    814 
    815 /// CollectOptionDescriptions - Collects option properties from all
    816 /// OptionLists.
    817 void CollectOptionDescriptions (const RecordVector& V,
    818                                 OptionDescriptions& OptDescs)
    819 {
    820   // For every OptionList:
    821   for (RecordVector::const_iterator B = V.begin(), E = V.end(); B!=E; ++B)
    822   {
    823     // Throws an exception if the value does not exist.
    824     ListInit* PropList = (*B)->getValueAsListInit("options");
    825 
    826     // For every option description in this list: invoke AddOption.
    827     std::for_each(PropList->begin(), PropList->end(), AddOption(OptDescs));
    828   }
    829 }
    830 
    831 // Tool information record
    832 
    833 namespace ToolFlags {
    834   enum ToolFlags { Join = 0x1, Sink = 0x2 };
    835 }
    836 
    837 struct ToolDescription : public RefCountedBase<ToolDescription> {
    838   std::string Name;
    839   Init* CmdLine;
    840   Init* Actions;
    841   StrVector InLanguage;
    842   std::string InFileOption;
    843   std::string OutFileOption;
    844   StrVector OutLanguage;
    845   std::string OutputSuffix;
    846   unsigned Flags;
    847   const Init* OnEmpty;
    848 
    849   // Various boolean properties
    850   void setSink()      { Flags |= ToolFlags::Sink; }
    851   bool isSink() const { return Flags & ToolFlags::Sink; }
    852   void setJoin()      { Flags |= ToolFlags::Join; }
    853   bool isJoin() const { return Flags & ToolFlags::Join; }
    854 
    855   // Default ctor here is needed because StringMap can only store
    856   // DefaultConstructible objects
    857   ToolDescription (const std::string &n = "")
    858     : Name(n), CmdLine(0), Actions(0), OutFileOption("-o"),
    859       Flags(0), OnEmpty(0)
    860   {}
    861 };
    862 
    863 /// ToolDescriptions - A list of Tool information records.
    864 typedef std::vector<IntrusiveRefCntPtr<ToolDescription> > ToolDescriptions;
    865 
    866 
    867 /// CollectToolProperties - Function object for iterating over a list of
    868 /// tool property records.
    869 
    870 class CollectToolProperties;
    871 typedef void (CollectToolProperties::* CollectToolPropertiesHandler)
    872 (const DagInit&);
    873 
    874 class CollectToolProperties : public HandlerTable<CollectToolPropertiesHandler>
    875 {
    876 private:
    877 
    878   /// toolDesc_ - Properties of the current Tool. This is where the
    879   /// information is stored.
    880   ToolDescription& toolDesc_;
    881 
    882 public:
    883 
    884   explicit CollectToolProperties (ToolDescription& d)
    885     : toolDesc_(d)
    886   {
    887     if (!staticMembersInitialized_) {
    888 
    889       AddHandler("actions", &CollectToolProperties::onActions);
    890       AddHandler("command", &CollectToolProperties::onCommand);
    891       AddHandler("in_language", &CollectToolProperties::onInLanguage);
    892       AddHandler("join", &CollectToolProperties::onJoin);
    893       AddHandler("out_language", &CollectToolProperties::onOutLanguage);
    894 
    895       AddHandler("out_file_option", &CollectToolProperties::onOutFileOption);
    896       AddHandler("in_file_option", &CollectToolProperties::onInFileOption);
    897 
    898       AddHandler("output_suffix", &CollectToolProperties::onOutputSuffix);
    899       AddHandler("sink", &CollectToolProperties::onSink);
    900       AddHandler("works_on_empty", &CollectToolProperties::onWorksOnEmpty);
    901 
    902       staticMembersInitialized_ = true;
    903     }
    904   }
    905 
    906   void operator() (Init* I) {
    907     InvokeDagInitHandler(this, I);
    908   }
    909 
    910 private:
    911 
    912   /// Property handlers --
    913   /// Functions that extract information about tool properties from
    914   /// DAG representation.
    915 
    916   void onActions (const DagInit& d) {
    917     CheckNumberOfArguments(d, 1);
    918     Init* Case = d.getArg(0);
    919     if (typeid(*Case) != typeid(DagInit) ||
    920         GetOperatorName(static_cast<DagInit&>(*Case)) != "case")
    921       throw "The argument to (actions) should be a 'case' construct!";
    922     toolDesc_.Actions = Case;
    923   }
    924 
    925   void onCommand (const DagInit& d) {
    926     CheckNumberOfArguments(d, 1);
    927     toolDesc_.CmdLine = d.getArg(0);
    928   }
    929 
    930   /// onInOutLanguage - Common implementation of on{In,Out}Language().
    931   void onInOutLanguage (const DagInit& d, StrVector& OutVec) {
    932     CheckNumberOfArguments(d, 1);
    933 
    934     // Copy strings to the output vector.
    935     for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) {
    936       OutVec.push_back(InitPtrToString(d.getArg(i)));
    937     }
    938 
    939     // Remove duplicates.
    940     std::sort(OutVec.begin(), OutVec.end());
    941     StrVector::iterator newE = std::unique(OutVec.begin(), OutVec.end());
    942     OutVec.erase(newE, OutVec.end());
    943   }
    944 
    945 
    946   void onInLanguage (const DagInit& d) {
    947     this->onInOutLanguage(d, toolDesc_.InLanguage);
    948   }
    949 
    950   void onJoin (const DagInit& d) {
    951     bool isReallyJoin = false;
    952 
    953     if (d.getNumArgs() == 0) {
    954       isReallyJoin = true;
    955     }
    956     else {
    957       Init* I = d.getArg(0);
    958       isReallyJoin = InitPtrToBool(I);
    959     }
    960 
    961     // Is this *really* a join tool? We allow (join false) for generating two
    962     // tool descriptions from a single generic one.
    963     // TOFIX: come up with a cleaner solution.
    964     if (isReallyJoin) {
    965       toolDesc_.setJoin();
    966     }
    967   }
    968 
    969   void onOutLanguage (const DagInit& d) {
    970     this->onInOutLanguage(d, toolDesc_.OutLanguage);
    971   }
    972 
    973   void onOutFileOption (const DagInit& d) {
    974     CheckNumberOfArguments(d, 1);
    975     toolDesc_.OutFileOption = InitPtrToString(d.getArg(0));
    976   }
    977 
    978   void onInFileOption (const DagInit& d) {
    979     CheckNumberOfArguments(d, 1);
    980     toolDesc_.InFileOption = InitPtrToString(d.getArg(0));
    981   }
    982 
    983   void onOutputSuffix (const DagInit& d) {
    984     CheckNumberOfArguments(d, 1);
    985     toolDesc_.OutputSuffix = InitPtrToString(d.getArg(0));
    986   }
    987 
    988   void onSink (const DagInit& d) {
    989     CheckNumberOfArguments(d, 0);
    990     toolDesc_.setSink();
    991   }
    992 
    993   void onWorksOnEmpty (const DagInit& d) {
    994     toolDesc_.OnEmpty = d.getArg(0);
    995   }
    996 
    997 };
    998 
    999 /// CollectToolDescriptions - Gather information about tool properties
   1000 /// from the parsed TableGen data (basically a wrapper for the
   1001 /// CollectToolProperties function object).
   1002 void CollectToolDescriptions (const RecordVector& Tools,
   1003                               ToolDescriptions& ToolDescs)
   1004 {
   1005   // Iterate over a properties list of every Tool definition
   1006   for (RecordVector::const_iterator B = Tools.begin(),
   1007          E = Tools.end(); B!=E; ++B) {
   1008     const Record* T = *B;
   1009     // Throws an exception if the value does not exist.
   1010     ListInit* PropList = T->getValueAsListInit("properties");
   1011 
   1012     IntrusiveRefCntPtr<ToolDescription>
   1013       ToolDesc(new ToolDescription(T->getName()));
   1014 
   1015     std::for_each(PropList->begin(), PropList->end(),
   1016                   CollectToolProperties(*ToolDesc));
   1017     ToolDescs.push_back(ToolDesc);
   1018   }
   1019 }
   1020 
   1021 /// FillInEdgeVector - Merge all compilation graph definitions into
   1022 /// one single edge list.
   1023 void FillInEdgeVector(const RecordVector& CompilationGraphs,
   1024                       DagVector& Out) {
   1025   for (RecordVector::const_iterator B = CompilationGraphs.begin(),
   1026          E = CompilationGraphs.end(); B != E; ++B) {
   1027     const ListInit* Edges = (*B)->getValueAsListInit("edges");
   1028 
   1029     for (ListInit::const_iterator B = Edges->begin(),
   1030            E = Edges->end(); B != E; ++B) {
   1031       Out.push_back(&InitPtrToDag(*B));
   1032     }
   1033   }
   1034 }
   1035 
   1036 /// NotInGraph - Helper function object for FilterNotInGraph.
   1037 struct NotInGraph {
   1038 private:
   1039   const llvm::StringSet<>& ToolsInGraph_;
   1040 
   1041 public:
   1042   NotInGraph(const llvm::StringSet<>& ToolsInGraph)
   1043   : ToolsInGraph_(ToolsInGraph)
   1044   {}
   1045 
   1046   bool operator()(const IntrusiveRefCntPtr<ToolDescription>& x) {
   1047     return (ToolsInGraph_.count(x->Name) == 0);
   1048   }
   1049 };
   1050 
   1051 /// FilterNotInGraph - Filter out from ToolDescs all Tools not
   1052 /// mentioned in the compilation graph definition.
   1053 void FilterNotInGraph (const DagVector& EdgeVector,
   1054                        ToolDescriptions& ToolDescs) {
   1055 
   1056   // List all tools mentioned in the graph.
   1057   llvm::StringSet<> ToolsInGraph;
   1058 
   1059   for (DagVector::const_iterator B = EdgeVector.begin(),
   1060          E = EdgeVector.end(); B != E; ++B) {
   1061 
   1062     const DagInit* Edge = *B;
   1063     const std::string& NodeA = InitPtrToString(Edge->getArg(0));
   1064     const std::string& NodeB = InitPtrToString(Edge->getArg(1));
   1065 
   1066     if (NodeA != "root")
   1067       ToolsInGraph.insert(NodeA);
   1068     ToolsInGraph.insert(NodeB);
   1069   }
   1070 
   1071   // Filter ToolPropertiesList.
   1072   ToolDescriptions::iterator new_end =
   1073     std::remove_if(ToolDescs.begin(), ToolDescs.end(),
   1074                    NotInGraph(ToolsInGraph));
   1075   ToolDescs.erase(new_end, ToolDescs.end());
   1076 }
   1077 
   1078 /// FillInToolToLang - Fills in two tables that map tool names to
   1079 /// input & output language names.  Helper function used by TypecheckGraph().
   1080 void FillInToolToLang (const ToolDescriptions& ToolDescs,
   1081                        StringMap<StringSet<> >& ToolToInLang,
   1082                        StringMap<StringSet<> >& ToolToOutLang) {
   1083   for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
   1084          E = ToolDescs.end(); B != E; ++B) {
   1085     const ToolDescription& D = *(*B);
   1086     for (StrVector::const_iterator B = D.InLanguage.begin(),
   1087            E = D.InLanguage.end(); B != E; ++B)
   1088       ToolToInLang[D.Name].insert(*B);
   1089     for (StrVector::const_iterator B = D.OutLanguage.begin(),
   1090            E = D.OutLanguage.end(); B != E; ++B)
   1091       ToolToOutLang[D.Name].insert(*B);
   1092   }
   1093 }
   1094 
   1095 /// Intersect - Is set intersection non-empty?
   1096 bool Intersect (const StringSet<>& S1, const StringSet<>& S2) {
   1097   for (StringSet<>::const_iterator B = S1.begin(), E = S1.end(); B != E; ++B) {
   1098     if (S2.count(B->first()) != 0)
   1099       return true;
   1100   }
   1101   return false;
   1102 }
   1103 
   1104 /// TypecheckGraph - Check that names for output and input languages
   1105 /// on all edges do match.
   1106 void TypecheckGraph (const DagVector& EdgeVector,
   1107                      const ToolDescriptions& ToolDescs) {
   1108   StringMap<StringSet<> > ToolToInLang;
   1109   StringMap<StringSet<> > ToolToOutLang;
   1110 
   1111   FillInToolToLang(ToolDescs, ToolToInLang, ToolToOutLang);
   1112 
   1113   for (DagVector::const_iterator B = EdgeVector.begin(),
   1114          E = EdgeVector.end(); B != E; ++B) {
   1115     const DagInit* Edge = *B;
   1116     const std::string& NodeA = InitPtrToString(Edge->getArg(0));
   1117     const std::string& NodeB = InitPtrToString(Edge->getArg(1));
   1118     StringMap<StringSet<> >::iterator IA = ToolToOutLang.find(NodeA);
   1119     StringMap<StringSet<> >::iterator IB = ToolToInLang.find(NodeB);
   1120 
   1121     if (NodeB == "root")
   1122       throw "Edges back to the root are not allowed!";
   1123 
   1124     if (NodeA != "root") {
   1125       if (IA == ToolToOutLang.end())
   1126         throw NodeA + ": no output language defined!";
   1127       if (IB == ToolToInLang.end())
   1128         throw NodeB + ": no input language defined!";
   1129 
   1130       if (!Intersect(IA->second, IB->second)) {
   1131         throw "Edge " + NodeA + "->" + NodeB
   1132           + ": output->input language mismatch";
   1133       }
   1134     }
   1135   }
   1136 }
   1137 
   1138 /// WalkCase - Walks the 'case' expression DAG and invokes
   1139 /// TestCallback on every test, and StatementCallback on every
   1140 /// statement. Handles 'case' nesting, but not the 'and' and 'or'
   1141 /// combinators (that is, they are passed directly to TestCallback).
   1142 /// TestCallback must have type 'void TestCallback(const DagInit*, unsigned
   1143 /// IndentLevel, bool FirstTest)'.
   1144 /// StatementCallback must have type 'void StatementCallback(const Init*,
   1145 /// unsigned IndentLevel)'.
   1146 template <typename F1, typename F2>
   1147 void WalkCase(const Init* Case, F1 TestCallback, F2 StatementCallback,
   1148               unsigned IndentLevel = 0)
   1149 {
   1150   const DagInit& d = InitPtrToDag(Case);
   1151 
   1152   // Error checks.
   1153   if (GetOperatorName(d) != "case")
   1154     throw "WalkCase should be invoked only on 'case' expressions!";
   1155 
   1156   if (d.getNumArgs() < 2)
   1157     throw "There should be at least one clause in the 'case' expression:\n"
   1158       + d.getAsString();
   1159 
   1160   // Main loop.
   1161   bool even = false;
   1162   const unsigned numArgs = d.getNumArgs();
   1163   unsigned i = 1;
   1164   for (DagInit::const_arg_iterator B = d.arg_begin(), E = d.arg_end();
   1165        B != E; ++B) {
   1166     Init* arg = *B;
   1167 
   1168     if (!even)
   1169     {
   1170       // Handle test.
   1171       const DagInit& Test = InitPtrToDag(arg);
   1172 
   1173       if (GetOperatorName(Test) == "default" && (i+1 != numArgs))
   1174         throw "The 'default' clause should be the last in the "
   1175           "'case' construct!";
   1176       if (i == numArgs)
   1177         throw "Case construct handler: no corresponding action "
   1178           "found for the test " + Test.getAsString() + '!';
   1179 
   1180       TestCallback(Test, IndentLevel, (i == 1));
   1181     }
   1182     else
   1183     {
   1184       if (dynamic_cast<DagInit*>(arg)
   1185           && GetOperatorName(static_cast<DagInit&>(*arg)) == "case") {
   1186         // Nested 'case'.
   1187         WalkCase(arg, TestCallback, StatementCallback, IndentLevel + Indent1);
   1188       }
   1189 
   1190       // Handle statement.
   1191       StatementCallback(arg, IndentLevel);
   1192     }
   1193 
   1194     ++i;
   1195     even = !even;
   1196   }
   1197 }
   1198 
   1199 /// ExtractOptionNames - A helper function object used by
   1200 /// CheckForSuperfluousOptions() to walk the 'case' DAG.
   1201 class ExtractOptionNames {
   1202   llvm::StringSet<>& OptionNames_;
   1203 
   1204   void processDag(const Init* Statement) {
   1205     const DagInit& Stmt = InitPtrToDag(Statement);
   1206     const std::string& ActionName = GetOperatorName(Stmt);
   1207     if (ActionName == "forward" || ActionName == "forward_as" ||
   1208         ActionName == "forward_value" ||
   1209         ActionName == "forward_transformed_value" ||
   1210         ActionName == "parameter_equals" || ActionName == "element_in_list") {
   1211       CheckNumberOfArguments(Stmt, 1);
   1212 
   1213       Init* Arg = Stmt.getArg(0);
   1214       if (typeid(*Arg) == typeid(StringInit))
   1215         OptionNames_.insert(InitPtrToString(Arg));
   1216     }
   1217     else if (ActionName == "any_switch_on" || ActionName == "switch_on" ||
   1218              ActionName == "any_not_empty" || ActionName == "any_empty" ||
   1219              ActionName == "not_empty" || ActionName == "empty") {
   1220       for (unsigned i = 0, NumArgs = Stmt.getNumArgs(); i < NumArgs; ++i) {
   1221         Init* Arg = Stmt.getArg(i);
   1222         if (typeid(*Arg) == typeid(StringInit))
   1223           OptionNames_.insert(InitPtrToString(Arg));
   1224       }
   1225     }
   1226     else if (ActionName == "and" || ActionName == "or" || ActionName == "not") {
   1227       for (unsigned i = 0, NumArgs = Stmt.getNumArgs(); i < NumArgs; ++i) {
   1228         this->processDag(Stmt.getArg(i));
   1229       }
   1230     }
   1231   }
   1232 
   1233 public:
   1234   ExtractOptionNames(llvm::StringSet<>& OptionNames) : OptionNames_(OptionNames)
   1235   {}
   1236 
   1237   void operator()(const Init* Statement) {
   1238     // Statement is either a dag, or a list of dags.
   1239     if (typeid(*Statement) == typeid(ListInit)) {
   1240       const ListInit& DagList = *static_cast<const ListInit*>(Statement);
   1241       for (ListInit::const_iterator B = DagList.begin(), E = DagList.end();
   1242            B != E; ++B)
   1243         this->processDag(*B);
   1244     }
   1245     else {
   1246       this->processDag(Statement);
   1247     }
   1248   }
   1249 
   1250   void operator()(const DagInit& Test, unsigned, bool) {
   1251     this->operator()(&Test);
   1252   }
   1253   void operator()(const Init* Statement, unsigned) {
   1254     this->operator()(Statement);
   1255   }
   1256 };
   1257 
   1258 /// IsOptionalEdge - Validate that the 'optional_edge' has proper structure.
   1259 bool IsOptionalEdge (const DagInit& Edg) {
   1260   return (GetOperatorName(Edg) == "optional_edge") && (Edg.getNumArgs() > 2);
   1261 }
   1262 
   1263 /// CheckForSuperfluousOptions - Check that there are no side
   1264 /// effect-free options (specified only in the OptionList). Otherwise,
   1265 /// output a warning.
   1266 void CheckForSuperfluousOptions (const DagVector& EdgeVector,
   1267                                  const ToolDescriptions& ToolDescs,
   1268                                  const OptionDescriptions& OptDescs) {
   1269   llvm::StringSet<> nonSuperfluousOptions;
   1270 
   1271   // Add all options mentioned in the ToolDesc.Actions to the set of
   1272   // non-superfluous options.
   1273   for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
   1274          E = ToolDescs.end(); B != E; ++B) {
   1275     const ToolDescription& TD = *(*B);
   1276     ExtractOptionNames Callback(nonSuperfluousOptions);
   1277     if (TD.Actions)
   1278       WalkCase(TD.Actions, Callback, Callback);
   1279   }
   1280 
   1281   // Add all options mentioned in the 'case' clauses of the
   1282   // OptionalEdges of the compilation graph to the set of
   1283   // non-superfluous options.
   1284   for (DagVector::const_iterator B = EdgeVector.begin(),
   1285          E = EdgeVector.end(); B != E; ++B) {
   1286     const DagInit& Edge = **B;
   1287     if (IsOptionalEdge(Edge)) {
   1288       const DagInit& Weight = InitPtrToDag(Edge.getArg(2));
   1289       WalkCase(&Weight, ExtractOptionNames(nonSuperfluousOptions), Id());
   1290     }
   1291   }
   1292 
   1293   // Check that all options in OptDescs belong to the set of
   1294   // non-superfluous options.
   1295   for (OptionDescriptions::const_iterator B = OptDescs.begin(),
   1296          E = OptDescs.end(); B != E; ++B) {
   1297     const OptionDescription& Val = B->second;
   1298     if (!nonSuperfluousOptions.count(Val.Name)
   1299         && Val.Type != OptionType::Alias)
   1300       llvm::errs() << "Warning: option '-" << Val.Name << "' has no effect! "
   1301         "Probable cause: this option is specified only in the OptionList.\n";
   1302   }
   1303 }
   1304 
   1305 /// EmitCaseTest0Args - Helper function used by EmitCaseConstructHandler().
   1306 bool EmitCaseTest0Args(const std::string& TestName, raw_ostream& O) {
   1307   if (TestName == "single_input_file") {
   1308     O << "InputFilenames.size() == 1";
   1309     return true;
   1310   }
   1311   else if (TestName == "multiple_input_files") {
   1312     O << "InputFilenames.size() > 1";
   1313     return true;
   1314   }
   1315 
   1316   return false;
   1317 }
   1318 
   1319 /// EmitMultipleArgumentTest - Helper function used by
   1320 /// EmitCaseTestMultipleArgs()
   1321 template <typename F>
   1322 void EmitMultipleArgumentTest(const DagInit& D, const char* LogicOp,
   1323                               F Callback, raw_ostream& O)
   1324 {
   1325   for (unsigned i = 0, NumArgs = D.getNumArgs(); i < NumArgs; ++i) {
   1326     if (i != 0)
   1327        O << ' ' << LogicOp << ' ';
   1328     Callback(InitPtrToString(D.getArg(i)), O);
   1329   }
   1330 }
   1331 
   1332 // Callbacks for use with EmitMultipleArgumentTest
   1333 
   1334 class EmitSwitchOn {
   1335   const OptionDescriptions& OptDescs_;
   1336 public:
   1337   EmitSwitchOn(const OptionDescriptions& OptDescs) : OptDescs_(OptDescs)
   1338   {}
   1339 
   1340   void operator()(const std::string& OptName, raw_ostream& O) const {
   1341     const OptionDescription& OptDesc = OptDescs_.FindSwitch(OptName);
   1342     O << OptDesc.GenVariableName();
   1343   }
   1344 };
   1345 
   1346 class EmitEmptyTest {
   1347   bool EmitNegate_;
   1348   const OptionDescriptions& OptDescs_;
   1349 public:
   1350   EmitEmptyTest(bool EmitNegate, const OptionDescriptions& OptDescs)
   1351     : EmitNegate_(EmitNegate), OptDescs_(OptDescs)
   1352   {}
   1353 
   1354   void operator()(const std::string& OptName, raw_ostream& O) const {
   1355     const char* Neg = (EmitNegate_ ? "!" : "");
   1356     if (OptName == "o") {
   1357       O << Neg << "OutputFilename.empty()";
   1358     }
   1359     else if (OptName == "save-temps") {
   1360       O << Neg << "(SaveTemps == SaveTempsEnum::Unset)";
   1361     }
   1362     else {
   1363       const OptionDescription& OptDesc = OptDescs_.FindListOrParameter(OptName);
   1364       O << Neg << OptDesc.GenVariableName() << ".empty()";
   1365     }
   1366   }
   1367 };
   1368 
   1369 
   1370 /// EmitCaseTestMultipleArgs - Helper function used by EmitCaseTest1Arg()
   1371 bool EmitCaseTestMultipleArgs (const std::string& TestName,
   1372                                const DagInit& d,
   1373                                const OptionDescriptions& OptDescs,
   1374                                raw_ostream& O) {
   1375   if (TestName == "any_switch_on") {
   1376     EmitMultipleArgumentTest(d, "||", EmitSwitchOn(OptDescs), O);
   1377     return true;
   1378   }
   1379   else if (TestName == "switch_on") {
   1380     EmitMultipleArgumentTest(d, "&&", EmitSwitchOn(OptDescs), O);
   1381     return true;
   1382   }
   1383   else if (TestName == "any_not_empty") {
   1384     EmitMultipleArgumentTest(d, "||", EmitEmptyTest(true, OptDescs), O);
   1385     return true;
   1386   }
   1387   else if (TestName == "any_empty") {
   1388     EmitMultipleArgumentTest(d, "||", EmitEmptyTest(false, OptDescs), O);
   1389     return true;
   1390   }
   1391   else if (TestName == "not_empty") {
   1392     EmitMultipleArgumentTest(d, "&&", EmitEmptyTest(true, OptDescs), O);
   1393     return true;
   1394   }
   1395   else if (TestName == "empty") {
   1396     EmitMultipleArgumentTest(d, "&&", EmitEmptyTest(false, OptDescs), O);
   1397     return true;
   1398   }
   1399 
   1400   return false;
   1401 }
   1402 
   1403 /// EmitCaseTest1Arg - Helper function used by EmitCaseTest1OrMoreArgs()
   1404 bool EmitCaseTest1Arg (const std::string& TestName,
   1405                        const DagInit& d,
   1406                        const OptionDescriptions& OptDescs,
   1407                        raw_ostream& O) {
   1408   const std::string& Arg = InitPtrToString(d.getArg(0));
   1409 
   1410   if (TestName == "input_languages_contain") {
   1411     O << "InLangs.count(\"" << Arg << "\") != 0";
   1412     return true;
   1413   }
   1414   else if (TestName == "in_language") {
   1415     // This works only for single-argument Tool::GenerateAction. Join
   1416     // tools can process several files in different languages simultaneously.
   1417 
   1418     // TODO: make this work with Edge::Weight (if possible).
   1419     O << "LangMap.GetLanguage(inFile) == \"" << Arg << '\"';
   1420     return true;
   1421   }
   1422 
   1423   return false;
   1424 }
   1425 
   1426 /// EmitCaseTest1OrMoreArgs - Helper function used by
   1427 /// EmitCaseConstructHandler()
   1428 bool EmitCaseTest1OrMoreArgs(const std::string& TestName,
   1429                              const DagInit& d,
   1430                              const OptionDescriptions& OptDescs,
   1431                              raw_ostream& O) {
   1432   CheckNumberOfArguments(d, 1);
   1433   return EmitCaseTest1Arg(TestName, d, OptDescs, O) ||
   1434     EmitCaseTestMultipleArgs(TestName, d, OptDescs, O);
   1435 }
   1436 
   1437 /// EmitCaseTest2Args - Helper function used by EmitCaseConstructHandler().
   1438 bool EmitCaseTest2Args(const std::string& TestName,
   1439                        const DagInit& d,
   1440                        unsigned IndentLevel,
   1441                        const OptionDescriptions& OptDescs,
   1442                        raw_ostream& O) {
   1443   CheckNumberOfArguments(d, 2);
   1444   const std::string& OptName = InitPtrToString(d.getArg(0));
   1445   const std::string& OptArg = InitPtrToString(d.getArg(1));
   1446 
   1447   if (TestName == "parameter_equals") {
   1448     const OptionDescription& OptDesc = OptDescs.FindParameter(OptName);
   1449     O << OptDesc.GenVariableName() << " == \"" << OptArg << "\"";
   1450     return true;
   1451   }
   1452   else if (TestName == "element_in_list") {
   1453     const OptionDescription& OptDesc = OptDescs.FindParameterList(OptName);
   1454     const std::string& VarName = OptDesc.GenVariableName();
   1455     O << "std::find(" << VarName << ".begin(),\n";
   1456     O.indent(IndentLevel + Indent1)
   1457       << VarName << ".end(), \""
   1458       << OptArg << "\") != " << VarName << ".end()";
   1459     return true;
   1460   }
   1461 
   1462   return false;
   1463 }
   1464 
   1465 // Forward declaration.
   1466 // EmitLogicalOperationTest and EmitCaseTest are mutually recursive.
   1467 void EmitCaseTest(const DagInit& d, unsigned IndentLevel,
   1468                   const OptionDescriptions& OptDescs,
   1469                   raw_ostream& O);
   1470 
   1471 /// EmitLogicalOperationTest - Helper function used by
   1472 /// EmitCaseConstructHandler.
   1473 void EmitLogicalOperationTest(const DagInit& d, const char* LogicOp,
   1474                               unsigned IndentLevel,
   1475                               const OptionDescriptions& OptDescs,
   1476                               raw_ostream& O) {
   1477   O << '(';
   1478   for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) {
   1479     const DagInit& InnerTest = InitPtrToDag(d.getArg(i));
   1480     EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
   1481     if (i != NumArgs - 1) {
   1482       O << ")\n";
   1483       O.indent(IndentLevel + Indent1) << ' ' << LogicOp << " (";
   1484     }
   1485     else {
   1486       O << ')';
   1487     }
   1488   }
   1489 }
   1490 
   1491 void EmitLogicalNot(const DagInit& d, unsigned IndentLevel,
   1492                     const OptionDescriptions& OptDescs, raw_ostream& O)
   1493 {
   1494   CheckNumberOfArguments(d, 1);
   1495   const DagInit& InnerTest = InitPtrToDag(d.getArg(0));
   1496   O << "! (";
   1497   EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
   1498   O << ")";
   1499 }
   1500 
   1501 /// EmitCaseTest - Helper function used by EmitCaseConstructHandler.
   1502 void EmitCaseTest(const DagInit& d, unsigned IndentLevel,
   1503                   const OptionDescriptions& OptDescs,
   1504                   raw_ostream& O) {
   1505   const std::string& TestName = GetOperatorName(d);
   1506 
   1507   if (TestName == "and")
   1508     EmitLogicalOperationTest(d, "&&", IndentLevel, OptDescs, O);
   1509   else if (TestName == "or")
   1510     EmitLogicalOperationTest(d, "||", IndentLevel, OptDescs, O);
   1511   else if (TestName == "not")
   1512     EmitLogicalNot(d, IndentLevel, OptDescs, O);
   1513   else if (EmitCaseTest0Args(TestName, O))
   1514     return;
   1515   else if (EmitCaseTest1OrMoreArgs(TestName, d, OptDescs, O))
   1516     return;
   1517   else if (EmitCaseTest2Args(TestName, d, IndentLevel, OptDescs, O))
   1518     return;
   1519   else
   1520     throw "Unknown test '" + TestName + "' used in the 'case' construct!";
   1521 }
   1522 
   1523 
   1524 /// EmitCaseTestCallback - Callback used by EmitCaseConstructHandler.
   1525 class EmitCaseTestCallback {
   1526   bool EmitElseIf_;
   1527   const OptionDescriptions& OptDescs_;
   1528   raw_ostream& O_;
   1529 public:
   1530 
   1531   EmitCaseTestCallback(bool EmitElseIf,
   1532                        const OptionDescriptions& OptDescs, raw_ostream& O)
   1533     : EmitElseIf_(EmitElseIf), OptDescs_(OptDescs), O_(O)
   1534   {}
   1535 
   1536   void operator()(const DagInit& Test, unsigned IndentLevel, bool FirstTest)
   1537   {
   1538     if (GetOperatorName(Test) == "default") {
   1539       O_.indent(IndentLevel) << "else {\n";
   1540     }
   1541     else {
   1542       O_.indent(IndentLevel)
   1543         << ((!FirstTest && EmitElseIf_) ? "else if (" : "if (");
   1544       EmitCaseTest(Test, IndentLevel, OptDescs_, O_);
   1545       O_ << ") {\n";
   1546     }
   1547   }
   1548 };
   1549 
   1550 /// EmitCaseStatementCallback - Callback used by EmitCaseConstructHandler.
   1551 template <typename F>
   1552 class EmitCaseStatementCallback {
   1553   F Callback_;
   1554   raw_ostream& O_;
   1555 public:
   1556 
   1557   EmitCaseStatementCallback(F Callback, raw_ostream& O)
   1558     : Callback_(Callback), O_(O)
   1559   {}
   1560 
   1561   void operator() (const Init* Statement, unsigned IndentLevel) {
   1562     // Is this a nested 'case'?
   1563     bool IsCase = dynamic_cast<const DagInit*>(Statement) &&
   1564       GetOperatorName(static_cast<const DagInit&>(*Statement)) == "case";
   1565 
   1566     // If so, ignore it, it is handled by our caller, WalkCase.
   1567     if (!IsCase) {
   1568       if (typeid(*Statement) == typeid(ListInit)) {
   1569         const ListInit& DagList = *static_cast<const ListInit*>(Statement);
   1570         for (ListInit::const_iterator B = DagList.begin(), E = DagList.end();
   1571              B != E; ++B)
   1572           Callback_(*B, (IndentLevel + Indent1), O_);
   1573       }
   1574       else {
   1575         Callback_(Statement, (IndentLevel + Indent1), O_);
   1576       }
   1577     }
   1578     O_.indent(IndentLevel) << "}\n";
   1579   }
   1580 
   1581 };
   1582 
   1583 /// EmitCaseConstructHandler - Emit code that handles the 'case'
   1584 /// construct. Takes a function object that should emit code for every case
   1585 /// clause. Implemented on top of WalkCase.
   1586 /// Callback's type is void F(const Init* Statement, unsigned IndentLevel,
   1587 /// raw_ostream& O).
   1588 /// EmitElseIf parameter controls the type of condition that is emitted ('if
   1589 /// (..) {..} else if (..) {} .. else {..}' vs. 'if (..) {..} if(..)  {..}
   1590 /// .. else {..}').
   1591 template <typename F>
   1592 void EmitCaseConstructHandler(const Init* Case, unsigned IndentLevel,
   1593                               F Callback, bool EmitElseIf,
   1594                               const OptionDescriptions& OptDescs,
   1595                               raw_ostream& O) {
   1596   WalkCase(Case, EmitCaseTestCallback(EmitElseIf, OptDescs, O),
   1597            EmitCaseStatementCallback<F>(Callback, O), IndentLevel);
   1598 }
   1599 
   1600 /// TokenizeCmdLine - converts from
   1601 /// "$CALL(HookName, 'Arg1', 'Arg2')/path -arg1 -arg2" to
   1602 /// ["$CALL(", "HookName", "Arg1", "Arg2", ")/path", "-arg1", "-arg2"].
   1603 void TokenizeCmdLine(const std::string& CmdLine, StrVector& Out) {
   1604   const char* Delimiters = " \t\n\v\f\r";
   1605   enum TokenizerState
   1606   { Normal, SpecialCommand, InsideSpecialCommand, InsideQuotationMarks }
   1607   cur_st  = Normal;
   1608 
   1609   if (CmdLine.empty())
   1610     return;
   1611   Out.push_back("");
   1612 
   1613   std::string::size_type B = CmdLine.find_first_not_of(Delimiters),
   1614     E = CmdLine.size();
   1615 
   1616   for (; B != E; ++B) {
   1617     char cur_ch = CmdLine[B];
   1618 
   1619     switch (cur_st) {
   1620     case Normal:
   1621       if (cur_ch == '$') {
   1622         cur_st = SpecialCommand;
   1623         break;
   1624       }
   1625       if (OneOf(Delimiters, cur_ch)) {
   1626         // Skip whitespace
   1627         B = CmdLine.find_first_not_of(Delimiters, B);
   1628         if (B == std::string::npos) {
   1629           B = E-1;
   1630           continue;
   1631         }
   1632         --B;
   1633         Out.push_back("");
   1634         continue;
   1635       }
   1636       break;
   1637 
   1638 
   1639     case SpecialCommand:
   1640       if (OneOf(Delimiters, cur_ch)) {
   1641         cur_st = Normal;
   1642         Out.push_back("");
   1643         continue;
   1644       }
   1645       if (cur_ch == '(') {
   1646         Out.push_back("");
   1647         cur_st = InsideSpecialCommand;
   1648         continue;
   1649       }
   1650       break;
   1651 
   1652     case InsideSpecialCommand:
   1653       if (OneOf(Delimiters, cur_ch)) {
   1654         continue;
   1655       }
   1656       if (cur_ch == '\'') {
   1657         cur_st = InsideQuotationMarks;
   1658         Out.push_back("");
   1659         continue;
   1660       }
   1661       if (cur_ch == ')') {
   1662         cur_st = Normal;
   1663         Out.push_back("");
   1664       }
   1665       if (cur_ch == ',') {
   1666         continue;
   1667       }
   1668 
   1669       break;
   1670 
   1671     case InsideQuotationMarks:
   1672       if (cur_ch == '\'') {
   1673         cur_st = InsideSpecialCommand;
   1674         continue;
   1675       }
   1676       break;
   1677     }
   1678 
   1679     Out.back().push_back(cur_ch);
   1680   }
   1681 }
   1682 
   1683 /// SubstituteCall - Given "$CALL(HookName, [Arg1 [, Arg2 [...]]])", output
   1684 /// "hooks::HookName([Arg1 [, Arg2 [, ...]]])". Helper function used by
   1685 /// SubstituteSpecialCommands().
   1686 StrVector::const_iterator
   1687 SubstituteCall (StrVector::const_iterator Pos,
   1688                 StrVector::const_iterator End,
   1689                 bool IsJoin, raw_ostream& O)
   1690 {
   1691   const char* errorMessage = "Syntax error in $CALL invocation!";
   1692   CheckedIncrement(Pos, End, errorMessage);
   1693   const std::string& CmdName = *Pos;
   1694 
   1695   if (CmdName == ")")
   1696     throw "$CALL invocation: empty argument list!";
   1697 
   1698   O << "hooks::";
   1699   O << CmdName << "(";
   1700 
   1701 
   1702   bool firstIteration = true;
   1703   while (true) {
   1704     CheckedIncrement(Pos, End, errorMessage);
   1705     const std::string& Arg = *Pos;
   1706     assert(Arg.size() != 0);
   1707 
   1708     if (Arg[0] == ')')
   1709       break;
   1710 
   1711     if (firstIteration)
   1712       firstIteration = false;
   1713     else
   1714       O << ", ";
   1715 
   1716     if (Arg == "$INFILE") {
   1717       if (IsJoin)
   1718         throw "$CALL(Hook, $INFILE) can't be used with a Join tool!";
   1719       else
   1720         O << "inFile.c_str()";
   1721     }
   1722     else {
   1723       O << '"' << Arg << '"';
   1724     }
   1725   }
   1726 
   1727   O << ')';
   1728 
   1729   return Pos;
   1730 }
   1731 
   1732 /// SubstituteEnv - Given '$ENV(VAR_NAME)', output 'getenv("VAR_NAME")'. Helper
   1733 /// function used by SubstituteSpecialCommands().
   1734 StrVector::const_iterator
   1735 SubstituteEnv (StrVector::const_iterator Pos,
   1736                StrVector::const_iterator End, raw_ostream& O)
   1737 {
   1738   const char* errorMessage = "Syntax error in $ENV invocation!";
   1739   CheckedIncrement(Pos, End, errorMessage);
   1740   const std::string& EnvName = *Pos;
   1741 
   1742   if (EnvName == ")")
   1743     throw "$ENV invocation: empty argument list!";
   1744 
   1745   O << "checkCString(std::getenv(\"";
   1746   O << EnvName;
   1747   O << "\"))";
   1748 
   1749   CheckedIncrement(Pos, End, errorMessage);
   1750 
   1751   return Pos;
   1752 }
   1753 
   1754 /// SubstituteSpecialCommands - Given an invocation of $CALL or $ENV, output
   1755 /// handler code. Helper function used by EmitCmdLineVecFill().
   1756 StrVector::const_iterator
   1757 SubstituteSpecialCommands (StrVector::const_iterator Pos,
   1758                            StrVector::const_iterator End,
   1759                            bool IsJoin, raw_ostream& O)
   1760 {
   1761 
   1762   const std::string& cmd = *Pos;
   1763 
   1764   // Perform substitution.
   1765   if (cmd == "$CALL") {
   1766     Pos = SubstituteCall(Pos, End, IsJoin, O);
   1767   }
   1768   else if (cmd == "$ENV") {
   1769     Pos = SubstituteEnv(Pos, End, O);
   1770   }
   1771   else {
   1772     throw "Unknown special command: " + cmd;
   1773   }
   1774 
   1775   // Handle '$CMD(ARG)/additional/text'.
   1776   const std::string& Leftover = *Pos;
   1777   assert(Leftover.at(0) == ')');
   1778   if (Leftover.size() != 1)
   1779     O << " + std::string(\"" << (Leftover.c_str() + 1) << "\")";
   1780 
   1781   return Pos;
   1782 }
   1783 
   1784 /// EmitCmdLineVecFill - Emit code that fills in the command line
   1785 /// vector. Helper function used by EmitGenerateActionMethod().
   1786 void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName,
   1787                         bool IsJoin, unsigned IndentLevel,
   1788                         raw_ostream& O) {
   1789   StrVector StrVec;
   1790   TokenizeCmdLine(InitPtrToString(CmdLine), StrVec);
   1791 
   1792   if (StrVec.empty())
   1793     throw "Tool '" + ToolName + "' has empty command line!";
   1794 
   1795   StrVector::const_iterator B = StrVec.begin(), E = StrVec.end();
   1796 
   1797   // Emit the command itself.
   1798   assert(!StrVec[0].empty());
   1799   O.indent(IndentLevel) << "cmd = ";
   1800   if (StrVec[0][0] == '$') {
   1801     B = SubstituteSpecialCommands(B, E, IsJoin, O);
   1802     ++B;
   1803   }
   1804   else {
   1805     O << '"' << StrVec[0] << '"';
   1806     ++B;
   1807   }
   1808   O << ";\n";
   1809 
   1810   // Go through the command arguments.
   1811   assert(B <= E);
   1812   for (; B != E; ++B) {
   1813     const std::string& cmd = *B;
   1814 
   1815     assert(!cmd.empty());
   1816     O.indent(IndentLevel);
   1817 
   1818     if (cmd.at(0) == '$') {
   1819       O << "vec.push_back(std::make_pair(0, ";
   1820       B = SubstituteSpecialCommands(B, E, IsJoin, O);
   1821       O << "));\n";
   1822     }
   1823     else {
   1824       O << "vec.push_back(std::make_pair(0, \"" << cmd << "\"));\n";
   1825     }
   1826   }
   1827 
   1828 }
   1829 
   1830 /// EmitForEachListElementCycleHeader - Emit common code for iterating through
   1831 /// all elements of a list. Helper function used by
   1832 /// EmitForwardOptionPropertyHandlingCode.
   1833 void EmitForEachListElementCycleHeader (const OptionDescription& D,
   1834                                         unsigned IndentLevel,
   1835                                         raw_ostream& O) {
   1836   unsigned IndentLevel1 = IndentLevel + Indent1;
   1837 
   1838   O.indent(IndentLevel)
   1839     << "for (" << D.GenTypeDeclaration()
   1840     << "::iterator B = " << D.GenVariableName() << ".begin(),\n";
   1841   O.indent(IndentLevel)
   1842     << "E = " << D.GenVariableName() << ".end(); B != E;) {\n";
   1843   O.indent(IndentLevel1) << "unsigned pos = " << D.GenVariableName()
   1844                          << ".getPosition(B - " << D.GenVariableName()
   1845                          << ".begin());\n";
   1846 }
   1847 
   1848 /// EmitForwardOptionPropertyHandlingCode - Helper function used to
   1849 /// implement EmitActionHandler. Emits code for
   1850 /// handling the (forward) and (forward_as) option properties.
   1851 void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
   1852                                             unsigned IndentLevel,
   1853                                             const std::string& NewName,
   1854                                             raw_ostream& O) {
   1855   const std::string& Name = NewName.empty()
   1856     ? ("-" + D.Name)
   1857     : NewName;
   1858   unsigned IndentLevel1 = IndentLevel + Indent1;
   1859 
   1860   switch (D.Type) {
   1861   case OptionType::Switch:
   1862     O.indent(IndentLevel)
   1863       << "vec.push_back(std::make_pair(" << D.GenVariableName()
   1864       << ".getPosition(), \"" << Name << "\"));\n";
   1865     break;
   1866   case OptionType::Parameter:
   1867     O.indent(IndentLevel) << "vec.push_back(std::make_pair("
   1868                           << D.GenVariableName()
   1869                           <<".getPosition(), \"" << Name;
   1870 
   1871     if (!D.isForwardNotSplit()) {
   1872       O << "\"));\n";
   1873       O.indent(IndentLevel) << "vec.push_back(std::make_pair("
   1874                             << D.GenVariableName() << ".getPosition(), "
   1875                             << D.GenVariableName() << "));\n";
   1876     }
   1877     else {
   1878       O << "=\" + " << D.GenVariableName() << "));\n";
   1879     }
   1880     break;
   1881   case OptionType::Prefix:
   1882     O.indent(IndentLevel) << "vec.push_back(std::make_pair("
   1883                           << D.GenVariableName() << ".getPosition(), \""
   1884                           << Name << "\" + "
   1885                           << D.GenVariableName() << "));\n";
   1886     break;
   1887   case OptionType::PrefixList:
   1888     EmitForEachListElementCycleHeader(D, IndentLevel, O);
   1889     O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
   1890                            << Name << "\" + " << "*B));\n";
   1891     O.indent(IndentLevel1) << "++B;\n";
   1892 
   1893     for (int i = 1, j = D.MultiVal; i < j; ++i) {
   1894       O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, *B));\n";
   1895       O.indent(IndentLevel1) << "++B;\n";
   1896     }
   1897 
   1898     O.indent(IndentLevel) << "}\n";
   1899     break;
   1900   case OptionType::ParameterList:
   1901     EmitForEachListElementCycleHeader(D, IndentLevel, O);
   1902     O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
   1903                            << Name << "\"));\n";
   1904 
   1905     for (int i = 0, j = D.MultiVal; i < j; ++i) {
   1906       O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, *B));\n";
   1907       O.indent(IndentLevel1) << "++B;\n";
   1908     }
   1909 
   1910     O.indent(IndentLevel) << "}\n";
   1911     break;
   1912   case OptionType::SwitchList:
   1913     EmitForEachListElementCycleHeader(D, IndentLevel, O);
   1914     O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
   1915                            << Name << "\"));\n";
   1916     O.indent(IndentLevel1) << "++B;\n";
   1917     O.indent(IndentLevel) << "}\n";
   1918     break;
   1919   case OptionType::Alias:
   1920   default:
   1921     throw "Aliases are not allowed in tool option descriptions!";
   1922   }
   1923 }
   1924 
   1925 /// ActionHandlingCallbackBase - Base class of EmitActionHandlersCallback and
   1926 /// EmitPreprocessOptionsCallback.
   1927 struct ActionHandlingCallbackBase
   1928 {
   1929 
   1930   void onErrorDag(const DagInit& d,
   1931                   unsigned IndentLevel, raw_ostream& O) const
   1932   {
   1933     O.indent(IndentLevel)
   1934       << "PrintError(\""
   1935       << (d.getNumArgs() >= 1 ? InitPtrToString(d.getArg(0)) : "Unknown error!")
   1936       << "\");\n";
   1937     O.indent(IndentLevel) << "return 1;\n";
   1938   }
   1939 
   1940   void onWarningDag(const DagInit& d,
   1941                     unsigned IndentLevel, raw_ostream& O) const
   1942   {
   1943     CheckNumberOfArguments(d, 1);
   1944     O.indent(IndentLevel) << "llvm::errs() << \""
   1945                           << InitPtrToString(d.getArg(0)) << "\";\n";
   1946   }
   1947 
   1948 };
   1949 
   1950 /// EmitActionHandlersCallback - Emit code that handles actions. Used by
   1951 /// EmitGenerateActionMethod() as an argument to EmitCaseConstructHandler().
   1952 class EmitActionHandlersCallback;
   1953 
   1954 typedef void (EmitActionHandlersCallback::* EmitActionHandlersCallbackHandler)
   1955 (const DagInit&, unsigned, raw_ostream&) const;
   1956 
   1957 class EmitActionHandlersCallback :
   1958   public ActionHandlingCallbackBase,
   1959   public HandlerTable<EmitActionHandlersCallbackHandler>
   1960 {
   1961   typedef EmitActionHandlersCallbackHandler Handler;
   1962 
   1963   const OptionDescriptions& OptDescs;
   1964 
   1965   /// EmitHookInvocation - Common code for hook invocation from actions. Used by
   1966   /// onAppendCmd and onOutputSuffix.
   1967   void EmitHookInvocation(const std::string& Str,
   1968                           const char* BlockOpen, const char* BlockClose,
   1969                           unsigned IndentLevel, raw_ostream& O) const
   1970   {
   1971     StrVector Out;
   1972     TokenizeCmdLine(Str, Out);
   1973 
   1974     for (StrVector::const_iterator B = Out.begin(), E = Out.end();
   1975          B != E; ++B) {
   1976       const std::string& cmd = *B;
   1977 
   1978       O.indent(IndentLevel) << BlockOpen;
   1979 
   1980       if (cmd.at(0) == '$')
   1981         B = SubstituteSpecialCommands(B, E,  /* IsJoin = */ true, O);
   1982       else
   1983         O << '"' << cmd << '"';
   1984 
   1985       O << BlockClose;
   1986     }
   1987   }
   1988 
   1989   void onAppendCmd (const DagInit& Dag,
   1990                     unsigned IndentLevel, raw_ostream& O) const
   1991   {
   1992     CheckNumberOfArguments(Dag, 1);
   1993     this->EmitHookInvocation(InitPtrToString(Dag.getArg(0)),
   1994                              "vec.push_back(std::make_pair(65536, ", "));\n",
   1995                              IndentLevel, O);
   1996   }
   1997 
   1998   void onForward (const DagInit& Dag,
   1999                   unsigned IndentLevel, raw_ostream& O) const
   2000   {
   2001     CheckNumberOfArguments(Dag, 1);
   2002     const std::string& Name = InitPtrToString(Dag.getArg(0));
   2003     EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name),
   2004                                           IndentLevel, "", O);
   2005   }
   2006 
   2007   void onForwardAs (const DagInit& Dag,
   2008                     unsigned IndentLevel, raw_ostream& O) const
   2009   {
   2010     CheckNumberOfArguments(Dag, 2);
   2011     const std::string& Name = InitPtrToString(Dag.getArg(0));
   2012     const std::string& NewName = InitPtrToString(Dag.getArg(1));
   2013     EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name),
   2014                                           IndentLevel, NewName, O);
   2015   }
   2016 
   2017   void onForwardValue (const DagInit& Dag,
   2018                        unsigned IndentLevel, raw_ostream& O) const
   2019   {
   2020     CheckNumberOfArguments(Dag, 1);
   2021     const std::string& Name = InitPtrToString(Dag.getArg(0));
   2022     const OptionDescription& D = OptDescs.FindParameterListOrParameter(Name);
   2023 
   2024     if (D.isSwitchList()) {
   2025       throw std::runtime_error
   2026         ("forward_value is not allowed with switch_list");
   2027     }
   2028 
   2029     if (D.isParameter()) {
   2030       O.indent(IndentLevel) << "vec.push_back(std::make_pair("
   2031                             << D.GenVariableName() << ".getPosition(), "
   2032                             << D.GenVariableName() << "));\n";
   2033     }
   2034     else {
   2035       O.indent(IndentLevel) << "for (" << D.GenTypeDeclaration()
   2036                             << "::iterator B = " << D.GenVariableName()
   2037                             << ".begin(), \n";
   2038       O.indent(IndentLevel + Indent1) << " E = " << D.GenVariableName()
   2039                                       << ".end(); B != E; ++B)\n";
   2040       O.indent(IndentLevel) << "{\n";
   2041       O.indent(IndentLevel + Indent1)
   2042         << "unsigned pos = " << D.GenVariableName()
   2043         << ".getPosition(B - " << D.GenVariableName()
   2044         << ".begin());\n";
   2045       O.indent(IndentLevel + Indent1)
   2046         << "vec.push_back(std::make_pair(pos, *B));\n";
   2047       O.indent(IndentLevel) << "}\n";
   2048     }
   2049   }
   2050 
   2051   void onForwardTransformedValue (const DagInit& Dag,
   2052                                   unsigned IndentLevel, raw_ostream& O) const
   2053   {
   2054     CheckNumberOfArguments(Dag, 2);
   2055     const std::string& Name = InitPtrToString(Dag.getArg(0));
   2056     const std::string& Hook = InitPtrToString(Dag.getArg(1));
   2057     const OptionDescription& D = OptDescs.FindParameterListOrParameter(Name);
   2058 
   2059     O.indent(IndentLevel) << "vec.push_back(std::make_pair("
   2060                           << D.GenVariableName() << ".getPosition("
   2061                           << (D.isList() ? "0" : "") << "), "
   2062                           << "hooks::" << Hook << "(" << D.GenVariableName()
   2063                           << (D.isParameter() ? ".c_str()" : "") << ")));\n";
   2064   }
   2065 
   2066   void onNoOutFile (const DagInit& Dag,
   2067                     unsigned IndentLevel, raw_ostream& O) const
   2068   {
   2069     CheckNumberOfArguments(Dag, 0);
   2070     O.indent(IndentLevel) << "no_out_file = true;\n";
   2071   }
   2072 
   2073   void onOutputSuffix (const DagInit& Dag,
   2074                        unsigned IndentLevel, raw_ostream& O) const
   2075   {
   2076     CheckNumberOfArguments(Dag, 1);
   2077     this->EmitHookInvocation(InitPtrToString(Dag.getArg(0)),
   2078                              "output_suffix = ", ";\n", IndentLevel, O);
   2079   }
   2080 
   2081   void onStopCompilation (const DagInit& Dag,
   2082                           unsigned IndentLevel, raw_ostream& O) const
   2083   {
   2084     O.indent(IndentLevel) << "stop_compilation = true;\n";
   2085   }
   2086 
   2087 
   2088   void onUnpackValues (const DagInit& Dag,
   2089                        unsigned IndentLevel, raw_ostream& O) const
   2090   {
   2091     throw "'unpack_values' is deprecated. "
   2092       "Use 'comma_separated' + 'forward_value' instead!";
   2093   }
   2094 
   2095  public:
   2096 
   2097   explicit EmitActionHandlersCallback(const OptionDescriptions& OD)
   2098     : OptDescs(OD)
   2099   {
   2100     if (!staticMembersInitialized_) {
   2101       AddHandler("error", &EmitActionHandlersCallback::onErrorDag);
   2102       AddHandler("warning", &EmitActionHandlersCallback::onWarningDag);
   2103       AddHandler("append_cmd", &EmitActionHandlersCallback::onAppendCmd);
   2104       AddHandler("forward", &EmitActionHandlersCallback::onForward);
   2105       AddHandler("forward_as", &EmitActionHandlersCallback::onForwardAs);
   2106       AddHandler("forward_value", &EmitActionHandlersCallback::onForwardValue);
   2107       AddHandler("forward_transformed_value",
   2108                  &EmitActionHandlersCallback::onForwardTransformedValue);
   2109       AddHandler("no_out_file",
   2110                  &EmitActionHandlersCallback::onNoOutFile);
   2111       AddHandler("output_suffix", &EmitActionHandlersCallback::onOutputSuffix);
   2112       AddHandler("stop_compilation",
   2113                  &EmitActionHandlersCallback::onStopCompilation);
   2114       AddHandler("unpack_values",
   2115                  &EmitActionHandlersCallback::onUnpackValues);
   2116 
   2117 
   2118       staticMembersInitialized_ = true;
   2119     }
   2120   }
   2121 
   2122   void operator()(const Init* I,
   2123                   unsigned IndentLevel, raw_ostream& O) const
   2124   {
   2125     InvokeDagInitHandler(this, I, IndentLevel, O);
   2126   }
   2127 };
   2128 
   2129 void EmitGenerateActionMethodHeader(const ToolDescription& D,
   2130                                     bool IsJoin, bool Naked,
   2131                                     raw_ostream& O)
   2132 {
   2133   O.indent(Indent1) << "int GenerateAction(Action& Out,\n";
   2134 
   2135   if (IsJoin)
   2136     O.indent(Indent2) << "const PathVector& inFiles,\n";
   2137   else
   2138     O.indent(Indent2) << "const sys::Path& inFile,\n";
   2139 
   2140   O.indent(Indent2) << "const bool HasChildren,\n";
   2141   O.indent(Indent2) << "const llvm::sys::Path& TempDir,\n";
   2142   O.indent(Indent2) << "const InputLanguagesSet& InLangs,\n";
   2143   O.indent(Indent2) << "const LanguageMap& LangMap) const\n";
   2144   O.indent(Indent1) << "{\n";
   2145 
   2146   if (!Naked) {
   2147     O.indent(Indent2) << "std::string cmd;\n";
   2148     O.indent(Indent2) << "std::string out_file;\n";
   2149     O.indent(Indent2)
   2150       << "std::vector<std::pair<unsigned, std::string> > vec;\n";
   2151     O.indent(Indent2) << "bool stop_compilation = !HasChildren;\n";
   2152     O.indent(Indent2) << "bool no_out_file = false;\n";
   2153     O.indent(Indent2) << "std::string output_suffix(\""
   2154                       << D.OutputSuffix << "\");\n";
   2155   }
   2156 }
   2157 
   2158 // EmitGenerateActionMethod - Emit either a normal or a "join" version of the
   2159 // Tool::GenerateAction() method.
   2160 void EmitGenerateActionMethod (const ToolDescription& D,
   2161                                const OptionDescriptions& OptDescs,
   2162                                bool IsJoin, raw_ostream& O) {
   2163 
   2164   EmitGenerateActionMethodHeader(D, IsJoin, /* Naked = */ false, O);
   2165 
   2166   if (!D.CmdLine)
   2167     throw "Tool " + D.Name + " has no cmd_line property!";
   2168 
   2169   // Process the 'command' property.
   2170   O << '\n';
   2171   EmitCmdLineVecFill(D.CmdLine, D.Name, IsJoin, Indent2, O);
   2172   O << '\n';
   2173 
   2174   // Process the 'actions' list of this tool.
   2175   if (D.Actions)
   2176     EmitCaseConstructHandler(D.Actions, Indent2,
   2177                              EmitActionHandlersCallback(OptDescs),
   2178                              false, OptDescs, O);
   2179   O << '\n';
   2180 
   2181   // Input file (s)
   2182   if (!D.InFileOption.empty()) {
   2183     O.indent(Indent2)
   2184       << "vec.push_back(std::make_pair(InputFilenames.getPosition(0), \""
   2185       << D.InFileOption << "\");\n";
   2186   }
   2187 
   2188   if (IsJoin) {
   2189     O.indent(Indent2)
   2190       << "for (PathVector::const_iterator B = inFiles.begin(),\n";
   2191     O.indent(Indent3) << "E = inFiles.end(); B != E; ++B)\n";
   2192     O.indent(Indent2) << "{\n";
   2193     O.indent(Indent3) << "vec.push_back(std::make_pair("
   2194                       << "InputFilenames.getPosition(B - inFiles.begin()), "
   2195                       << "B->str()));\n";
   2196     O.indent(Indent2) << "}\n";
   2197   }
   2198   else {
   2199     O.indent(Indent2) << "vec.push_back(std::make_pair("
   2200                       << "InputFilenames.getPosition(0), inFile.str()));\n";
   2201   }
   2202 
   2203   // Output file
   2204   O.indent(Indent2) << "if (!no_out_file) {\n";
   2205   if (!D.OutFileOption.empty())
   2206     O.indent(Indent3) << "vec.push_back(std::make_pair(65536, \""
   2207                       << D.OutFileOption << "\"));\n";
   2208 
   2209   O.indent(Indent3) << "out_file = this->OutFilename("
   2210                     << (IsJoin ? "sys::Path(),\n" : "inFile,\n");
   2211   O.indent(Indent4) <<
   2212     "TempDir, stop_compilation, output_suffix.c_str()).str();\n\n";
   2213   O.indent(Indent3) << "vec.push_back(std::make_pair(65536, out_file));\n";
   2214 
   2215   O.indent(Indent2) << "}\n\n";
   2216 
   2217   // Handle the Sink property.
   2218   std::string SinkOption("autogenerated::");
   2219   SinkOption += SinkOptionName;
   2220   if (D.isSink()) {
   2221     O.indent(Indent2) << "if (!" << SinkOption << ".empty()) {\n";
   2222     O.indent(Indent3) << "for (cl::list<std::string>::iterator B = "
   2223                       << SinkOption << ".begin(), E = " << SinkOption
   2224                       << ".end(); B != E; ++B)\n";
   2225     O.indent(Indent4) << "vec.push_back(std::make_pair(" << SinkOption
   2226                       << ".getPosition(B - " << SinkOption
   2227                       <<  ".begin()), *B));\n";
   2228     O.indent(Indent2) << "}\n";
   2229   }
   2230 
   2231   O.indent(Indent2) << "Out.Construct(cmd, this->SortArgs(vec), "
   2232                     << "stop_compilation, out_file);\n";
   2233   O.indent(Indent2) << "return 0;\n";
   2234   O.indent(Indent1) << "}\n\n";
   2235 }
   2236 
   2237 /// EmitGenerateActionMethods - Emit two GenerateAction() methods for
   2238 /// a given Tool class.
   2239 void EmitGenerateActionMethods (const ToolDescription& ToolDesc,
   2240                                 const OptionDescriptions& OptDescs,
   2241                                 raw_ostream& O) {
   2242   if (!ToolDesc.isJoin()) {
   2243     EmitGenerateActionMethodHeader(ToolDesc, /* IsJoin = */ true,
   2244                                    /* Naked = */ true, O);
   2245     O.indent(Indent2) << "PrintError(\"" << ToolDesc.Name
   2246                       << " is not a Join tool!\");\n";
   2247     O.indent(Indent2) << "return -1;\n";
   2248     O.indent(Indent1) << "}\n\n";
   2249   }
   2250   else {
   2251     EmitGenerateActionMethod(ToolDesc, OptDescs, true, O);
   2252   }
   2253 
   2254   EmitGenerateActionMethod(ToolDesc, OptDescs, false, O);
   2255 }
   2256 
   2257 /// EmitInOutLanguageMethods - Emit the [Input,Output]Language()
   2258 /// methods for a given Tool class.
   2259 void EmitInOutLanguageMethods (const ToolDescription& D, raw_ostream& O) {
   2260   O.indent(Indent1) << "const char** InputLanguages() const {\n";
   2261   O.indent(Indent2) << "return InputLanguages_;\n";
   2262   O.indent(Indent1) << "}\n\n";
   2263 
   2264   O.indent(Indent1) << "const char** OutputLanguages() const {\n";
   2265   O.indent(Indent2) << "return OutputLanguages_;\n";
   2266   O.indent(Indent1) << "}\n\n";
   2267 }
   2268 
   2269 /// EmitNameMethod - Emit the Name() method for a given Tool class.
   2270 void EmitNameMethod (const ToolDescription& D, raw_ostream& O) {
   2271   O.indent(Indent1) << "const char* Name() const {\n";
   2272   O.indent(Indent2) << "return \"" << D.Name << "\";\n";
   2273   O.indent(Indent1) << "}\n\n";
   2274 }
   2275 
   2276 /// EmitIsJoinMethod - Emit the IsJoin() method for a given Tool
   2277 /// class.
   2278 void EmitIsJoinMethod (const ToolDescription& D, raw_ostream& O) {
   2279   O.indent(Indent1) << "bool IsJoin() const {\n";
   2280   if (D.isJoin())
   2281     O.indent(Indent2) << "return true;\n";
   2282   else
   2283     O.indent(Indent2) << "return false;\n";
   2284   O.indent(Indent1) << "}\n\n";
   2285 }
   2286 
   2287 /// EmitWorksOnEmptyCallback - Callback used by EmitWorksOnEmptyMethod in
   2288 /// conjunction with EmitCaseConstructHandler.
   2289 void EmitWorksOnEmptyCallback (const Init* Value,
   2290                                unsigned IndentLevel, raw_ostream& O) {
   2291   CheckBooleanConstant(Value);
   2292   O.indent(IndentLevel) << "return " << Value->getAsString() << ";\n";
   2293 }
   2294 
   2295 /// EmitWorksOnEmptyMethod - Emit the WorksOnEmpty() method for a given Tool
   2296 /// class.
   2297 void EmitWorksOnEmptyMethod (const ToolDescription& D,
   2298                              const OptionDescriptions& OptDescs,
   2299                              raw_ostream& O)
   2300 {
   2301   O.indent(Indent1) << "bool WorksOnEmpty() const {\n";
   2302   if (D.OnEmpty == 0)
   2303     O.indent(Indent2) << "return false;\n";
   2304   else
   2305     EmitCaseConstructHandler(D.OnEmpty, Indent2, EmitWorksOnEmptyCallback,
   2306                              /*EmitElseIf = */ true, OptDescs, O);
   2307   O.indent(Indent1) << "}\n\n";
   2308 }
   2309 
   2310 /// EmitStrArray - Emit definition of a 'const char**' static member
   2311 /// variable. Helper used by EmitStaticMemberDefinitions();
   2312 void EmitStrArray(const std::string& Name, const std::string& VarName,
   2313                   const StrVector& StrVec, raw_ostream& O) {
   2314   O << "const char* " << Name << "::" << VarName << "[] = {";
   2315   for (StrVector::const_iterator B = StrVec.begin(), E = StrVec.end();
   2316        B != E; ++B)
   2317     O << '\"' << *B << "\", ";
   2318   O << "0};\n";
   2319 }
   2320 
   2321 /// EmitStaticMemberDefinitions - Emit static member definitions for a
   2322 /// given Tool class.
   2323 void EmitStaticMemberDefinitions(const ToolDescription& D, raw_ostream& O) {
   2324   if (D.InLanguage.empty())
   2325     throw "Tool " + D.Name + " has no 'in_language' property!";
   2326   if (D.OutLanguage.empty())
   2327     throw "Tool " + D.Name + " has no 'out_language' property!";
   2328 
   2329   EmitStrArray(D.Name, "InputLanguages_", D.InLanguage, O);
   2330   EmitStrArray(D.Name, "OutputLanguages_", D.OutLanguage, O);
   2331   O << '\n';
   2332 }
   2333 
   2334 /// EmitToolClassDefinition - Emit a Tool class definition.
   2335 void EmitToolClassDefinition (const ToolDescription& D,
   2336                               const OptionDescriptions& OptDescs,
   2337                               raw_ostream& O) {
   2338   if (D.Name == "root")
   2339     return;
   2340 
   2341   // Header
   2342   O << "class " << D.Name << " : public ";
   2343   if (D.isJoin())
   2344     O << "JoinTool";
   2345   else
   2346     O << "Tool";
   2347 
   2348   O << " {\nprivate:\n";
   2349   O.indent(Indent1) << "static const char* InputLanguages_[];\n";
   2350   O.indent(Indent1) << "static const char* OutputLanguages_[];\n\n";
   2351 
   2352   O << "public:\n";
   2353   EmitNameMethod(D, O);
   2354   EmitInOutLanguageMethods(D, O);
   2355   EmitIsJoinMethod(D, O);
   2356   EmitWorksOnEmptyMethod(D, OptDescs, O);
   2357   EmitGenerateActionMethods(D, OptDescs, O);
   2358 
   2359   // Close class definition
   2360   O << "};\n";
   2361 
   2362   EmitStaticMemberDefinitions(D, O);
   2363 
   2364 }
   2365 
   2366 /// EmitOptionDefinitions - Iterate over a list of option descriptions
   2367 /// and emit registration code.
   2368 void EmitOptionDefinitions (const OptionDescriptions& descs,
   2369                             bool HasSink, raw_ostream& O)
   2370 {
   2371   std::vector<OptionDescription> Aliases;
   2372 
   2373   // Emit static cl::Option variables.
   2374   for (OptionDescriptions::const_iterator B = descs.begin(),
   2375          E = descs.end(); B!=E; ++B) {
   2376     const OptionDescription& val = B->second;
   2377 
   2378     if (val.Type == OptionType::Alias) {
   2379       Aliases.push_back(val);
   2380       continue;
   2381     }
   2382 
   2383     O << val.GenTypeDeclaration() << ' '
   2384       << val.GenPlainVariableName();
   2385 
   2386     O << "(\"" << val.Name << "\"\n";
   2387 
   2388     if (val.Type == OptionType::Prefix || val.Type == OptionType::PrefixList)
   2389       O << ", cl::Prefix";
   2390 
   2391     if (val.isRequired()) {
   2392       if (val.isList() && !val.isMultiVal())
   2393         O << ", cl::OneOrMore";
   2394       else
   2395         O << ", cl::Required";
   2396     }
   2397 
   2398     if (val.isOptional())
   2399         O << ", cl::Optional";
   2400 
   2401     if (val.isOneOrMore())
   2402         O << ", cl::OneOrMore";
   2403 
   2404     if (val.isZeroOrMore())
   2405         O << ", cl::ZeroOrMore";
   2406 
   2407     if (val.isReallyHidden())
   2408       O << ", cl::ReallyHidden";
   2409     else if (val.isHidden())
   2410       O << ", cl::Hidden";
   2411 
   2412     if (val.isCommaSeparated())
   2413       O << ", cl::CommaSeparated";
   2414 
   2415     if (val.MultiVal > 1)
   2416       O << ", cl::multi_val(" << val.MultiVal << ')';
   2417 
   2418     if (val.InitVal) {
   2419       const std::string& str = val.InitVal->getAsString();
   2420       O << ", cl::init(" << str << ')';
   2421     }
   2422 
   2423     if (!val.Help.empty())
   2424       O << ", cl::desc(\"" << val.Help << "\")";
   2425 
   2426     O << ");\n\n";
   2427   }
   2428 
   2429   // Emit the aliases (they should go after all the 'proper' options).
   2430   for (std::vector<OptionDescription>::const_iterator
   2431          B = Aliases.begin(), E = Aliases.end(); B != E; ++B) {
   2432     const OptionDescription& val = *B;
   2433 
   2434     O << val.GenTypeDeclaration() << ' '
   2435       << val.GenPlainVariableName()
   2436       << "(\"" << val.Name << '\"';
   2437 
   2438     const OptionDescription& D = descs.FindOption(val.Help);
   2439     O << ", cl::aliasopt(" << D.GenVariableName() << ")";
   2440 
   2441     O << ", cl::desc(\"" << "An alias for -" + val.Help  << "\"));\n";
   2442   }
   2443 
   2444   // Emit the sink option.
   2445   if (HasSink)
   2446     O << "cl::list<std::string> " << SinkOptionName << "(cl::Sink);\n";
   2447 
   2448   O << '\n';
   2449 }
   2450 
   2451 /// EmitPreprocessOptionsCallback - Helper function passed to
   2452 /// EmitCaseConstructHandler() by EmitPreprocessOptions().
   2453 
   2454 class EmitPreprocessOptionsCallback;
   2455 
   2456 typedef void
   2457 (EmitPreprocessOptionsCallback::* EmitPreprocessOptionsCallbackHandler)
   2458 (const DagInit&, unsigned, raw_ostream&) const;
   2459 
   2460 class EmitPreprocessOptionsCallback :
   2461   public ActionHandlingCallbackBase,
   2462   public HandlerTable<EmitPreprocessOptionsCallbackHandler>
   2463 {
   2464   typedef EmitPreprocessOptionsCallbackHandler Handler;
   2465   typedef void
   2466   (EmitPreprocessOptionsCallback::* HandlerImpl)
   2467   (const Init*, unsigned, raw_ostream&) const;
   2468 
   2469   const OptionDescriptions& OptDescs_;
   2470 
   2471   void onEachArgument(const DagInit& d, HandlerImpl h,
   2472                       unsigned IndentLevel, raw_ostream& O) const
   2473   {
   2474     CheckNumberOfArguments(d, 1);
   2475 
   2476     for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) {
   2477       ((this)->*(h))(d.getArg(i), IndentLevel, O);
   2478     }
   2479   }
   2480 
   2481   void onUnsetOptionImpl(const Init* I,
   2482                          unsigned IndentLevel, raw_ostream& O) const
   2483   {
   2484     const std::string& OptName = InitPtrToString(I);
   2485     const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
   2486 
   2487     if (OptDesc.isSwitch()) {
   2488       O.indent(IndentLevel) << OptDesc.GenVariableName() << " = false;\n";
   2489     }
   2490     else if (OptDesc.isParameter()) {
   2491       O.indent(IndentLevel) << OptDesc.GenVariableName() << " = \"\";\n";
   2492     }
   2493     else if (OptDesc.isList()) {
   2494       O.indent(IndentLevel) << OptDesc.GenVariableName() << ".clear();\n";
   2495     }
   2496     else {
   2497       throw "Can't apply 'unset_option' to alias option '" + OptName + "'!";
   2498     }
   2499   }
   2500 
   2501   void onUnsetOption(const DagInit& d,
   2502                      unsigned IndentLevel, raw_ostream& O) const
   2503   {
   2504     this->onEachArgument(d, &EmitPreprocessOptionsCallback::onUnsetOptionImpl,
   2505                          IndentLevel, O);
   2506   }
   2507 
   2508   void onSetOptionImpl(const DagInit& D,
   2509                        unsigned IndentLevel, raw_ostream& O) const {
   2510     CheckNumberOfArguments(D, 2);
   2511 
   2512     const std::string& OptName = InitPtrToString(D.getArg(0));
   2513     const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
   2514     const Init* Value = D.getArg(1);
   2515 
   2516     if (OptDesc.isList()) {
   2517       const ListInit& List = InitPtrToList(Value);
   2518 
   2519       O.indent(IndentLevel) << OptDesc.GenVariableName() << ".clear();\n";
   2520       for (ListInit::const_iterator B = List.begin(), E = List.end();
   2521            B != E; ++B) {
   2522         const Init* CurElem = *B;
   2523         if (OptDesc.isSwitchList())
   2524           CheckBooleanConstant(CurElem);
   2525 
   2526         O.indent(IndentLevel)
   2527           << OptDesc.GenVariableName() << ".push_back(\""
   2528           << (OptDesc.isSwitchList() ? CurElem->getAsString()
   2529               : InitPtrToString(CurElem))
   2530           << "\");\n";
   2531       }
   2532     }
   2533     else if (OptDesc.isSwitch()) {
   2534       CheckBooleanConstant(Value);
   2535       O.indent(IndentLevel) << OptDesc.GenVariableName()
   2536                             << " = " << Value->getAsString() << ";\n";
   2537     }
   2538     else if (OptDesc.isParameter()) {
   2539       const std::string& Str = InitPtrToString(Value);
   2540       O.indent(IndentLevel) << OptDesc.GenVariableName()
   2541                             << " = \"" << Str << "\";\n";
   2542     }
   2543     else {
   2544       throw "Can't apply 'set_option' to alias option '" + OptName + "'!";
   2545     }
   2546   }
   2547 
   2548   void onSetSwitch(const Init* I,
   2549                    unsigned IndentLevel, raw_ostream& O) const {
   2550     const std::string& OptName = InitPtrToString(I);
   2551     const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
   2552 
   2553     if (OptDesc.isSwitch())
   2554       O.indent(IndentLevel) << OptDesc.GenVariableName() << " = true;\n";
   2555     else
   2556       throw "set_option: -" + OptName + " is not a switch option!";
   2557   }
   2558 
   2559   void onSetOption(const DagInit& d,
   2560                    unsigned IndentLevel, raw_ostream& O) const
   2561   {
   2562     CheckNumberOfArguments(d, 1);
   2563 
   2564     // 2-argument form: (set_option "A", true), (set_option "B", "C"),
   2565     // (set_option "D", ["E", "F"])
   2566     if (d.getNumArgs() == 2) {
   2567       const OptionDescription& OptDesc =
   2568         OptDescs_.FindOption(InitPtrToString(d.getArg(0)));
   2569       const Init* Opt2 = d.getArg(1);
   2570 
   2571       if (!OptDesc.isSwitch() || typeid(*Opt2) != typeid(StringInit)) {
   2572         this->onSetOptionImpl(d, IndentLevel, O);
   2573         return;
   2574       }
   2575     }
   2576 
   2577     // Multiple argument form: (set_option "A"), (set_option "B", "C", "D")
   2578     this->onEachArgument(d, &EmitPreprocessOptionsCallback::onSetSwitch,
   2579                          IndentLevel, O);
   2580   }
   2581 
   2582 public:
   2583 
   2584   EmitPreprocessOptionsCallback(const OptionDescriptions& OptDescs)
   2585   : OptDescs_(OptDescs)
   2586   {
   2587     if (!staticMembersInitialized_) {
   2588       AddHandler("error", &EmitPreprocessOptionsCallback::onErrorDag);
   2589       AddHandler("warning", &EmitPreprocessOptionsCallback::onWarningDag);
   2590       AddHandler("unset_option", &EmitPreprocessOptionsCallback::onUnsetOption);
   2591       AddHandler("set_option", &EmitPreprocessOptionsCallback::onSetOption);
   2592 
   2593       staticMembersInitialized_ = true;
   2594     }
   2595   }
   2596 
   2597   void operator()(const Init* I,
   2598                   unsigned IndentLevel, raw_ostream& O) const
   2599   {
   2600     InvokeDagInitHandler(this, I, IndentLevel, O);
   2601   }
   2602 
   2603 };
   2604 
   2605 /// EmitPreprocessOptions - Emit the PreprocessOptions() function.
   2606 void EmitPreprocessOptions (const RecordKeeper& Records,
   2607                             const OptionDescriptions& OptDecs, raw_ostream& O)
   2608 {
   2609   O << "int PreprocessOptions () {\n";
   2610 
   2611   const RecordVector& OptionPreprocessors =
   2612     Records.getAllDerivedDefinitions("OptionPreprocessor");
   2613 
   2614   for (RecordVector::const_iterator B = OptionPreprocessors.begin(),
   2615          E = OptionPreprocessors.end(); B!=E; ++B) {
   2616     DagInit* Case = (*B)->getValueAsDag("preprocessor");
   2617     EmitCaseConstructHandler(Case, Indent1,
   2618                              EmitPreprocessOptionsCallback(OptDecs),
   2619                              false, OptDecs, O);
   2620   }
   2621 
   2622   O << '\n';
   2623   O.indent(Indent1) << "return 0;\n";
   2624   O << "}\n\n";
   2625 }
   2626 
   2627 class DoEmitPopulateLanguageMap;
   2628 typedef void (DoEmitPopulateLanguageMap::* DoEmitPopulateLanguageMapHandler)
   2629 (const DagInit& D);
   2630 
   2631 class DoEmitPopulateLanguageMap
   2632 : public HandlerTable<DoEmitPopulateLanguageMapHandler>
   2633 {
   2634 private:
   2635   raw_ostream& O_;
   2636 
   2637 public:
   2638 
   2639   explicit DoEmitPopulateLanguageMap (raw_ostream& O) : O_(O) {
   2640     if (!staticMembersInitialized_) {
   2641       AddHandler("lang_to_suffixes",
   2642                  &DoEmitPopulateLanguageMap::onLangToSuffixes);
   2643 
   2644       staticMembersInitialized_ = true;
   2645     }
   2646   }
   2647 
   2648   void operator() (Init* I) {
   2649     InvokeDagInitHandler(this, I);
   2650   }
   2651 
   2652 private:
   2653 
   2654   void onLangToSuffixes (const DagInit& d) {
   2655     CheckNumberOfArguments(d, 2);
   2656 
   2657     const std::string& Lang = InitPtrToString(d.getArg(0));
   2658     Init* Suffixes = d.getArg(1);
   2659 
   2660     // Second argument to lang_to_suffixes is either a single string...
   2661     if (typeid(*Suffixes) == typeid(StringInit)) {
   2662       O_.indent(Indent1) << "langMap[\"" << InitPtrToString(Suffixes)
   2663                          << "\"] = \"" << Lang << "\";\n";
   2664     }
   2665     // ...or a list of strings.
   2666     else {
   2667       const ListInit& Lst = InitPtrToList(Suffixes);
   2668       assert(Lst.size() != 0);
   2669       for (ListInit::const_iterator B = Lst.begin(), E = Lst.end();
   2670            B != E; ++B) {
   2671         O_.indent(Indent1) << "langMap[\"" << InitPtrToString(*B)
   2672                            << "\"] = \"" << Lang << "\";\n";
   2673       }
   2674     }
   2675   }
   2676 
   2677 };
   2678 
   2679 /// EmitPopulateLanguageMap - Emit the PopulateLanguageMap() function.
   2680 void EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O)
   2681 {
   2682   O << "int PopulateLanguageMap (LanguageMap& langMap) {\n";
   2683 
   2684   // For each LanguageMap:
   2685   const RecordVector& LangMaps =
   2686     Records.getAllDerivedDefinitions("LanguageMap");
   2687 
   2688   // Call DoEmitPopulateLanguageMap.
   2689   for (RecordVector::const_iterator B = LangMaps.begin(),
   2690          E = LangMaps.end(); B!=E; ++B) {
   2691     ListInit* LangMap = (*B)->getValueAsListInit("map");
   2692     std::for_each(LangMap->begin(), LangMap->end(),
   2693                   DoEmitPopulateLanguageMap(O));
   2694   }
   2695 
   2696   O << '\n';
   2697   O.indent(Indent1) << "return 0;\n";
   2698   O << "}\n\n";
   2699 }
   2700 
   2701 /// EmitEdgePropertyHandlerCallback - Emits code that handles edge
   2702 /// properties. Helper function passed to EmitCaseConstructHandler() by
   2703 /// EmitEdgeClass().
   2704 void EmitEdgePropertyHandlerCallback (const Init* i, unsigned IndentLevel,
   2705                                       raw_ostream& O) {
   2706   const DagInit& d = InitPtrToDag(i);
   2707   const std::string& OpName = GetOperatorName(d);
   2708 
   2709   if (OpName == "inc_weight") {
   2710     O.indent(IndentLevel) << "ret += ";
   2711   }
   2712   else if (OpName == "error") {
   2713     CheckNumberOfArguments(d, 1);
   2714     O.indent(IndentLevel) << "PrintError(\""
   2715                           << InitPtrToString(d.getArg(0))
   2716                           << "\");\n";
   2717     O.indent(IndentLevel) << "return -1;\n";
   2718     return;
   2719   }
   2720   else {
   2721     throw "Unknown operator in edge properties list: '" + OpName + "'!"
   2722       "\nOnly 'inc_weight', 'dec_weight' and 'error' are allowed.";
   2723   }
   2724 
   2725   if (d.getNumArgs() > 0)
   2726     O << InitPtrToInt(d.getArg(0)) << ";\n";
   2727   else
   2728     O << "2;\n";
   2729 
   2730 }
   2731 
   2732 /// EmitEdgeClass - Emit a single Edge# class.
   2733 void EmitEdgeClass (unsigned N, const std::string& Target,
   2734                     const DagInit& Case, const OptionDescriptions& OptDescs,
   2735                     raw_ostream& O) {
   2736 
   2737   // Class constructor.
   2738   O << "class Edge" << N << ": public Edge {\n"
   2739     << "public:\n";
   2740   O.indent(Indent1) << "Edge" << N << "() : Edge(\"" << Target
   2741                     << "\") {}\n\n";
   2742 
   2743   // Function Weight().
   2744   O.indent(Indent1)
   2745     << "int Weight(const InputLanguagesSet& InLangs) const {\n";
   2746   O.indent(Indent2) << "unsigned ret = 0;\n";
   2747 
   2748   // Handle the 'case' construct.
   2749   EmitCaseConstructHandler(&Case, Indent2, EmitEdgePropertyHandlerCallback,
   2750                            false, OptDescs, O);
   2751 
   2752   O.indent(Indent2) << "return ret;\n";
   2753   O.indent(Indent1) << "}\n\n};\n\n";
   2754 }
   2755 
   2756 /// EmitEdgeClasses - Emit Edge* classes that represent graph edges.
   2757 void EmitEdgeClasses (const DagVector& EdgeVector,
   2758                       const OptionDescriptions& OptDescs,
   2759                       raw_ostream& O) {
   2760   int i = 0;
   2761   for (DagVector::const_iterator B = EdgeVector.begin(),
   2762          E = EdgeVector.end(); B != E; ++B) {
   2763     const DagInit& Edge = **B;
   2764     const std::string& Name = GetOperatorName(Edge);
   2765 
   2766     if (Name == "optional_edge") {
   2767       assert(IsOptionalEdge(Edge));
   2768       const std::string& NodeB = InitPtrToString(Edge.getArg(1));
   2769 
   2770       const DagInit& Weight = InitPtrToDag(Edge.getArg(2));
   2771       EmitEdgeClass(i, NodeB, Weight, OptDescs, O);
   2772     }
   2773     else if (Name != "edge") {
   2774       throw "Unknown edge class: '" + Name + "'!";
   2775     }
   2776 
   2777     ++i;
   2778   }
   2779 }
   2780 
   2781 /// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraph() function.
   2782 void EmitPopulateCompilationGraph (const DagVector& EdgeVector,
   2783                                    const ToolDescriptions& ToolDescs,
   2784                                    raw_ostream& O)
   2785 {
   2786   O << "int PopulateCompilationGraph (CompilationGraph& G) {\n";
   2787 
   2788   for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
   2789          E = ToolDescs.end(); B != E; ++B)
   2790     O.indent(Indent1) << "G.insertNode(new " << (*B)->Name << "());\n";
   2791 
   2792   O << '\n';
   2793 
   2794   // Insert edges.
   2795 
   2796   int i = 0;
   2797   for (DagVector::const_iterator B = EdgeVector.begin(),
   2798          E = EdgeVector.end(); B != E; ++B) {
   2799     const DagInit& Edge = **B;
   2800     const std::string& NodeA = InitPtrToString(Edge.getArg(0));
   2801     const std::string& NodeB = InitPtrToString(Edge.getArg(1));
   2802 
   2803     O.indent(Indent1) << "if (int ret = G.insertEdge(\"" << NodeA << "\", ";
   2804 
   2805     if (IsOptionalEdge(Edge))
   2806       O << "new Edge" << i << "()";
   2807     else
   2808       O << "new SimpleEdge(\"" << NodeB << "\")";
   2809 
   2810     O << "))\n";
   2811     O.indent(Indent2) << "return ret;\n";
   2812 
   2813     ++i;
   2814   }
   2815 
   2816   O << '\n';
   2817   O.indent(Indent1) << "return 0;\n";
   2818   O << "}\n\n";
   2819 }
   2820 
   2821 /// HookInfo - Information about the hook type and number of arguments.
   2822 struct HookInfo {
   2823 
   2824   // A hook can either have a single parameter of type std::vector<std::string>,
   2825   // or NumArgs parameters of type const char*.
   2826   enum HookType { ListHook, ArgHook };
   2827 
   2828   HookType Type;
   2829   unsigned NumArgs;
   2830 
   2831   HookInfo() : Type(ArgHook), NumArgs(1)
   2832   {}
   2833 
   2834   HookInfo(HookType T) : Type(T), NumArgs(1)
   2835   {}
   2836 
   2837   HookInfo(unsigned N) : Type(ArgHook), NumArgs(N)
   2838   {}
   2839 };
   2840 
   2841 typedef llvm::StringMap<HookInfo> HookInfoMap;
   2842 
   2843 /// ExtractHookNames - Extract the hook names from all instances of
   2844 /// $CALL(HookName) in the provided command line string/action. Helper
   2845 /// function used by FillInHookNames().
   2846 class ExtractHookNames {
   2847   HookInfoMap& HookNames_;
   2848   const OptionDescriptions& OptDescs_;
   2849 public:
   2850   ExtractHookNames(HookInfoMap& HookNames, const OptionDescriptions& OptDescs)
   2851     : HookNames_(HookNames), OptDescs_(OptDescs)
   2852   {}
   2853 
   2854   void onAction (const DagInit& Dag) {
   2855     const std::string& Name = GetOperatorName(Dag);
   2856 
   2857     if (Name == "forward_transformed_value") {
   2858       CheckNumberOfArguments(Dag, 2);
   2859       const std::string& OptName = InitPtrToString(Dag.getArg(0));
   2860       const std::string& HookName = InitPtrToString(Dag.getArg(1));
   2861       const OptionDescription& D =
   2862         OptDescs_.FindParameterListOrParameter(OptName);
   2863 
   2864       HookNames_[HookName] = HookInfo(D.isList() ? HookInfo::ListHook
   2865                                       : HookInfo::ArgHook);
   2866     }
   2867     else if (Name == "append_cmd" || Name == "output_suffix") {
   2868       CheckNumberOfArguments(Dag, 1);
   2869       this->onCmdLine(InitPtrToString(Dag.getArg(0)));
   2870     }
   2871   }
   2872 
   2873   void onCmdLine(const std::string& Cmd) {
   2874     StrVector cmds;
   2875     TokenizeCmdLine(Cmd, cmds);
   2876 
   2877     for (StrVector::const_iterator B = cmds.begin(), E = cmds.end();
   2878          B != E; ++B) {
   2879       const std::string& cmd = *B;
   2880 
   2881       if (cmd == "$CALL") {
   2882         unsigned NumArgs = 0;
   2883         CheckedIncrement(B, E, "Syntax error in $CALL invocation!");
   2884         const std::string& HookName = *B;
   2885 
   2886         if (HookName.at(0) == ')')
   2887           throw "$CALL invoked with no arguments!";
   2888 
   2889         while (++B != E && B->at(0) != ')') {
   2890           ++NumArgs;
   2891         }
   2892 
   2893         HookInfoMap::const_iterator H = HookNames_.find(HookName);
   2894 
   2895         if (H != HookNames_.end() && H->second.NumArgs != NumArgs &&
   2896             H->second.Type != HookInfo::ArgHook)
   2897           throw "Overloading of hooks is not allowed. Overloaded hook: "
   2898             + HookName;
   2899         else
   2900           HookNames_[HookName] = HookInfo(NumArgs);
   2901       }
   2902     }
   2903   }
   2904 
   2905   void operator()(const Init* Arg) {
   2906 
   2907     // We're invoked on an action (either a dag or a dag list).
   2908     if (typeid(*Arg) == typeid(DagInit)) {
   2909       const DagInit& Dag = InitPtrToDag(Arg);
   2910       this->onAction(Dag);
   2911       return;
   2912     }
   2913     else if (typeid(*Arg) == typeid(ListInit)) {
   2914       const ListInit& List = InitPtrToList(Arg);
   2915       for (ListInit::const_iterator B = List.begin(), E = List.end(); B != E;
   2916            ++B) {
   2917         const DagInit& Dag = InitPtrToDag(*B);
   2918         this->onAction(Dag);
   2919       }
   2920       return;
   2921     }
   2922 
   2923     // We're invoked on a command line string.
   2924     this->onCmdLine(InitPtrToString(Arg));
   2925   }
   2926 
   2927   void operator()(const Init* Statement, unsigned) {
   2928     this->operator()(Statement);
   2929   }
   2930 };
   2931 
   2932 /// FillInHookNames - Actually extract the hook names from all command
   2933 /// line strings. Helper function used by EmitHookDeclarations().
   2934 void FillInHookNames(const ToolDescriptions& ToolDescs,
   2935                      const OptionDescriptions& OptDescs,
   2936                      HookInfoMap& HookNames)
   2937 {
   2938   // For all tool descriptions:
   2939   for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
   2940          E = ToolDescs.end(); B != E; ++B) {
   2941     const ToolDescription& D = *(*B);
   2942 
   2943     // Look for 'forward_transformed_value' in 'actions'.
   2944     if (D.Actions)
   2945       WalkCase(D.Actions, Id(), ExtractHookNames(HookNames, OptDescs));
   2946 
   2947     // Look for hook invocations in 'cmd_line'.
   2948     if (!D.CmdLine)
   2949       continue;
   2950     if (dynamic_cast<StringInit*>(D.CmdLine))
   2951       // This is a string.
   2952       ExtractHookNames(HookNames, OptDescs).operator()(D.CmdLine);
   2953     else
   2954       // This is a 'case' construct.
   2955       WalkCase(D.CmdLine, Id(), ExtractHookNames(HookNames, OptDescs));
   2956   }
   2957 }
   2958 
   2959 /// EmitHookDeclarations - Parse CmdLine fields of all the tool
   2960 /// property records and emit hook function declaration for each
   2961 /// instance of $CALL(HookName).
   2962 void EmitHookDeclarations(const ToolDescriptions& ToolDescs,
   2963                           const OptionDescriptions& OptDescs, raw_ostream& O) {
   2964   HookInfoMap HookNames;
   2965 
   2966   FillInHookNames(ToolDescs, OptDescs, HookNames);
   2967   if (HookNames.empty())
   2968     return;
   2969 
   2970   for (HookInfoMap::const_iterator B = HookNames.begin(),
   2971          E = HookNames.end(); B != E; ++B) {
   2972     StringRef HookName = B->first();
   2973     const HookInfo &Info = B->second;
   2974 
   2975     O.indent(Indent1) << "std::string " << HookName << "(";
   2976 
   2977     if (Info.Type == HookInfo::ArgHook) {
   2978       for (unsigned i = 0, j = Info.NumArgs; i < j; ++i) {
   2979         O << "const char* Arg" << i << (i+1 == j ? "" : ", ");
   2980       }
   2981     }
   2982     else {
   2983       O << "const std::vector<std::string>& Arg";
   2984     }
   2985 
   2986     O <<");\n";
   2987   }
   2988 }
   2989 
   2990 /// EmitIncludes - Emit necessary #include directives and some
   2991 /// additional declarations.
   2992 void EmitIncludes(raw_ostream& O) {
   2993   O << "#include \"llvm/CompilerDriver/BuiltinOptions.h\"\n"
   2994     << "#include \"llvm/CompilerDriver/CompilationGraph.h\"\n"
   2995     << "#include \"llvm/CompilerDriver/Error.h\"\n"
   2996     << "#include \"llvm/CompilerDriver/Tool.h\"\n\n"
   2997 
   2998     << "#include \"llvm/Support/CommandLine.h\"\n"
   2999     << "#include \"llvm/Support/raw_ostream.h\"\n\n"
   3000 
   3001     << "#include <algorithm>\n"
   3002     << "#include <cstdlib>\n"
   3003     << "#include <iterator>\n"
   3004     << "#include <stdexcept>\n\n"
   3005 
   3006     << "using namespace llvm;\n"
   3007     << "using namespace llvmc;\n\n"
   3008 
   3009     << "inline const char* checkCString(const char* s)\n"
   3010     << "{ return s == NULL ? \"\" : s; }\n\n";
   3011 }
   3012 
   3013 
   3014 /// DriverData - Holds all information about the driver.
   3015 struct DriverData {
   3016   OptionDescriptions OptDescs;
   3017   ToolDescriptions ToolDescs;
   3018   DagVector Edges;
   3019   bool HasSink;
   3020 };
   3021 
   3022 /// HasSink - Go through the list of tool descriptions and check if
   3023 /// there are any with the 'sink' property set.
   3024 bool HasSink(const ToolDescriptions& ToolDescs) {
   3025   for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
   3026          E = ToolDescs.end(); B != E; ++B)
   3027     if ((*B)->isSink())
   3028       return true;
   3029 
   3030   return false;
   3031 }
   3032 
   3033 /// CollectDriverData - Collect compilation graph edges, tool properties and
   3034 /// option properties from the parse tree.
   3035 void CollectDriverData (const RecordKeeper& Records, DriverData& Data) {
   3036   // Collect option properties.
   3037   const RecordVector& OptionLists =
   3038     Records.getAllDerivedDefinitions("OptionList");
   3039   CollectOptionDescriptions(OptionLists, Data.OptDescs);
   3040 
   3041   // Collect tool properties.
   3042   const RecordVector& Tools = Records.getAllDerivedDefinitions("Tool");
   3043   CollectToolDescriptions(Tools, Data.ToolDescs);
   3044   Data.HasSink = HasSink(Data.ToolDescs);
   3045 
   3046   // Collect compilation graph edges.
   3047   const RecordVector& CompilationGraphs =
   3048     Records.getAllDerivedDefinitions("CompilationGraph");
   3049   FillInEdgeVector(CompilationGraphs, Data.Edges);
   3050 }
   3051 
   3052 /// CheckDriverData - Perform some sanity checks on the collected data.
   3053 void CheckDriverData(DriverData& Data) {
   3054   // Filter out all tools not mentioned in the compilation graph.
   3055   FilterNotInGraph(Data.Edges, Data.ToolDescs);
   3056 
   3057   // Typecheck the compilation graph.
   3058   // TODO: use a genuine graph representation instead of a vector and check for
   3059   // multiple edges.
   3060   TypecheckGraph(Data.Edges, Data.ToolDescs);
   3061 
   3062   // Check that there are no options without side effects (specified
   3063   // only in the OptionList).
   3064   CheckForSuperfluousOptions(Data.Edges, Data.ToolDescs, Data.OptDescs);
   3065 }
   3066 
   3067 void EmitDriverCode(const DriverData& Data,
   3068                     raw_ostream& O, RecordKeeper &Records) {
   3069   // Emit file header.
   3070   EmitIncludes(O);
   3071 
   3072   // Emit global option registration code.
   3073   O << "namespace llvmc {\n"
   3074     << "namespace autogenerated {\n\n";
   3075   EmitOptionDefinitions(Data.OptDescs, Data.HasSink, O);
   3076   O << "} // End namespace autogenerated.\n"
   3077     << "} // End namespace llvmc.\n\n";
   3078 
   3079   // Emit hook declarations.
   3080   O << "namespace hooks {\n";
   3081   EmitHookDeclarations(Data.ToolDescs, Data.OptDescs, O);
   3082   O << "} // End namespace hooks.\n\n";
   3083 
   3084   O << "namespace {\n\n";
   3085   O << "using namespace llvmc::autogenerated;\n\n";
   3086 
   3087   // Emit Tool classes.
   3088   for (ToolDescriptions::const_iterator B = Data.ToolDescs.begin(),
   3089          E = Data.ToolDescs.end(); B!=E; ++B)
   3090     EmitToolClassDefinition(*(*B), Data.OptDescs, O);
   3091 
   3092   // Emit Edge# classes.
   3093   EmitEdgeClasses(Data.Edges, Data.OptDescs, O);
   3094 
   3095   O << "} // End anonymous namespace.\n\n";
   3096 
   3097   O << "namespace llvmc {\n";
   3098   O << "namespace autogenerated {\n\n";
   3099 
   3100   // Emit PreprocessOptions() function.
   3101   EmitPreprocessOptions(Records, Data.OptDescs, O);
   3102 
   3103   // Emit PopulateLanguageMap() function
   3104   // (language map maps from file extensions to language names).
   3105   EmitPopulateLanguageMap(Records, O);
   3106 
   3107   // Emit PopulateCompilationGraph() function.
   3108   EmitPopulateCompilationGraph(Data.Edges, Data.ToolDescs, O);
   3109 
   3110   O << "} // End namespace autogenerated.\n";
   3111   O << "} // End namespace llvmc.\n\n";
   3112 
   3113   // EOF
   3114 }
   3115 
   3116 
   3117 // End of anonymous namespace
   3118 }
   3119 
   3120 /// run - The back-end entry point.
   3121 void LLVMCConfigurationEmitter::run (raw_ostream &O) {
   3122   try {
   3123     DriverData Data;
   3124 
   3125     CollectDriverData(Records, Data);
   3126     CheckDriverData(Data);
   3127 
   3128     this->EmitSourceFileHeader("llvmc-based driver: auto-generated code", O);
   3129     EmitDriverCode(Data, O, Records);
   3130 
   3131   } catch (std::exception& Error) {
   3132     throw Error.what() + std::string(" - usually this means a syntax error.");
   3133   }
   3134 }
   3135