4293c95fd2fb6fb993604e9617c62a6a0d3cb88b
[oota-llvm.git] / utils / TableGen / LLVMCConfigurationEmitter.cpp
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/SmallVector.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/ADT/StringMap.h"
21 #include "llvm/ADT/StringSet.h"
22 #include <algorithm>
23 #include <cassert>
24 #include <functional>
25 #include <stdexcept>
26 #include <string>
27 #include <typeinfo>
28
29 using namespace llvm;
30
31 namespace {
32
33 //===----------------------------------------------------------------------===//
34 /// Typedefs
35
36 typedef std::vector<Record*> RecordVector;
37 typedef std::vector<std::string> StrVector;
38
39 //===----------------------------------------------------------------------===//
40 /// Constants
41
42 // Indentation.
43 unsigned TabWidth = 4;
44 unsigned Indent1  = TabWidth*1;
45 unsigned Indent2  = TabWidth*2;
46 unsigned Indent3  = TabWidth*3;
47
48 // Default help string.
49 const char * DefaultHelpString = "NO HELP MESSAGE PROVIDED";
50
51 // Name for the "sink" option.
52 const char * SinkOptionName = "AutoGeneratedSinkOption";
53
54 //===----------------------------------------------------------------------===//
55 /// Helper functions
56
57 /// Id - An 'identity' function object.
58 struct Id {
59   template<typename T0>
60   void operator()(const T0&) const {
61   }
62   template<typename T0, typename T1>
63   void operator()(const T0&, const T1&) const {
64   }
65   template<typename T0, typename T1, typename T2>
66   void operator()(const T0&, const T1&, const T2&) const {
67   }
68 };
69
70 int InitPtrToInt(const Init* ptr) {
71   const IntInit& val = dynamic_cast<const IntInit&>(*ptr);
72   return val.getValue();
73 }
74
75 const std::string& InitPtrToString(const Init* ptr) {
76   const StringInit& val = dynamic_cast<const StringInit&>(*ptr);
77   return val.getValue();
78 }
79
80 const ListInit& InitPtrToList(const Init* ptr) {
81   const ListInit& val = dynamic_cast<const ListInit&>(*ptr);
82   return val;
83 }
84
85 const DagInit& InitPtrToDag(const Init* ptr) {
86   const DagInit& val = dynamic_cast<const DagInit&>(*ptr);
87   return val;
88 }
89
90 const std::string GetOperatorName(const DagInit* D) {
91   return D->getOperator()->getAsString();
92 }
93
94 const std::string GetOperatorName(const DagInit& D) {
95   return GetOperatorName(&D);
96 }
97
98 // checkNumberOfArguments - Ensure that the number of args in d is
99 // greater than or equal to min_arguments, otherwise throw an exception.
100 void checkNumberOfArguments (const DagInit* d, unsigned min_arguments) {
101   if (!d || d->getNumArgs() < min_arguments)
102     throw GetOperatorName(d) + ": too few arguments!";
103 }
104
105 // isDagEmpty - is this DAG marked with an empty marker?
106 bool isDagEmpty (const DagInit* d) {
107   return GetOperatorName(d) == "empty_dag_marker";
108 }
109
110 // EscapeVariableName - Escape commas and other symbols not allowed
111 // in the C++ variable names. Makes it possible to use options named
112 // like "Wa," (useful for prefix options).
113 std::string EscapeVariableName(const std::string& Var) {
114   std::string ret;
115   for (unsigned i = 0; i != Var.size(); ++i) {
116     char cur_char = Var[i];
117     if (cur_char == ',') {
118       ret += "_comma_";
119     }
120     else if (cur_char == '+') {
121       ret += "_plus_";
122     }
123     else if (cur_char == '-') {
124       ret += "_dash_";
125     }
126     else {
127       ret.push_back(cur_char);
128     }
129   }
130   return ret;
131 }
132
133 /// oneOf - Does the input string contain this character?
134 bool oneOf(const char* lst, char c) {
135   while (*lst) {
136     if (*lst++ == c)
137       return true;
138   }
139   return false;
140 }
141
142 template <class I, class S>
143 void checkedIncrement(I& P, I E, S ErrorString) {
144   ++P;
145   if (P == E)
146     throw ErrorString;
147 }
148
149 // apply is needed because C++'s syntax doesn't let us construct a function
150 // object and call it in the same statement.
151 template<typename F, typename T0>
152 void apply(F Fun, T0& Arg0) {
153   return Fun(Arg0);
154 }
155
156 template<typename F, typename T0, typename T1>
157 void apply(F Fun, T0& Arg0, T1& Arg1) {
158   return Fun(Arg0, Arg1);
159 }
160
161 //===----------------------------------------------------------------------===//
162 /// Back-end specific code
163
164
165 /// OptionType - One of six different option types. See the
166 /// documentation for detailed description of differences.
167 namespace OptionType {
168
169   enum OptionType { Alias, Switch, Parameter, ParameterList,
170                     Prefix, PrefixList};
171
172   bool IsAlias(OptionType t) {
173     return (t == Alias);
174   }
175
176   bool IsList (OptionType t) {
177     return (t == ParameterList || t == PrefixList);
178   }
179
180   bool IsSwitch (OptionType t) {
181     return (t == Switch);
182   }
183
184   bool IsParameter (OptionType t) {
185     return (t == Parameter || t == Prefix);
186   }
187
188 }
189
190 OptionType::OptionType stringToOptionType(const std::string& T) {
191   if (T == "alias_option")
192     return OptionType::Alias;
193   else if (T == "switch_option")
194     return OptionType::Switch;
195   else if (T == "parameter_option")
196     return OptionType::Parameter;
197   else if (T == "parameter_list_option")
198     return OptionType::ParameterList;
199   else if (T == "prefix_option")
200     return OptionType::Prefix;
201   else if (T == "prefix_list_option")
202     return OptionType::PrefixList;
203   else
204     throw "Unknown option type: " + T + '!';
205 }
206
207 namespace OptionDescriptionFlags {
208   enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2,
209                                 ReallyHidden = 0x4, Extern = 0x8,
210                                 OneOrMore = 0x10, ZeroOrOne = 0x20 };
211 }
212
213 /// OptionDescription - Represents data contained in a single
214 /// OptionList entry.
215 struct OptionDescription {
216   OptionType::OptionType Type;
217   std::string Name;
218   unsigned Flags;
219   std::string Help;
220   unsigned MultiVal;
221   Init* InitVal;
222
223   OptionDescription(OptionType::OptionType t = OptionType::Switch,
224                     const std::string& n = "",
225                     const std::string& h = DefaultHelpString)
226     : Type(t), Name(n), Flags(0x0), Help(h), MultiVal(1), InitVal(0)
227   {}
228
229   /// GenTypeDeclaration - Returns the C++ variable type of this
230   /// option.
231   const char* GenTypeDeclaration() const;
232
233   /// GenVariableName - Returns the variable name used in the
234   /// generated C++ code.
235   std::string GenVariableName() const;
236
237   /// Merge - Merge two option descriptions.
238   void Merge (const OptionDescription& other);
239
240   // Misc convenient getters/setters.
241
242   bool isAlias() const;
243
244   bool isMultiVal() const;
245
246   bool isExtern() const;
247   void setExtern();
248
249   bool isRequired() const;
250   void setRequired();
251
252   bool isOneOrMore() const;
253   void setOneOrMore();
254
255   bool isZeroOrOne() const;
256   void setZeroOrOne();
257
258   bool isHidden() const;
259   void setHidden();
260
261   bool isReallyHidden() const;
262   void setReallyHidden();
263
264   bool isSwitch() const
265   { return OptionType::IsSwitch(this->Type); }
266
267   bool isParameter() const
268   { return OptionType::IsParameter(this->Type); }
269
270   bool isList() const
271   { return OptionType::IsList(this->Type); }
272
273 };
274
275 void OptionDescription::Merge (const OptionDescription& other)
276 {
277   if (other.Type != Type)
278     throw "Conflicting definitions for the option " + Name + "!";
279
280   if (Help == other.Help || Help == DefaultHelpString)
281     Help = other.Help;
282   else if (other.Help != DefaultHelpString) {
283     llvm::errs() << "Warning: several different help strings"
284       " defined for option " + Name + "\n";
285   }
286
287   Flags |= other.Flags;
288 }
289
290 bool OptionDescription::isAlias() const {
291   return OptionType::IsAlias(this->Type);
292 }
293
294 bool OptionDescription::isMultiVal() const {
295   return MultiVal > 1;
296 }
297
298 bool OptionDescription::isExtern() const {
299   return Flags & OptionDescriptionFlags::Extern;
300 }
301 void OptionDescription::setExtern() {
302   Flags |= OptionDescriptionFlags::Extern;
303 }
304
305 bool OptionDescription::isRequired() const {
306   return Flags & OptionDescriptionFlags::Required;
307 }
308 void OptionDescription::setRequired() {
309   Flags |= OptionDescriptionFlags::Required;
310 }
311
312 bool OptionDescription::isOneOrMore() const {
313   return Flags & OptionDescriptionFlags::OneOrMore;
314 }
315 void OptionDescription::setOneOrMore() {
316   Flags |= OptionDescriptionFlags::OneOrMore;
317 }
318
319 bool OptionDescription::isZeroOrOne() const {
320   return Flags & OptionDescriptionFlags::ZeroOrOne;
321 }
322 void OptionDescription::setZeroOrOne() {
323   Flags |= OptionDescriptionFlags::ZeroOrOne;
324 }
325
326 bool OptionDescription::isHidden() const {
327   return Flags & OptionDescriptionFlags::Hidden;
328 }
329 void OptionDescription::setHidden() {
330   Flags |= OptionDescriptionFlags::Hidden;
331 }
332
333 bool OptionDescription::isReallyHidden() const {
334   return Flags & OptionDescriptionFlags::ReallyHidden;
335 }
336 void OptionDescription::setReallyHidden() {
337   Flags |= OptionDescriptionFlags::ReallyHidden;
338 }
339
340 const char* OptionDescription::GenTypeDeclaration() const {
341   switch (Type) {
342   case OptionType::Alias:
343     return "cl::alias";
344   case OptionType::PrefixList:
345   case OptionType::ParameterList:
346     return "cl::list<std::string>";
347   case OptionType::Switch:
348     return "cl::opt<bool>";
349   case OptionType::Parameter:
350   case OptionType::Prefix:
351   default:
352     return "cl::opt<std::string>";
353   }
354 }
355
356 std::string OptionDescription::GenVariableName() const {
357   const std::string& EscapedName = EscapeVariableName(Name);
358   switch (Type) {
359   case OptionType::Alias:
360     return "AutoGeneratedAlias_" + EscapedName;
361   case OptionType::PrefixList:
362   case OptionType::ParameterList:
363     return "AutoGeneratedList_" + EscapedName;
364   case OptionType::Switch:
365     return "AutoGeneratedSwitch_" + EscapedName;
366   case OptionType::Prefix:
367   case OptionType::Parameter:
368   default:
369     return "AutoGeneratedParameter_" + EscapedName;
370   }
371 }
372
373 /// OptionDescriptions - An OptionDescription array plus some helper
374 /// functions.
375 class OptionDescriptions {
376   typedef StringMap<OptionDescription> container_type;
377
378   /// Descriptions - A list of OptionDescriptions.
379   container_type Descriptions;
380
381 public:
382   /// FindOption - exception-throwing wrapper for find().
383   const OptionDescription& FindOption(const std::string& OptName) const;
384
385   // Wrappers for FindOption that throw an exception in case the option has a
386   // wrong type.
387   const OptionDescription& FindSwitch(const std::string& OptName) const;
388   const OptionDescription& FindParameter(const std::string& OptName) const;
389   const OptionDescription& FindList(const std::string& OptName) const;
390   const OptionDescription&
391   FindListOrParameter(const std::string& OptName) const;
392
393   /// insertDescription - Insert new OptionDescription into
394   /// OptionDescriptions list
395   void InsertDescription (const OptionDescription& o);
396
397   // Support for STL-style iteration
398   typedef container_type::const_iterator const_iterator;
399   const_iterator begin() const { return Descriptions.begin(); }
400   const_iterator end() const { return Descriptions.end(); }
401 };
402
403 const OptionDescription&
404 OptionDescriptions::FindOption(const std::string& OptName) const {
405   const_iterator I = Descriptions.find(OptName);
406   if (I != Descriptions.end())
407     return I->second;
408   else
409     throw OptName + ": no such option!";
410 }
411
412 const OptionDescription&
413 OptionDescriptions::FindSwitch(const std::string& OptName) const {
414   const OptionDescription& OptDesc = this->FindOption(OptName);
415   if (!OptDesc.isSwitch())
416     throw OptName + ": incorrect option type - should be a switch!";
417   return OptDesc;
418 }
419
420 const OptionDescription&
421 OptionDescriptions::FindList(const std::string& OptName) const {
422   const OptionDescription& OptDesc = this->FindOption(OptName);
423   if (!OptDesc.isList())
424     throw OptName + ": incorrect option type - should be a list!";
425   return OptDesc;
426 }
427
428 const OptionDescription&
429 OptionDescriptions::FindParameter(const std::string& OptName) const {
430   const OptionDescription& OptDesc = this->FindOption(OptName);
431   if (!OptDesc.isParameter())
432     throw OptName + ": incorrect option type - should be a parameter!";
433   return OptDesc;
434 }
435
436 const OptionDescription&
437 OptionDescriptions::FindListOrParameter(const std::string& OptName) const {
438   const OptionDescription& OptDesc = this->FindOption(OptName);
439   if (!OptDesc.isList() && !OptDesc.isParameter())
440     throw OptName
441       + ": incorrect option type - should be a list or parameter!";
442   return OptDesc;
443 }
444
445 void OptionDescriptions::InsertDescription (const OptionDescription& o) {
446   container_type::iterator I = Descriptions.find(o.Name);
447   if (I != Descriptions.end()) {
448     OptionDescription& D = I->second;
449     D.Merge(o);
450   }
451   else {
452     Descriptions[o.Name] = o;
453   }
454 }
455
456 /// HandlerTable - A base class for function objects implemented as
457 /// 'tables of handlers'.
458 template <class T>
459 class HandlerTable {
460 protected:
461   // Implementation details.
462
463   /// Handler -
464   typedef void (T::* Handler) (const DagInit*);
465   /// HandlerMap - A map from property names to property handlers
466   typedef StringMap<Handler> HandlerMap;
467
468   static HandlerMap Handlers_;
469   static bool staticMembersInitialized_;
470
471   T* childPtr;
472 public:
473
474   HandlerTable(T* cp) : childPtr(cp)
475   {}
476
477   /// operator() - Just forwards to the corresponding property
478   /// handler.
479   void operator() (Init* i) {
480     const DagInit& property = InitPtrToDag(i);
481     const std::string& property_name = GetOperatorName(property);
482     typename HandlerMap::iterator method = Handlers_.find(property_name);
483
484     if (method != Handlers_.end()) {
485       Handler h = method->second;
486       (childPtr->*h)(&property);
487     }
488     else {
489       throw "No handler found for property " + property_name + "!";
490     }
491   }
492
493   void AddHandler(const char* Property, Handler Handl) {
494     Handlers_[Property] = Handl;
495   }
496 };
497
498 template <class T> typename HandlerTable<T>::HandlerMap
499 HandlerTable<T>::Handlers_;
500 template <class T> bool HandlerTable<T>::staticMembersInitialized_ = false;
501
502
503 /// CollectOptionProperties - Function object for iterating over an
504 /// option property list.
505 class CollectOptionProperties : public HandlerTable<CollectOptionProperties> {
506 private:
507
508   /// optDescs_ - OptionDescriptions table. This is where the
509   /// information is stored.
510   OptionDescription& optDesc_;
511
512 public:
513
514   explicit CollectOptionProperties(OptionDescription& OD)
515     : HandlerTable<CollectOptionProperties>(this), optDesc_(OD)
516   {
517     if (!staticMembersInitialized_) {
518       AddHandler("extern", &CollectOptionProperties::onExtern);
519       AddHandler("help", &CollectOptionProperties::onHelp);
520       AddHandler("hidden", &CollectOptionProperties::onHidden);
521       AddHandler("init", &CollectOptionProperties::onInit);
522       AddHandler("multi_val", &CollectOptionProperties::onMultiVal);
523       AddHandler("one_or_more", &CollectOptionProperties::onOneOrMore);
524       AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden);
525       AddHandler("required", &CollectOptionProperties::onRequired);
526       AddHandler("zero_or_one", &CollectOptionProperties::onZeroOrOne);
527
528       staticMembersInitialized_ = true;
529     }
530   }
531
532 private:
533
534   /// Option property handlers --
535   /// Methods that handle option properties such as (help) or (hidden).
536
537   void onExtern (const DagInit* d) {
538     checkNumberOfArguments(d, 0);
539     optDesc_.setExtern();
540   }
541
542   void onHelp (const DagInit* d) {
543     checkNumberOfArguments(d, 1);
544     optDesc_.Help = InitPtrToString(d->getArg(0));
545   }
546
547   void onHidden (const DagInit* d) {
548     checkNumberOfArguments(d, 0);
549     optDesc_.setHidden();
550   }
551
552   void onReallyHidden (const DagInit* d) {
553     checkNumberOfArguments(d, 0);
554     optDesc_.setReallyHidden();
555   }
556
557   void onRequired (const DagInit* d) {
558     checkNumberOfArguments(d, 0);
559     if (optDesc_.isOneOrMore())
560       throw std::string("An option can't have both (required) "
561                         "and (one_or_more) properties!");
562     optDesc_.setRequired();
563   }
564
565   void onInit (const DagInit* d) {
566     checkNumberOfArguments(d, 1);
567     Init* i = d->getArg(0);
568     const std::string& str = i->getAsString();
569
570     bool correct = optDesc_.isParameter() && dynamic_cast<StringInit*>(i);
571     correct |= (optDesc_.isSwitch() && (str == "true" || str == "false"));
572
573     if (!correct)
574       throw std::string("Incorrect usage of the 'init' option property!");
575
576     optDesc_.InitVal = i;
577   }
578
579   void onOneOrMore (const DagInit* d) {
580     checkNumberOfArguments(d, 0);
581     if (optDesc_.isRequired() || optDesc_.isZeroOrOne())
582       throw std::string("Only one of (required), (zero_or_one) or "
583                         "(one_or_more) properties is allowed!");
584     if (!OptionType::IsList(optDesc_.Type))
585       llvm::errs() << "Warning: specifying the 'one_or_more' property "
586         "on a non-list option will have no effect.\n";
587     optDesc_.setOneOrMore();
588   }
589
590   void onZeroOrOne (const DagInit* d) {
591     checkNumberOfArguments(d, 0);
592     if (optDesc_.isRequired() || optDesc_.isOneOrMore())
593       throw std::string("Only one of (required), (zero_or_one) or "
594                         "(one_or_more) properties is allowed!");
595     if (!OptionType::IsList(optDesc_.Type))
596       llvm::errs() << "Warning: specifying the 'zero_or_one' property"
597         "on a non-list option will have no effect.\n";
598     optDesc_.setZeroOrOne();
599   }
600
601   void onMultiVal (const DagInit* d) {
602     checkNumberOfArguments(d, 1);
603     int val = InitPtrToInt(d->getArg(0));
604     if (val < 2)
605       throw std::string("Error in the 'multi_val' property: "
606                         "the value must be greater than 1!");
607     if (!OptionType::IsList(optDesc_.Type))
608       throw std::string("The multi_val property is valid only "
609                         "on list options!");
610     optDesc_.MultiVal = val;
611   }
612
613 };
614
615 /// AddOption - A function object that is applied to every option
616 /// description. Used by CollectOptionDescriptions.
617 class AddOption {
618 private:
619   OptionDescriptions& OptDescs_;
620
621 public:
622   explicit AddOption(OptionDescriptions& OD) : OptDescs_(OD)
623   {}
624
625   void operator()(const Init* i) {
626     const DagInit& d = InitPtrToDag(i);
627     checkNumberOfArguments(&d, 1);
628
629     const OptionType::OptionType Type =
630       stringToOptionType(GetOperatorName(d));
631     const std::string& Name = InitPtrToString(d.getArg(0));
632
633     OptionDescription OD(Type, Name);
634
635     if (!OD.isExtern())
636       checkNumberOfArguments(&d, 2);
637
638     if (OD.isAlias()) {
639       // Aliases store the aliased option name in the 'Help' field.
640       OD.Help = InitPtrToString(d.getArg(1));
641     }
642     else if (!OD.isExtern()) {
643       processOptionProperties(&d, OD);
644     }
645     OptDescs_.InsertDescription(OD);
646   }
647
648 private:
649   /// processOptionProperties - Go through the list of option
650   /// properties and call a corresponding handler for each.
651   static void processOptionProperties (const DagInit* d, OptionDescription& o) {
652     checkNumberOfArguments(d, 2);
653     DagInit::const_arg_iterator B = d->arg_begin();
654     // Skip the first argument: it's always the option name.
655     ++B;
656     std::for_each(B, d->arg_end(), CollectOptionProperties(o));
657   }
658
659 };
660
661 /// CollectOptionDescriptions - Collects option properties from all
662 /// OptionLists.
663 void CollectOptionDescriptions (RecordVector::const_iterator B,
664                                 RecordVector::const_iterator E,
665                                 OptionDescriptions& OptDescs)
666 {
667   // For every OptionList:
668   for (; B!=E; ++B) {
669     RecordVector::value_type T = *B;
670     // Throws an exception if the value does not exist.
671     ListInit* PropList = T->getValueAsListInit("options");
672
673     // For every option description in this list:
674     // collect the information and
675     std::for_each(PropList->begin(), PropList->end(), AddOption(OptDescs));
676   }
677 }
678
679 // Tool information record
680
681 namespace ToolFlags {
682   enum ToolFlags { Join = 0x1, Sink = 0x2 };
683 }
684
685 struct ToolDescription : public RefCountedBase<ToolDescription> {
686   std::string Name;
687   Init* CmdLine;
688   Init* Actions;
689   StrVector InLanguage;
690   std::string OutLanguage;
691   std::string OutputSuffix;
692   unsigned Flags;
693
694   // Various boolean properties
695   void setSink()      { Flags |= ToolFlags::Sink; }
696   bool isSink() const { return Flags & ToolFlags::Sink; }
697   void setJoin()      { Flags |= ToolFlags::Join; }
698   bool isJoin() const { return Flags & ToolFlags::Join; }
699
700   // Default ctor here is needed because StringMap can only store
701   // DefaultConstructible objects
702   ToolDescription() : CmdLine(0), Actions(0), Flags(0) {}
703   ToolDescription (const std::string& n)
704   : Name(n), CmdLine(0), Actions(0), Flags(0)
705   {}
706 };
707
708 /// ToolDescriptions - A list of Tool information records.
709 typedef std::vector<IntrusiveRefCntPtr<ToolDescription> > ToolDescriptions;
710
711
712 /// CollectToolProperties - Function object for iterating over a list of
713 /// tool property records.
714 class CollectToolProperties : public HandlerTable<CollectToolProperties> {
715 private:
716
717   /// toolDesc_ - Properties of the current Tool. This is where the
718   /// information is stored.
719   ToolDescription& toolDesc_;
720
721 public:
722
723   explicit CollectToolProperties (ToolDescription& d)
724     : HandlerTable<CollectToolProperties>(this) , toolDesc_(d)
725   {
726     if (!staticMembersInitialized_) {
727
728       AddHandler("actions", &CollectToolProperties::onActions);
729       AddHandler("cmd_line", &CollectToolProperties::onCmdLine);
730       AddHandler("in_language", &CollectToolProperties::onInLanguage);
731       AddHandler("join", &CollectToolProperties::onJoin);
732       AddHandler("out_language", &CollectToolProperties::onOutLanguage);
733       AddHandler("output_suffix", &CollectToolProperties::onOutputSuffix);
734       AddHandler("sink", &CollectToolProperties::onSink);
735
736       staticMembersInitialized_ = true;
737     }
738   }
739
740 private:
741
742   /// Property handlers --
743   /// Functions that extract information about tool properties from
744   /// DAG representation.
745
746   void onActions (const DagInit* d) {
747     checkNumberOfArguments(d, 1);
748     Init* Case = d->getArg(0);
749     if (typeid(*Case) != typeid(DagInit) ||
750         GetOperatorName(static_cast<DagInit*>(Case)) != "case")
751       throw
752         std::string("The argument to (actions) should be a 'case' construct!");
753     toolDesc_.Actions = Case;
754   }
755
756   void onCmdLine (const DagInit* d) {
757     checkNumberOfArguments(d, 1);
758     toolDesc_.CmdLine = d->getArg(0);
759   }
760
761   void onInLanguage (const DagInit* d) {
762     checkNumberOfArguments(d, 1);
763     Init* arg = d->getArg(0);
764
765     // Find out the argument's type.
766     if (typeid(*arg) == typeid(StringInit)) {
767       // It's a string.
768       toolDesc_.InLanguage.push_back(InitPtrToString(arg));
769     }
770     else {
771       // It's a list.
772       const ListInit& lst = InitPtrToList(arg);
773       StrVector& out = toolDesc_.InLanguage;
774
775       // Copy strings to the output vector.
776       for (ListInit::const_iterator B = lst.begin(), E = lst.end();
777            B != E; ++B) {
778         out.push_back(InitPtrToString(*B));
779       }
780
781       // Remove duplicates.
782       std::sort(out.begin(), out.end());
783       StrVector::iterator newE = std::unique(out.begin(), out.end());
784       out.erase(newE, out.end());
785     }
786   }
787
788   void onJoin (const DagInit* d) {
789     checkNumberOfArguments(d, 0);
790     toolDesc_.setJoin();
791   }
792
793   void onOutLanguage (const DagInit* d) {
794     checkNumberOfArguments(d, 1);
795     toolDesc_.OutLanguage = InitPtrToString(d->getArg(0));
796   }
797
798   void onOutputSuffix (const DagInit* d) {
799     checkNumberOfArguments(d, 1);
800     toolDesc_.OutputSuffix = InitPtrToString(d->getArg(0));
801   }
802
803   void onSink (const DagInit* d) {
804     checkNumberOfArguments(d, 0);
805     toolDesc_.setSink();
806   }
807
808 };
809
810 /// CollectToolDescriptions - Gather information about tool properties
811 /// from the parsed TableGen data (basically a wrapper for the
812 /// CollectToolProperties function object).
813 void CollectToolDescriptions (RecordVector::const_iterator B,
814                               RecordVector::const_iterator E,
815                               ToolDescriptions& ToolDescs)
816 {
817   // Iterate over a properties list of every Tool definition
818   for (;B!=E;++B) {
819     const Record* T = *B;
820     // Throws an exception if the value does not exist.
821     ListInit* PropList = T->getValueAsListInit("properties");
822
823     IntrusiveRefCntPtr<ToolDescription>
824       ToolDesc(new ToolDescription(T->getName()));
825
826     std::for_each(PropList->begin(), PropList->end(),
827                   CollectToolProperties(*ToolDesc));
828     ToolDescs.push_back(ToolDesc);
829   }
830 }
831
832 /// FillInEdgeVector - Merge all compilation graph definitions into
833 /// one single edge list.
834 void FillInEdgeVector(RecordVector::const_iterator B,
835                       RecordVector::const_iterator E, RecordVector& Out) {
836   for (; B != E; ++B) {
837     const ListInit* edges = (*B)->getValueAsListInit("edges");
838
839     for (unsigned i = 0; i < edges->size(); ++i)
840       Out.push_back(edges->getElementAsRecord(i));
841   }
842 }
843
844 /// CalculatePriority - Calculate the priority of this plugin.
845 int CalculatePriority(RecordVector::const_iterator B,
846                       RecordVector::const_iterator E) {
847   int priority = 0;
848
849   if (B != E) {
850     priority  = static_cast<int>((*B)->getValueAsInt("priority"));
851
852     if (++B != E)
853       throw std::string("More than one 'PluginPriority' instance found: "
854                         "most probably an error!");
855   }
856
857   return priority;
858 }
859
860 /// NotInGraph - Helper function object for FilterNotInGraph.
861 struct NotInGraph {
862 private:
863   const llvm::StringSet<>& ToolsInGraph_;
864
865 public:
866   NotInGraph(const llvm::StringSet<>& ToolsInGraph)
867   : ToolsInGraph_(ToolsInGraph)
868   {}
869
870   bool operator()(const IntrusiveRefCntPtr<ToolDescription>& x) {
871     return (ToolsInGraph_.count(x->Name) == 0);
872   }
873 };
874
875 /// FilterNotInGraph - Filter out from ToolDescs all Tools not
876 /// mentioned in the compilation graph definition.
877 void FilterNotInGraph (const RecordVector& EdgeVector,
878                        ToolDescriptions& ToolDescs) {
879
880   // List all tools mentioned in the graph.
881   llvm::StringSet<> ToolsInGraph;
882
883   for (RecordVector::const_iterator B = EdgeVector.begin(),
884          E = EdgeVector.end(); B != E; ++B) {
885
886     const Record* Edge = *B;
887     const std::string& NodeA = Edge->getValueAsString("a");
888     const std::string& NodeB = Edge->getValueAsString("b");
889
890     if (NodeA != "root")
891       ToolsInGraph.insert(NodeA);
892     ToolsInGraph.insert(NodeB);
893   }
894
895   // Filter ToolPropertiesList.
896   ToolDescriptions::iterator new_end =
897     std::remove_if(ToolDescs.begin(), ToolDescs.end(),
898                    NotInGraph(ToolsInGraph));
899   ToolDescs.erase(new_end, ToolDescs.end());
900 }
901
902 /// FillInToolToLang - Fills in two tables that map tool names to
903 /// (input, output) languages.  Helper function used by TypecheckGraph().
904 void FillInToolToLang (const ToolDescriptions& ToolDescs,
905                        StringMap<StringSet<> >& ToolToInLang,
906                        StringMap<std::string>& ToolToOutLang) {
907   for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
908          E = ToolDescs.end(); B != E; ++B) {
909     const ToolDescription& D = *(*B);
910     for (StrVector::const_iterator B = D.InLanguage.begin(),
911            E = D.InLanguage.end(); B != E; ++B)
912       ToolToInLang[D.Name].insert(*B);
913     ToolToOutLang[D.Name] = D.OutLanguage;
914   }
915 }
916
917 /// TypecheckGraph - Check that names for output and input languages
918 /// on all edges do match. This doesn't do much when the information
919 /// about the whole graph is not available (i.e. when compiling most
920 /// plugins).
921 void TypecheckGraph (const RecordVector& EdgeVector,
922                      const ToolDescriptions& ToolDescs) {
923   StringMap<StringSet<> > ToolToInLang;
924   StringMap<std::string> ToolToOutLang;
925
926   FillInToolToLang(ToolDescs, ToolToInLang, ToolToOutLang);
927   StringMap<std::string>::iterator IAE = ToolToOutLang.end();
928   StringMap<StringSet<> >::iterator IBE = ToolToInLang.end();
929
930   for (RecordVector::const_iterator B = EdgeVector.begin(),
931          E = EdgeVector.end(); B != E; ++B) {
932     const Record* Edge = *B;
933     const std::string& NodeA = Edge->getValueAsString("a");
934     const std::string& NodeB = Edge->getValueAsString("b");
935     StringMap<std::string>::iterator IA = ToolToOutLang.find(NodeA);
936     StringMap<StringSet<> >::iterator IB = ToolToInLang.find(NodeB);
937
938     if (NodeA != "root") {
939       if (IA != IAE && IB != IBE && IB->second.count(IA->second) == 0)
940         throw "Edge " + NodeA + "->" + NodeB
941           + ": output->input language mismatch";
942     }
943
944     if (NodeB == "root")
945       throw std::string("Edges back to the root are not allowed!");
946   }
947 }
948
949 /// WalkCase - Walks the 'case' expression DAG and invokes
950 /// TestCallback on every test, and StatementCallback on every
951 /// statement. Handles 'case' nesting, but not the 'and' and 'or'
952 /// combinators (that is, they are passed directly to TestCallback).
953 /// TestCallback must have type 'void TestCallback(const DagInit*, unsigned
954 /// IndentLevel, bool FirstTest)'.
955 /// StatementCallback must have type 'void StatementCallback(const Init*,
956 /// unsigned IndentLevel)'.
957 template <typename F1, typename F2>
958 void WalkCase(const Init* Case, F1 TestCallback, F2 StatementCallback,
959               unsigned IndentLevel = 0)
960 {
961   const DagInit& d = InitPtrToDag(Case);
962
963   // Error checks.
964   if (GetOperatorName(d) != "case")
965     throw std::string("WalkCase should be invoked only on 'case' expressions!");
966
967   if (d.getNumArgs() < 2)
968     throw "There should be at least one clause in the 'case' expression:\n"
969       + d.getAsString();
970
971   // Main loop.
972   bool even = false;
973   const unsigned numArgs = d.getNumArgs();
974   unsigned i = 1;
975   for (DagInit::const_arg_iterator B = d.arg_begin(), E = d.arg_end();
976        B != E; ++B) {
977     Init* arg = *B;
978
979     if (!even)
980     {
981       // Handle test.
982       const DagInit& Test = InitPtrToDag(arg);
983
984       if (GetOperatorName(Test) == "default" && (i+1 != numArgs))
985         throw std::string("The 'default' clause should be the last in the"
986                           "'case' construct!");
987       if (i == numArgs)
988         throw "Case construct handler: no corresponding action "
989           "found for the test " + Test.getAsString() + '!';
990
991       TestCallback(&Test, IndentLevel, (i == 1));
992     }
993     else
994     {
995       if (dynamic_cast<DagInit*>(arg)
996           && GetOperatorName(static_cast<DagInit*>(arg)) == "case") {
997         // Nested 'case'.
998         WalkCase(arg, TestCallback, StatementCallback, IndentLevel + Indent1);
999       }
1000
1001       // Handle statement.
1002       StatementCallback(arg, IndentLevel);
1003     }
1004
1005     ++i;
1006     even = !even;
1007   }
1008 }
1009
1010 /// ExtractOptionNames - A helper function object used by
1011 /// CheckForSuperfluousOptions() to walk the 'case' DAG.
1012 class ExtractOptionNames {
1013   llvm::StringSet<>& OptionNames_;
1014
1015   void processDag(const Init* Statement) {
1016     const DagInit& Stmt = InitPtrToDag(Statement);
1017     const std::string& ActionName = GetOperatorName(Stmt);
1018     if (ActionName == "forward" || ActionName == "forward_as" ||
1019         ActionName == "unpack_values" || ActionName == "switch_on" ||
1020         ActionName == "parameter_equals" || ActionName == "element_in_list" ||
1021         ActionName == "not_empty" || ActionName == "empty") {
1022       checkNumberOfArguments(&Stmt, 1);
1023       const std::string& Name = InitPtrToString(Stmt.getArg(0));
1024       OptionNames_.insert(Name);
1025     }
1026     else if (ActionName == "and" || ActionName == "or") {
1027       for (unsigned i = 0, NumArgs = Stmt.getNumArgs(); i < NumArgs; ++i) {
1028         this->processDag(Stmt.getArg(i));
1029       }
1030     }
1031   }
1032
1033 public:
1034   ExtractOptionNames(llvm::StringSet<>& OptionNames) : OptionNames_(OptionNames)
1035   {}
1036
1037   void operator()(const Init* Statement) {
1038     if (typeid(*Statement) == typeid(ListInit)) {
1039       const ListInit& DagList = *static_cast<const ListInit*>(Statement);
1040       for (ListInit::const_iterator B = DagList.begin(), E = DagList.end();
1041            B != E; ++B)
1042         this->processDag(*B);
1043     }
1044     else {
1045       this->processDag(Statement);
1046     }
1047   }
1048
1049   void operator()(const DagInit* Test, unsigned, bool) {
1050     this->operator()(Test);
1051   }
1052   void operator()(const Init* Statement, unsigned) {
1053     this->operator()(Statement);
1054   }
1055 };
1056
1057 /// CheckForSuperfluousOptions - Check that there are no side
1058 /// effect-free options (specified only in the OptionList). Otherwise,
1059 /// output a warning.
1060 void CheckForSuperfluousOptions (const RecordVector& Edges,
1061                                  const ToolDescriptions& ToolDescs,
1062                                  const OptionDescriptions& OptDescs) {
1063   llvm::StringSet<> nonSuperfluousOptions;
1064
1065   // Add all options mentioned in the ToolDesc.Actions to the set of
1066   // non-superfluous options.
1067   for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
1068          E = ToolDescs.end(); B != E; ++B) {
1069     const ToolDescription& TD = *(*B);
1070     ExtractOptionNames Callback(nonSuperfluousOptions);
1071     if (TD.Actions)
1072       WalkCase(TD.Actions, Callback, Callback);
1073   }
1074
1075   // Add all options mentioned in the 'case' clauses of the
1076   // OptionalEdges of the compilation graph to the set of
1077   // non-superfluous options.
1078   for (RecordVector::const_iterator B = Edges.begin(), E = Edges.end();
1079        B != E; ++B) {
1080     const Record* Edge = *B;
1081     DagInit* Weight = Edge->getValueAsDag("weight");
1082
1083     if (!isDagEmpty(Weight))
1084       WalkCase(Weight, ExtractOptionNames(nonSuperfluousOptions), Id());
1085   }
1086
1087   // Check that all options in OptDescs belong to the set of
1088   // non-superfluous options.
1089   for (OptionDescriptions::const_iterator B = OptDescs.begin(),
1090          E = OptDescs.end(); B != E; ++B) {
1091     const OptionDescription& Val = B->second;
1092     if (!nonSuperfluousOptions.count(Val.Name)
1093         && Val.Type != OptionType::Alias)
1094       llvm::errs() << "Warning: option '-" << Val.Name << "' has no effect! "
1095         "Probable cause: this option is specified only in the OptionList.\n";
1096   }
1097 }
1098
1099 /// EmitCaseTest0Args - Helper function used by EmitCaseConstructHandler().
1100 bool EmitCaseTest0Args(const std::string& TestName, raw_ostream& O) {
1101   if (TestName == "single_input_file") {
1102     O << "InputFilenames.size() == 1";
1103     return true;
1104   }
1105   else if (TestName == "multiple_input_files") {
1106     O << "InputFilenames.size() > 1";
1107     return true;
1108   }
1109
1110   return false;
1111 }
1112
1113 /// EmitListTest - Helper function used by EmitCaseTest1ArgList().
1114 template <typename F>
1115 void EmitListTest(const ListInit& L, const char* LogicOp,
1116                   F Callback, raw_ostream& O)
1117 {
1118   // This is a lot like EmitLogicalOperationTest, but works on ListInits instead
1119   // of Dags...
1120   bool isFirst = true;
1121   for (ListInit::const_iterator B = L.begin(), E = L.end(); B != E; ++B) {
1122     if (isFirst)
1123       isFirst = false;
1124     else
1125       O << " || ";
1126     Callback(InitPtrToString(*B), O);
1127   }
1128 }
1129
1130 // Callbacks for use with EmitListTest.
1131
1132 class EmitSwitchOn {
1133   const OptionDescriptions& OptDescs_;
1134 public:
1135   EmitSwitchOn(const OptionDescriptions& OptDescs) : OptDescs_(OptDescs)
1136   {}
1137
1138   void operator()(const std::string& OptName, raw_ostream& O) const {
1139     const OptionDescription& OptDesc = OptDescs_.FindSwitch(OptName);
1140     O << OptDesc.GenVariableName();
1141   }
1142 };
1143
1144 class EmitEmptyTest {
1145   bool EmitNegate_;
1146   const OptionDescriptions& OptDescs_;
1147 public:
1148   EmitEmptyTest(bool EmitNegate, const OptionDescriptions& OptDescs)
1149     : EmitNegate_(EmitNegate), OptDescs_(OptDescs)
1150   {}
1151
1152   void operator()(const std::string& OptName, raw_ostream& O) const {
1153     const char* Neg = (EmitNegate_ ? "!" : "");
1154     if (OptName == "o") {
1155       O << Neg << "OutputFilename.empty()";
1156     }
1157     else {
1158       const OptionDescription& OptDesc = OptDescs_.FindListOrParameter(OptName);
1159       O << Neg << OptDesc.GenVariableName() << ".empty()";
1160     }
1161   }
1162 };
1163
1164
1165 /// EmitCaseTest1ArgList - Helper function used by EmitCaseTest1Arg();
1166 bool EmitCaseTest1ArgList(const std::string& TestName,
1167                           const DagInit& d,
1168                           const OptionDescriptions& OptDescs,
1169                           raw_ostream& O) {
1170   const ListInit& L = *static_cast<ListInit*>(d.getArg(0));
1171
1172   if (TestName == "any_switch_on") {
1173     EmitListTest(L, "||", EmitSwitchOn(OptDescs), O);
1174     return true;
1175   }
1176   else if (TestName == "switch_on") {
1177     EmitListTest(L, "&&", EmitSwitchOn(OptDescs), O);
1178     return true;
1179   }
1180   else if (TestName == "any_not_empty") {
1181     EmitListTest(L, "||", EmitEmptyTest(true, OptDescs), O);
1182     return true;
1183   }
1184   else if (TestName == "any_empty") {
1185     EmitListTest(L, "||", EmitEmptyTest(false, OptDescs), O);
1186     return true;
1187   }
1188   else if (TestName == "not_empty") {
1189     EmitListTest(L, "&&", EmitEmptyTest(true, OptDescs), O);
1190     return true;
1191   }
1192   else if (TestName == "empty") {
1193     EmitListTest(L, "&&", EmitEmptyTest(false, OptDescs), O);
1194     return true;
1195   }
1196
1197   return false;
1198 }
1199
1200 /// EmitCaseTest1ArgStr - Helper function used by EmitCaseTest1Arg();
1201 bool EmitCaseTest1ArgStr(const std::string& TestName,
1202                          const DagInit& d,
1203                          const OptionDescriptions& OptDescs,
1204                          raw_ostream& O) {
1205   const std::string& OptName = InitPtrToString(d.getArg(0));
1206
1207   if (TestName == "switch_on") {
1208     apply(EmitSwitchOn(OptDescs), OptName, O);
1209     return true;
1210   }
1211   else if (TestName == "input_languages_contain") {
1212     O << "InLangs.count(\"" << OptName << "\") != 0";
1213     return true;
1214   }
1215   else if (TestName == "in_language") {
1216     // This works only for single-argument Tool::GenerateAction. Join
1217     // tools can process several files in different languages simultaneously.
1218
1219     // TODO: make this work with Edge::Weight (if possible).
1220     O << "LangMap.GetLanguage(inFile) == \"" << OptName << '\"';
1221     return true;
1222   }
1223   else if (TestName == "not_empty" || TestName == "empty") {
1224     bool EmitNegate = (TestName == "not_empty");
1225     apply(EmitEmptyTest(EmitNegate, OptDescs), OptName, O);
1226     return true;
1227   }
1228
1229   return false;
1230 }
1231
1232 /// EmitCaseTest1Arg - Helper function used by EmitCaseConstructHandler();
1233 bool EmitCaseTest1Arg(const std::string& TestName,
1234                       const DagInit& d,
1235                       const OptionDescriptions& OptDescs,
1236                       raw_ostream& O) {
1237   checkNumberOfArguments(&d, 1);
1238   if (typeid(*d.getArg(0)) == typeid(ListInit))
1239     return EmitCaseTest1ArgList(TestName, d, OptDescs, O);
1240   else
1241     return EmitCaseTest1ArgStr(TestName, d, OptDescs, O);
1242 }
1243
1244 /// EmitCaseTest2Args - Helper function used by EmitCaseConstructHandler().
1245 bool EmitCaseTest2Args(const std::string& TestName,
1246                        const DagInit& d,
1247                        unsigned IndentLevel,
1248                        const OptionDescriptions& OptDescs,
1249                        raw_ostream& O) {
1250   checkNumberOfArguments(&d, 2);
1251   const std::string& OptName = InitPtrToString(d.getArg(0));
1252   const std::string& OptArg = InitPtrToString(d.getArg(1));
1253
1254   if (TestName == "parameter_equals") {
1255     const OptionDescription& OptDesc = OptDescs.FindParameter(OptName);
1256     O << OptDesc.GenVariableName() << " == \"" << OptArg << "\"";
1257     return true;
1258   }
1259   else if (TestName == "element_in_list") {
1260     const OptionDescription& OptDesc = OptDescs.FindList(OptName);
1261     const std::string& VarName = OptDesc.GenVariableName();
1262     O << "std::find(" << VarName << ".begin(),\n";
1263     O.indent(IndentLevel + Indent1)
1264       << VarName << ".end(), \""
1265       << OptArg << "\") != " << VarName << ".end()";
1266     return true;
1267   }
1268
1269   return false;
1270 }
1271
1272 // Forward declaration.
1273 // EmitLogicalOperationTest and EmitCaseTest are mutually recursive.
1274 void EmitCaseTest(const DagInit& d, unsigned IndentLevel,
1275                   const OptionDescriptions& OptDescs,
1276                   raw_ostream& O);
1277
1278 /// EmitLogicalOperationTest - Helper function used by
1279 /// EmitCaseConstructHandler.
1280 void EmitLogicalOperationTest(const DagInit& d, const char* LogicOp,
1281                               unsigned IndentLevel,
1282                               const OptionDescriptions& OptDescs,
1283                               raw_ostream& O) {
1284   O << '(';
1285   for (unsigned j = 0, NumArgs = d.getNumArgs(); j < NumArgs; ++j) {
1286     const DagInit& InnerTest = InitPtrToDag(d.getArg(j));
1287     EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
1288     if (j != NumArgs - 1) {
1289       O << ")\n";
1290       O.indent(IndentLevel + Indent1) << ' ' << LogicOp << " (";
1291     }
1292     else {
1293       O << ')';
1294     }
1295   }
1296 }
1297
1298 void EmitLogicalNot(const DagInit& d, unsigned IndentLevel,
1299                     const OptionDescriptions& OptDescs, raw_ostream& O)
1300 {
1301   checkNumberOfArguments(&d, 1);
1302   const DagInit& InnerTest = InitPtrToDag(d.getArg(0));
1303   O << "! (";
1304   EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
1305   O << ")";
1306 }
1307
1308 /// EmitCaseTest - Helper function used by EmitCaseConstructHandler.
1309 void EmitCaseTest(const DagInit& d, unsigned IndentLevel,
1310                   const OptionDescriptions& OptDescs,
1311                   raw_ostream& O) {
1312   const std::string& TestName = GetOperatorName(d);
1313
1314   if (TestName == "and")
1315     EmitLogicalOperationTest(d, "&&", IndentLevel, OptDescs, O);
1316   else if (TestName == "or")
1317     EmitLogicalOperationTest(d, "||", IndentLevel, OptDescs, O);
1318   else if (TestName == "not")
1319     EmitLogicalNot(d, IndentLevel, OptDescs, O);
1320   else if (EmitCaseTest0Args(TestName, O))
1321     return;
1322   else if (EmitCaseTest1Arg(TestName, d, OptDescs, O))
1323     return;
1324   else if (EmitCaseTest2Args(TestName, d, IndentLevel, OptDescs, O))
1325     return;
1326   else
1327     throw TestName + ": unknown edge property!";
1328 }
1329
1330
1331 /// EmitCaseTestCallback - Callback used by EmitCaseConstructHandler.
1332 class EmitCaseTestCallback {
1333   bool EmitElseIf_;
1334   const OptionDescriptions& OptDescs_;
1335   raw_ostream& O_;
1336 public:
1337
1338   EmitCaseTestCallback(bool EmitElseIf,
1339                        const OptionDescriptions& OptDescs, raw_ostream& O)
1340     : EmitElseIf_(EmitElseIf), OptDescs_(OptDescs), O_(O)
1341   {}
1342
1343   void operator()(const DagInit* Test, unsigned IndentLevel, bool FirstTest)
1344   {
1345     if (GetOperatorName(Test) == "default") {
1346       O_.indent(IndentLevel) << "else {\n";
1347     }
1348     else {
1349       O_.indent(IndentLevel)
1350         << ((!FirstTest && EmitElseIf_) ? "else if (" : "if (");
1351       EmitCaseTest(*Test, IndentLevel, OptDescs_, O_);
1352       O_ << ") {\n";
1353     }
1354   }
1355 };
1356
1357 /// EmitCaseStatementCallback - Callback used by EmitCaseConstructHandler.
1358 template <typename F>
1359 class EmitCaseStatementCallback {
1360   F Callback_;
1361   raw_ostream& O_;
1362 public:
1363
1364   EmitCaseStatementCallback(F Callback, raw_ostream& O)
1365     : Callback_(Callback), O_(O)
1366   {}
1367
1368   void operator() (const Init* Statement, unsigned IndentLevel) {
1369
1370     // Ignore nested 'case' DAG.
1371     if (!(dynamic_cast<const DagInit*>(Statement) &&
1372           GetOperatorName(static_cast<const DagInit*>(Statement)) == "case")) {
1373       if (typeid(*Statement) == typeid(ListInit)) {
1374         const ListInit& DagList = *static_cast<const ListInit*>(Statement);
1375         for (ListInit::const_iterator B = DagList.begin(), E = DagList.end();
1376              B != E; ++B)
1377           Callback_(*B, (IndentLevel + Indent1), O_);
1378       }
1379       else {
1380         Callback_(Statement, (IndentLevel + Indent1), O_);
1381       }
1382     }
1383     O_.indent(IndentLevel) << "}\n";
1384   }
1385
1386 };
1387
1388 /// EmitCaseConstructHandler - Emit code that handles the 'case'
1389 /// construct. Takes a function object that should emit code for every case
1390 /// clause. Implemented on top of WalkCase.
1391 /// Callback's type is void F(Init* Statement, unsigned IndentLevel,
1392 /// raw_ostream& O).
1393 /// EmitElseIf parameter controls the type of condition that is emitted ('if
1394 /// (..) {..} else if (..) {} .. else {..}' vs. 'if (..) {..} if(..)  {..}
1395 /// .. else {..}').
1396 template <typename F>
1397 void EmitCaseConstructHandler(const Init* Case, unsigned IndentLevel,
1398                               F Callback, bool EmitElseIf,
1399                               const OptionDescriptions& OptDescs,
1400                               raw_ostream& O) {
1401   WalkCase(Case, EmitCaseTestCallback(EmitElseIf, OptDescs, O),
1402            EmitCaseStatementCallback<F>(Callback, O), IndentLevel);
1403 }
1404
1405 /// TokenizeCmdline - converts from "$CALL(HookName, 'Arg1', 'Arg2')/path" to
1406 /// ["$CALL(", "HookName", "Arg1", "Arg2", ")/path"] .
1407 /// Helper function used by EmitCmdLineVecFill and.
1408 void TokenizeCmdline(const std::string& CmdLine, StrVector& Out) {
1409   const char* Delimiters = " \t\n\v\f\r";
1410   enum TokenizerState
1411   { Normal, SpecialCommand, InsideSpecialCommand, InsideQuotationMarks }
1412   cur_st  = Normal;
1413
1414   if (CmdLine.empty())
1415     return;
1416   Out.push_back("");
1417
1418   std::string::size_type B = CmdLine.find_first_not_of(Delimiters),
1419     E = CmdLine.size();
1420
1421   for (; B != E; ++B) {
1422     char cur_ch = CmdLine[B];
1423
1424     switch (cur_st) {
1425     case Normal:
1426       if (cur_ch == '$') {
1427         cur_st = SpecialCommand;
1428         break;
1429       }
1430       if (oneOf(Delimiters, cur_ch)) {
1431         // Skip whitespace
1432         B = CmdLine.find_first_not_of(Delimiters, B);
1433         if (B == std::string::npos) {
1434           B = E-1;
1435           continue;
1436         }
1437         --B;
1438         Out.push_back("");
1439         continue;
1440       }
1441       break;
1442
1443
1444     case SpecialCommand:
1445       if (oneOf(Delimiters, cur_ch)) {
1446         cur_st = Normal;
1447         Out.push_back("");
1448         continue;
1449       }
1450       if (cur_ch == '(') {
1451         Out.push_back("");
1452         cur_st = InsideSpecialCommand;
1453         continue;
1454       }
1455       break;
1456
1457     case InsideSpecialCommand:
1458       if (oneOf(Delimiters, cur_ch)) {
1459         continue;
1460       }
1461       if (cur_ch == '\'') {
1462         cur_st = InsideQuotationMarks;
1463         Out.push_back("");
1464         continue;
1465       }
1466       if (cur_ch == ')') {
1467         cur_st = Normal;
1468         Out.push_back("");
1469       }
1470       if (cur_ch == ',') {
1471         continue;
1472       }
1473
1474       break;
1475
1476     case InsideQuotationMarks:
1477       if (cur_ch == '\'') {
1478         cur_st = InsideSpecialCommand;
1479         continue;
1480       }
1481       break;
1482     }
1483
1484     Out.back().push_back(cur_ch);
1485   }
1486 }
1487
1488 /// SubstituteSpecialCommands - Perform string substitution for $CALL
1489 /// and $ENV. Helper function used by EmitCmdLineVecFill().
1490 StrVector::const_iterator SubstituteSpecialCommands
1491 (StrVector::const_iterator Pos, StrVector::const_iterator End, raw_ostream& O)
1492 {
1493
1494   const std::string& cmd = *Pos;
1495
1496   if (cmd == "$CALL") {
1497     checkedIncrement(Pos, End, "Syntax error in $CALL invocation!");
1498     const std::string& CmdName = *Pos;
1499
1500     if (CmdName == ")")
1501       throw std::string("$CALL invocation: empty argument list!");
1502
1503     O << "hooks::";
1504     O << CmdName << "(";
1505
1506
1507     bool firstIteration = true;
1508     while (true) {
1509       checkedIncrement(Pos, End, "Syntax error in $CALL invocation!");
1510       const std::string& Arg = *Pos;
1511       assert(Arg.size() != 0);
1512
1513       if (Arg[0] == ')')
1514         break;
1515
1516       if (firstIteration)
1517         firstIteration = false;
1518       else
1519         O << ", ";
1520
1521       O << '"' << Arg << '"';
1522     }
1523
1524     O << ')';
1525
1526   }
1527   else if (cmd == "$ENV") {
1528     checkedIncrement(Pos, End, "Syntax error in $ENV invocation!");
1529     const std::string& EnvName = *Pos;
1530
1531     if (EnvName == ")")
1532       throw "$ENV invocation: empty argument list!";
1533
1534     O << "checkCString(std::getenv(\"";
1535     O << EnvName;
1536     O << "\"))";
1537
1538     checkedIncrement(Pos, End, "Syntax error in $ENV invocation!");
1539   }
1540   else {
1541     throw "Unknown special command: " + cmd;
1542   }
1543
1544   const std::string& Leftover = *Pos;
1545   assert(Leftover.at(0) == ')');
1546   if (Leftover.size() != 1)
1547     O << " + std::string(\"" << (Leftover.c_str() + 1) << "\")";
1548
1549   return Pos;
1550 }
1551
1552 /// EmitCmdLineVecFill - Emit code that fills in the command line
1553 /// vector. Helper function used by EmitGenerateActionMethod().
1554 void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName,
1555                         bool IsJoin, unsigned IndentLevel,
1556                         raw_ostream& O) {
1557   StrVector StrVec;
1558   TokenizeCmdline(InitPtrToString(CmdLine), StrVec);
1559
1560   if (StrVec.empty())
1561     throw "Tool '" + ToolName + "' has empty command line!";
1562
1563   StrVector::const_iterator I = StrVec.begin(), E = StrVec.end();
1564
1565   // If there is a hook invocation on the place of the first command, skip it.
1566   assert(!StrVec[0].empty());
1567   if (StrVec[0][0] == '$') {
1568     while (I != E && (*I)[0] != ')' )
1569       ++I;
1570
1571     // Skip the ')' symbol.
1572     ++I;
1573   }
1574   else {
1575     ++I;
1576   }
1577
1578   bool hasINFILE = false;
1579
1580   for (; I != E; ++I) {
1581     const std::string& cmd = *I;
1582     assert(!cmd.empty());
1583     O.indent(IndentLevel);
1584     if (cmd.at(0) == '$') {
1585       if (cmd == "$INFILE") {
1586         hasINFILE = true;
1587         if (IsJoin) {
1588           O << "for (PathVector::const_iterator B = inFiles.begin()"
1589             << ", E = inFiles.end();\n";
1590           O.indent(IndentLevel) << "B != E; ++B)\n";
1591           O.indent(IndentLevel + Indent1) << "vec.push_back(B->str());\n";
1592         }
1593         else {
1594           O << "vec.push_back(inFile.str());\n";
1595         }
1596       }
1597       else if (cmd == "$OUTFILE") {
1598         O << "vec.push_back(\"\");\n";
1599         O.indent(IndentLevel) << "out_file_index = vec.size()-1;\n";
1600       }
1601       else {
1602         O << "vec.push_back(";
1603         I = SubstituteSpecialCommands(I, E, O);
1604         O << ");\n";
1605       }
1606     }
1607     else {
1608       O << "vec.push_back(\"" << cmd << "\");\n";
1609     }
1610   }
1611   if (!hasINFILE)
1612     throw "Tool '" + ToolName + "' doesn't take any input!";
1613
1614   O.indent(IndentLevel) << "cmd = ";
1615   if (StrVec[0][0] == '$')
1616     SubstituteSpecialCommands(StrVec.begin(), StrVec.end(), O);
1617   else
1618     O << '"' << StrVec[0] << '"';
1619   O << ";\n";
1620 }
1621
1622 /// EmitCmdLineVecFillCallback - A function object wrapper around
1623 /// EmitCmdLineVecFill(). Used by EmitGenerateActionMethod() as an
1624 /// argument to EmitCaseConstructHandler().
1625 class EmitCmdLineVecFillCallback {
1626   bool IsJoin;
1627   const std::string& ToolName;
1628  public:
1629   EmitCmdLineVecFillCallback(bool J, const std::string& TN)
1630     : IsJoin(J), ToolName(TN) {}
1631
1632   void operator()(const Init* Statement, unsigned IndentLevel,
1633                   raw_ostream& O) const
1634   {
1635     EmitCmdLineVecFill(Statement, ToolName, IsJoin, IndentLevel, O);
1636   }
1637 };
1638
1639 /// EmitForwardOptionPropertyHandlingCode - Helper function used to
1640 /// implement EmitActionHandler. Emits code for
1641 /// handling the (forward) and (forward_as) option properties.
1642 void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
1643                                             unsigned IndentLevel,
1644                                             const std::string& NewName,
1645                                             raw_ostream& O) {
1646   const std::string& Name = NewName.empty()
1647     ? ("-" + D.Name)
1648     : NewName;
1649   unsigned IndentLevel1 = IndentLevel + Indent1;
1650
1651   switch (D.Type) {
1652   case OptionType::Switch:
1653     O.indent(IndentLevel) << "vec.push_back(\"" << Name << "\");\n";
1654     break;
1655   case OptionType::Parameter:
1656     O.indent(IndentLevel) << "vec.push_back(\"" << Name << "\");\n";
1657     O.indent(IndentLevel) << "vec.push_back(" << D.GenVariableName() << ");\n";
1658     break;
1659   case OptionType::Prefix:
1660     O.indent(IndentLevel) << "vec.push_back(\"" << Name << "\" + "
1661                           << D.GenVariableName() << ");\n";
1662     break;
1663   case OptionType::PrefixList:
1664     O.indent(IndentLevel)
1665       << "for (" << D.GenTypeDeclaration()
1666       << "::iterator B = " << D.GenVariableName() << ".begin(),\n";
1667     O.indent(IndentLevel)
1668       << "E = " << D.GenVariableName() << ".end(); B != E;) {\n";
1669     O.indent(IndentLevel1) << "vec.push_back(\"" << Name << "\" + " << "*B);\n";
1670     O.indent(IndentLevel1) << "++B;\n";
1671
1672     for (int i = 1, j = D.MultiVal; i < j; ++i) {
1673       O.indent(IndentLevel1) << "vec.push_back(*B);\n";
1674       O.indent(IndentLevel1) << "++B;\n";
1675     }
1676
1677     O.indent(IndentLevel) << "}\n";
1678     break;
1679   case OptionType::ParameterList:
1680     O.indent(IndentLevel)
1681       << "for (" << D.GenTypeDeclaration() << "::iterator B = "
1682       << D.GenVariableName() << ".begin(),\n";
1683     O.indent(IndentLevel) << "E = " << D.GenVariableName()
1684                           << ".end() ; B != E;) {\n";
1685     O.indent(IndentLevel1) << "vec.push_back(\"" << Name << "\");\n";
1686
1687     for (int i = 0, j = D.MultiVal; i < j; ++i) {
1688       O.indent(IndentLevel1) << "vec.push_back(*B);\n";
1689       O.indent(IndentLevel1) << "++B;\n";
1690     }
1691
1692     O.indent(IndentLevel) << "}\n";
1693     break;
1694   case OptionType::Alias:
1695   default:
1696     throw std::string("Aliases are not allowed in tool option descriptions!");
1697   }
1698 }
1699
1700 /// ActionHandlingCallbackBase - Base class of EmitActionHandlersCallback and
1701 /// EmitPreprocessOptionsCallback.
1702 struct ActionHandlingCallbackBase {
1703
1704   void onErrorDag(const DagInit& d,
1705                   unsigned IndentLevel, raw_ostream& O) const
1706   {
1707     O.indent(IndentLevel)
1708       << "throw std::runtime_error(\"" <<
1709       (d.getNumArgs() >= 1 ? InitPtrToString(d.getArg(0))
1710        : "Unknown error!")
1711       << "\");\n";
1712   }
1713
1714   void onWarningDag(const DagInit& d,
1715                     unsigned IndentLevel, raw_ostream& O) const
1716   {
1717     checkNumberOfArguments(&d, 1);
1718     O.indent(IndentLevel) << "llvm::errs() << \""
1719                           << InitPtrToString(d.getArg(0)) << "\";\n";
1720   }
1721
1722 };
1723
1724 /// EmitActionHandlersCallback - Emit code that handles actions. Used by
1725 /// EmitGenerateActionMethod() as an argument to EmitCaseConstructHandler().
1726 class EmitActionHandlersCallback : ActionHandlingCallbackBase {
1727   const OptionDescriptions& OptDescs;
1728
1729   void processActionDag(const Init* Statement, unsigned IndentLevel,
1730                         raw_ostream& O) const
1731   {
1732     const DagInit& Dag = InitPtrToDag(Statement);
1733     const std::string& ActionName = GetOperatorName(Dag);
1734
1735     if (ActionName == "append_cmd") {
1736       checkNumberOfArguments(&Dag, 1);
1737       const std::string& Cmd = InitPtrToString(Dag.getArg(0));
1738       StrVector Out;
1739       llvm::SplitString(Cmd, Out);
1740
1741       for (StrVector::const_iterator B = Out.begin(), E = Out.end();
1742            B != E; ++B)
1743         O.indent(IndentLevel) << "vec.push_back(\"" << *B << "\");\n";
1744     }
1745     else if (ActionName == "error") {
1746       this->onErrorDag(Dag, IndentLevel, O);
1747     }
1748     else if (ActionName == "warning") {
1749       this->onWarningDag(Dag, IndentLevel, O);
1750     }
1751     else if (ActionName == "forward") {
1752       checkNumberOfArguments(&Dag, 1);
1753       const std::string& Name = InitPtrToString(Dag.getArg(0));
1754       EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name),
1755                                             IndentLevel, "", O);
1756     }
1757     else if (ActionName == "forward_as") {
1758       checkNumberOfArguments(&Dag, 2);
1759       const std::string& Name = InitPtrToString(Dag.getArg(0));
1760       const std::string& NewName = InitPtrToString(Dag.getArg(1));
1761       EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name),
1762                                             IndentLevel, NewName, O);
1763     }
1764     else if (ActionName == "output_suffix") {
1765       checkNumberOfArguments(&Dag, 1);
1766       const std::string& OutSuf = InitPtrToString(Dag.getArg(0));
1767       O.indent(IndentLevel) << "output_suffix = \"" << OutSuf << "\";\n";
1768     }
1769     else if (ActionName == "stop_compilation") {
1770       O.indent(IndentLevel) << "stop_compilation = true;\n";
1771     }
1772     else if (ActionName == "unpack_values") {
1773       checkNumberOfArguments(&Dag, 1);
1774       const std::string& Name = InitPtrToString(Dag.getArg(0));
1775       const OptionDescription& D = OptDescs.FindOption(Name);
1776
1777       if (D.isMultiVal())
1778         throw std::string("Can't use unpack_values with multi-valued options!");
1779
1780       if (D.isList()) {
1781         O.indent(IndentLevel)
1782           << "for (" << D.GenTypeDeclaration()
1783           << "::iterator B = " << D.GenVariableName() << ".begin(),\n";
1784         O.indent(IndentLevel)
1785           << "E = " << D.GenVariableName() << ".end(); B != E; ++B)\n";
1786         O.indent(IndentLevel + Indent1)
1787           << "llvm::SplitString(*B, vec, \",\");\n";
1788       }
1789       else if (D.isParameter()){
1790         O.indent(IndentLevel) << "llvm::SplitString("
1791                               << D.GenVariableName() << ", vec, \",\");\n";
1792       }
1793       else {
1794         throw "Option '" + D.Name +
1795           "': switches can't have the 'unpack_values' property!";
1796       }
1797     }
1798     else {
1799       throw "Unknown action name: " + ActionName + "!";
1800     }
1801   }
1802  public:
1803   EmitActionHandlersCallback(const OptionDescriptions& OD)
1804     : OptDescs(OD) {}
1805
1806   void operator()(const Init* Statement,
1807                   unsigned IndentLevel, raw_ostream& O) const
1808   {
1809     this->processActionDag(Statement, IndentLevel, O);
1810   }
1811 };
1812
1813 bool IsOutFileIndexCheckRequiredStr (const Init* CmdLine) {
1814   StrVector StrVec;
1815   TokenizeCmdline(InitPtrToString(CmdLine), StrVec);
1816
1817   for (StrVector::const_iterator I = StrVec.begin(), E = StrVec.end();
1818        I != E; ++I) {
1819     if (*I == "$OUTFILE")
1820       return false;
1821   }
1822
1823   return true;
1824 }
1825
1826 class IsOutFileIndexCheckRequiredStrCallback {
1827   bool* ret_;
1828
1829 public:
1830   IsOutFileIndexCheckRequiredStrCallback(bool* ret) : ret_(ret)
1831   {}
1832
1833   void operator()(const Init* CmdLine) {
1834     // Ignore nested 'case' DAG.
1835     if (typeid(*CmdLine) == typeid(DagInit))
1836       return;
1837
1838     if (IsOutFileIndexCheckRequiredStr(CmdLine))
1839       *ret_ = true;
1840   }
1841
1842   void operator()(const DagInit* Test, unsigned, bool) {
1843     this->operator()(Test);
1844   }
1845   void operator()(const Init* Statement, unsigned) {
1846     this->operator()(Statement);
1847   }
1848 };
1849
1850 bool IsOutFileIndexCheckRequiredCase (Init* CmdLine) {
1851   bool ret = false;
1852   WalkCase(CmdLine, Id(), IsOutFileIndexCheckRequiredStrCallback(&ret));
1853   return ret;
1854 }
1855
1856 /// IsOutFileIndexCheckRequired - Should we emit an "out_file_index != -1" check
1857 /// in EmitGenerateActionMethod() ?
1858 bool IsOutFileIndexCheckRequired (Init* CmdLine) {
1859   if (typeid(*CmdLine) == typeid(StringInit))
1860     return IsOutFileIndexCheckRequiredStr(CmdLine);
1861   else
1862     return IsOutFileIndexCheckRequiredCase(CmdLine);
1863 }
1864
1865 // EmitGenerateActionMethod - Emit either a normal or a "join" version of the
1866 // Tool::GenerateAction() method.
1867 void EmitGenerateActionMethod (const ToolDescription& D,
1868                                const OptionDescriptions& OptDescs,
1869                                bool IsJoin, raw_ostream& O) {
1870   if (IsJoin)
1871     O.indent(Indent1) << "Action GenerateAction(const PathVector& inFiles,\n";
1872   else
1873     O.indent(Indent1) << "Action GenerateAction(const sys::Path& inFile,\n";
1874
1875   O.indent(Indent2) << "bool HasChildren,\n";
1876   O.indent(Indent2) << "const llvm::sys::Path& TempDir,\n";
1877   O.indent(Indent2) << "const InputLanguagesSet& InLangs,\n";
1878   O.indent(Indent2) << "const LanguageMap& LangMap) const\n";
1879   O.indent(Indent1) << "{\n";
1880   O.indent(Indent2) << "std::string cmd;\n";
1881   O.indent(Indent2) << "std::vector<std::string> vec;\n";
1882   O.indent(Indent2) << "bool stop_compilation = !HasChildren;\n";
1883   O.indent(Indent2) << "const char* output_suffix = \""
1884                     << D.OutputSuffix << "\";\n";
1885
1886   if (!D.CmdLine)
1887     throw "Tool " + D.Name + " has no cmd_line property!";
1888
1889   bool IndexCheckRequired = IsOutFileIndexCheckRequired(D.CmdLine);
1890   O.indent(Indent2) << "int out_file_index"
1891                     << (IndexCheckRequired ? " = -1" : "")
1892                     << ";\n\n";
1893
1894   // Process the cmd_line property.
1895   if (typeid(*D.CmdLine) == typeid(StringInit))
1896     EmitCmdLineVecFill(D.CmdLine, D.Name, IsJoin, Indent2, O);
1897   else
1898     EmitCaseConstructHandler(D.CmdLine, Indent2,
1899                              EmitCmdLineVecFillCallback(IsJoin, D.Name),
1900                              true, OptDescs, O);
1901
1902   // For every understood option, emit handling code.
1903   if (D.Actions)
1904     EmitCaseConstructHandler(D.Actions, Indent2, EmitActionHandlersCallback(OptDescs),
1905                              false, OptDescs, O);
1906
1907   O << '\n';
1908   O.indent(Indent2)
1909     << "std::string out_file = OutFilename("
1910     << (IsJoin ? "sys::Path(),\n" : "inFile,\n");
1911   O.indent(Indent3) << "TempDir, stop_compilation, output_suffix).str();\n\n";
1912
1913   if (IndexCheckRequired)
1914     O.indent(Indent2) << "if (out_file_index != -1)\n";
1915   O.indent(IndexCheckRequired ? Indent3 : Indent2)
1916     << "vec[out_file_index] = out_file;\n";
1917
1918   // Handle the Sink property.
1919   if (D.isSink()) {
1920     O.indent(Indent2) << "if (!" << SinkOptionName << ".empty()) {\n";
1921     O.indent(Indent3) << "vec.insert(vec.end(), "
1922                       << SinkOptionName << ".begin(), " << SinkOptionName
1923                       << ".end());\n";
1924     O.indent(Indent2) << "}\n";
1925   }
1926
1927   O.indent(Indent2) << "return Action(cmd, vec, stop_compilation, out_file);\n";
1928   O.indent(Indent1) << "}\n\n";
1929 }
1930
1931 /// EmitGenerateActionMethods - Emit two GenerateAction() methods for
1932 /// a given Tool class.
1933 void EmitGenerateActionMethods (const ToolDescription& ToolDesc,
1934                                 const OptionDescriptions& OptDescs,
1935                                 raw_ostream& O) {
1936   if (!ToolDesc.isJoin()) {
1937     O.indent(Indent1) << "Action GenerateAction(const PathVector& inFiles,\n";
1938     O.indent(Indent2) << "bool HasChildren,\n";
1939     O.indent(Indent2) << "const llvm::sys::Path& TempDir,\n";
1940     O.indent(Indent2) << "const InputLanguagesSet& InLangs,\n";
1941     O.indent(Indent2) << "const LanguageMap& LangMap) const\n";
1942     O.indent(Indent1) << "{\n";
1943     O.indent(Indent2) << "throw std::runtime_error(\"" << ToolDesc.Name
1944                       << " is not a Join tool!\");\n";
1945     O.indent(Indent1) << "}\n\n";
1946   }
1947   else {
1948     EmitGenerateActionMethod(ToolDesc, OptDescs, true, O);
1949   }
1950
1951   EmitGenerateActionMethod(ToolDesc, OptDescs, false, O);
1952 }
1953
1954 /// EmitInOutLanguageMethods - Emit the [Input,Output]Language()
1955 /// methods for a given Tool class.
1956 void EmitInOutLanguageMethods (const ToolDescription& D, raw_ostream& O) {
1957   O.indent(Indent1) << "const char** InputLanguages() const {\n";
1958   O.indent(Indent2) << "return InputLanguages_;\n";
1959   O.indent(Indent1) << "}\n\n";
1960
1961   if (D.OutLanguage.empty())
1962     throw "Tool " + D.Name + " has no 'out_language' property!";
1963
1964   O.indent(Indent1) << "const char* OutputLanguage() const {\n";
1965   O.indent(Indent2) << "return \"" << D.OutLanguage << "\";\n";
1966   O.indent(Indent1) << "}\n\n";
1967 }
1968
1969 /// EmitNameMethod - Emit the Name() method for a given Tool class.
1970 void EmitNameMethod (const ToolDescription& D, raw_ostream& O) {
1971   O.indent(Indent1) << "const char* Name() const {\n";
1972   O.indent(Indent2) << "return \"" << D.Name << "\";\n";
1973   O.indent(Indent1) << "}\n\n";
1974 }
1975
1976 /// EmitIsJoinMethod - Emit the IsJoin() method for a given Tool
1977 /// class.
1978 void EmitIsJoinMethod (const ToolDescription& D, raw_ostream& O) {
1979   O.indent(Indent1) << "bool IsJoin() const {\n";
1980   if (D.isJoin())
1981     O.indent(Indent2) << "return true;\n";
1982   else
1983     O.indent(Indent2) << "return false;\n";
1984   O.indent(Indent1) << "}\n\n";
1985 }
1986
1987 /// EmitStaticMemberDefinitions - Emit static member definitions for a
1988 /// given Tool class.
1989 void EmitStaticMemberDefinitions(const ToolDescription& D, raw_ostream& O) {
1990   if (D.InLanguage.empty())
1991     throw "Tool " + D.Name + " has no 'in_language' property!";
1992
1993   O << "const char* " << D.Name << "::InputLanguages_[] = {";
1994   for (StrVector::const_iterator B = D.InLanguage.begin(),
1995          E = D.InLanguage.end(); B != E; ++B)
1996     O << '\"' << *B << "\", ";
1997   O << "0};\n\n";
1998 }
1999
2000 /// EmitToolClassDefinition - Emit a Tool class definition.
2001 void EmitToolClassDefinition (const ToolDescription& D,
2002                               const OptionDescriptions& OptDescs,
2003                               raw_ostream& O) {
2004   if (D.Name == "root")
2005     return;
2006
2007   // Header
2008   O << "class " << D.Name << " : public ";
2009   if (D.isJoin())
2010     O << "JoinTool";
2011   else
2012     O << "Tool";
2013
2014   O << "{\nprivate:\n";
2015   O.indent(Indent1) << "static const char* InputLanguages_[];\n\n";
2016
2017   O << "public:\n";
2018   EmitNameMethod(D, O);
2019   EmitInOutLanguageMethods(D, O);
2020   EmitIsJoinMethod(D, O);
2021   EmitGenerateActionMethods(D, OptDescs, O);
2022
2023   // Close class definition
2024   O << "};\n";
2025
2026   EmitStaticMemberDefinitions(D, O);
2027
2028 }
2029
2030 /// EmitOptionDefinitions - Iterate over a list of option descriptions
2031 /// and emit registration code.
2032 void EmitOptionDefinitions (const OptionDescriptions& descs,
2033                             bool HasSink, bool HasExterns,
2034                             raw_ostream& O)
2035 {
2036   std::vector<OptionDescription> Aliases;
2037
2038   // Emit static cl::Option variables.
2039   for (OptionDescriptions::const_iterator B = descs.begin(),
2040          E = descs.end(); B!=E; ++B) {
2041     const OptionDescription& val = B->second;
2042
2043     if (val.Type == OptionType::Alias) {
2044       Aliases.push_back(val);
2045       continue;
2046     }
2047
2048     if (val.isExtern())
2049       O << "extern ";
2050
2051     O << val.GenTypeDeclaration() << ' '
2052       << val.GenVariableName();
2053
2054     if (val.isExtern()) {
2055       O << ";\n";
2056       continue;
2057     }
2058
2059     O << "(\"" << val.Name << "\"\n";
2060
2061     if (val.Type == OptionType::Prefix || val.Type == OptionType::PrefixList)
2062       O << ", cl::Prefix";
2063
2064     if (val.isRequired()) {
2065       if (val.isList() && !val.isMultiVal())
2066         O << ", cl::OneOrMore";
2067       else
2068         O << ", cl::Required";
2069     }
2070     else if (val.isOneOrMore() && val.isList()) {
2071         O << ", cl::OneOrMore";
2072     }
2073     else if (val.isZeroOrOne() && val.isList()) {
2074         O << ", cl::ZeroOrOne";
2075     }
2076
2077     if (val.isReallyHidden()) {
2078       O << ", cl::ReallyHidden";
2079     }
2080     else if (val.isHidden()) {
2081       O << ", cl::Hidden";
2082     }
2083
2084     if (val.MultiVal > 1)
2085       O << ", cl::multi_val(" << val.MultiVal << ')';
2086
2087     if (val.InitVal) {
2088       const std::string& str = val.InitVal->getAsString();
2089       O << ", cl::init(" << str << ')';
2090     }
2091
2092     if (!val.Help.empty())
2093       O << ", cl::desc(\"" << val.Help << "\")";
2094
2095     O << ");\n\n";
2096   }
2097
2098   // Emit the aliases (they should go after all the 'proper' options).
2099   for (std::vector<OptionDescription>::const_iterator
2100          B = Aliases.begin(), E = Aliases.end(); B != E; ++B) {
2101     const OptionDescription& val = *B;
2102
2103     O << val.GenTypeDeclaration() << ' '
2104       << val.GenVariableName()
2105       << "(\"" << val.Name << '\"';
2106
2107     const OptionDescription& D = descs.FindOption(val.Help);
2108     O << ", cl::aliasopt(" << D.GenVariableName() << ")";
2109
2110     O << ", cl::desc(\"" << "An alias for -" + val.Help  << "\"));\n";
2111   }
2112
2113   // Emit the sink option.
2114   if (HasSink)
2115     O << (HasExterns ? "extern cl" : "cl")
2116       << "::list<std::string> " << SinkOptionName
2117       << (HasExterns ? ";\n" : "(cl::Sink);\n");
2118
2119   O << '\n';
2120 }
2121
2122 /// EmitPreprocessOptionsCallback - Helper function passed to
2123 /// EmitCaseConstructHandler() by EmitPreprocessOptions().
2124 class EmitPreprocessOptionsCallback : ActionHandlingCallbackBase {
2125   const OptionDescriptions& OptDescs_;
2126
2127   void onUnsetOption(Init* i, unsigned IndentLevel, raw_ostream& O) {
2128     const std::string& OptName = InitPtrToString(i);
2129     const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
2130     const OptionType::OptionType OptType = OptDesc.Type;
2131
2132     if (OptType == OptionType::Switch) {
2133       O.indent(IndentLevel) << OptDesc.GenVariableName() << " = false;\n";
2134     }
2135     else if (OptType == OptionType::Parameter
2136              || OptType == OptionType::Prefix) {
2137       O.indent(IndentLevel) << OptDesc.GenVariableName() << " = \"\";\n";
2138     }
2139     else {
2140       throw std::string("'unset_option' can only be applied to "
2141                         "switches or parameter/prefix options.");
2142     }
2143   }
2144
2145   void processDag(const Init* I, unsigned IndentLevel, raw_ostream& O)
2146   {
2147     const DagInit& d = InitPtrToDag(I);
2148     const std::string& OpName = GetOperatorName(d);
2149
2150     if (OpName == "warning") {
2151       this->onWarningDag(d, IndentLevel, O);
2152     }
2153     else if (OpName == "error") {
2154       this->onWarningDag(d, IndentLevel, O);
2155     }
2156     else if (OpName == "unset_option") {
2157       checkNumberOfArguments(&d, 1);
2158       Init* I = d.getArg(0);
2159       if (typeid(*I) == typeid(ListInit)) {
2160         const ListInit& DagList = *static_cast<const ListInit*>(I);
2161         for (ListInit::const_iterator B = DagList.begin(), E = DagList.end();
2162              B != E; ++B)
2163           this->onUnsetOption(*B, IndentLevel, O);
2164       }
2165       else {
2166         this->onUnsetOption(I, IndentLevel, O);
2167       }
2168     }
2169     else {
2170       throw "Unknown operator in the option preprocessor: '" + OpName + "'!"
2171         "\nOnly 'warning', 'error' and 'unset_option' are allowed.";
2172     }
2173   }
2174
2175 public:
2176
2177   void operator()(const Init* I, unsigned IndentLevel, raw_ostream& O) {
2178       this->processDag(I, IndentLevel, O);
2179   }
2180
2181   EmitPreprocessOptionsCallback(const OptionDescriptions& OptDescs)
2182   : OptDescs_(OptDescs)
2183   {}
2184 };
2185
2186 /// EmitPreprocessOptions - Emit the PreprocessOptionsLocal() function.
2187 void EmitPreprocessOptions (const RecordKeeper& Records,
2188                             const OptionDescriptions& OptDecs, raw_ostream& O)
2189 {
2190   O << "void PreprocessOptionsLocal() {\n";
2191
2192   const RecordVector& OptionPreprocessors =
2193     Records.getAllDerivedDefinitions("OptionPreprocessor");
2194
2195   for (RecordVector::const_iterator B = OptionPreprocessors.begin(),
2196          E = OptionPreprocessors.end(); B!=E; ++B) {
2197     DagInit* Case = (*B)->getValueAsDag("preprocessor");
2198     EmitCaseConstructHandler(Case, Indent1,
2199                              EmitPreprocessOptionsCallback(OptDecs),
2200                              false, OptDecs, O);
2201   }
2202
2203   O << "}\n\n";
2204 }
2205
2206 /// EmitPopulateLanguageMap - Emit the PopulateLanguageMapLocal() function.
2207 void EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O)
2208 {
2209   O << "void PopulateLanguageMapLocal(LanguageMap& langMap) {\n";
2210
2211   // Get the relevant field out of RecordKeeper
2212   const Record* LangMapRecord = Records.getDef("LanguageMap");
2213
2214   // It is allowed for a plugin to have no language map.
2215   if (LangMapRecord) {
2216
2217     ListInit* LangsToSuffixesList = LangMapRecord->getValueAsListInit("map");
2218     if (!LangsToSuffixesList)
2219       throw std::string("Error in the language map definition!");
2220
2221     for (unsigned i = 0; i < LangsToSuffixesList->size(); ++i) {
2222       const Record* LangToSuffixes = LangsToSuffixesList->getElementAsRecord(i);
2223
2224       const std::string& Lang = LangToSuffixes->getValueAsString("lang");
2225       const ListInit* Suffixes = LangToSuffixes->getValueAsListInit("suffixes");
2226
2227       for (unsigned i = 0; i < Suffixes->size(); ++i)
2228         O.indent(Indent1) << "langMap[\""
2229                           << InitPtrToString(Suffixes->getElement(i))
2230                           << "\"] = \"" << Lang << "\";\n";
2231     }
2232   }
2233
2234   O << "}\n\n";
2235 }
2236
2237 /// IncDecWeight - Helper function passed to EmitCaseConstructHandler()
2238 /// by EmitEdgeClass().
2239 void IncDecWeight (const Init* i, unsigned IndentLevel,
2240                    raw_ostream& O) {
2241   const DagInit& d = InitPtrToDag(i);
2242   const std::string& OpName = GetOperatorName(d);
2243
2244   if (OpName == "inc_weight") {
2245     O.indent(IndentLevel) << "ret += ";
2246   }
2247   else if (OpName == "dec_weight") {
2248     O.indent(IndentLevel) << "ret -= ";
2249   }
2250   else if (OpName == "error") {
2251     checkNumberOfArguments(&d, 1);
2252     O.indent(IndentLevel) << "throw std::runtime_error(\""
2253                           << InitPtrToString(d.getArg(0))
2254                           << "\");\n";
2255     return;
2256   }
2257   else {
2258     throw "Unknown operator in edge properties list: '" + OpName + "'!"
2259       "\nOnly 'inc_weight', 'dec_weight' and 'error' are allowed.";
2260   }
2261
2262   if (d.getNumArgs() > 0)
2263     O << InitPtrToInt(d.getArg(0)) << ";\n";
2264   else
2265     O << "2;\n";
2266
2267 }
2268
2269 /// EmitEdgeClass - Emit a single Edge# class.
2270 void EmitEdgeClass (unsigned N, const std::string& Target,
2271                     DagInit* Case, const OptionDescriptions& OptDescs,
2272                     raw_ostream& O) {
2273
2274   // Class constructor.
2275   O << "class Edge" << N << ": public Edge {\n"
2276     << "public:\n";
2277   O.indent(Indent1) << "Edge" << N << "() : Edge(\"" << Target
2278                     << "\") {}\n\n";
2279
2280   // Function Weight().
2281   O.indent(Indent1)
2282     << "unsigned Weight(const InputLanguagesSet& InLangs) const {\n";
2283   O.indent(Indent2) << "unsigned ret = 0;\n";
2284
2285   // Handle the 'case' construct.
2286   EmitCaseConstructHandler(Case, Indent2, IncDecWeight, false, OptDescs, O);
2287
2288   O.indent(Indent2) << "return ret;\n";
2289   O.indent(Indent1) << "};\n\n};\n\n";
2290 }
2291
2292 /// EmitEdgeClasses - Emit Edge* classes that represent graph edges.
2293 void EmitEdgeClasses (const RecordVector& EdgeVector,
2294                       const OptionDescriptions& OptDescs,
2295                       raw_ostream& O) {
2296   int i = 0;
2297   for (RecordVector::const_iterator B = EdgeVector.begin(),
2298          E = EdgeVector.end(); B != E; ++B) {
2299     const Record* Edge = *B;
2300     const std::string& NodeB = Edge->getValueAsString("b");
2301     DagInit* Weight = Edge->getValueAsDag("weight");
2302
2303     if (!isDagEmpty(Weight))
2304       EmitEdgeClass(i, NodeB, Weight, OptDescs, O);
2305     ++i;
2306   }
2307 }
2308
2309 /// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraphLocal()
2310 /// function.
2311 void EmitPopulateCompilationGraph (const RecordVector& EdgeVector,
2312                                    const ToolDescriptions& ToolDescs,
2313                                    raw_ostream& O)
2314 {
2315   O << "void PopulateCompilationGraphLocal(CompilationGraph& G) {\n";
2316
2317   for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
2318          E = ToolDescs.end(); B != E; ++B)
2319     O.indent(Indent1) << "G.insertNode(new " << (*B)->Name << "());\n";
2320
2321   O << '\n';
2322
2323   // Insert edges.
2324
2325   int i = 0;
2326   for (RecordVector::const_iterator B = EdgeVector.begin(),
2327          E = EdgeVector.end(); B != E; ++B) {
2328     const Record* Edge = *B;
2329     const std::string& NodeA = Edge->getValueAsString("a");
2330     const std::string& NodeB = Edge->getValueAsString("b");
2331     DagInit* Weight = Edge->getValueAsDag("weight");
2332
2333     O.indent(Indent1) << "G.insertEdge(\"" << NodeA << "\", ";
2334
2335     if (isDagEmpty(Weight))
2336       O << "new SimpleEdge(\"" << NodeB << "\")";
2337     else
2338       O << "new Edge" << i << "()";
2339
2340     O << ");\n";
2341     ++i;
2342   }
2343
2344   O << "}\n\n";
2345 }
2346
2347 /// ExtractHookNames - Extract the hook names from all instances of
2348 /// $CALL(HookName) in the provided command line string. Helper
2349 /// function used by FillInHookNames().
2350 class ExtractHookNames {
2351   llvm::StringMap<unsigned>& HookNames_;
2352 public:
2353   ExtractHookNames(llvm::StringMap<unsigned>& HookNames)
2354   : HookNames_(HookNames) {}
2355
2356   void operator()(const Init* CmdLine) {
2357     StrVector cmds;
2358
2359     // Ignore nested 'case' DAG.
2360     if (typeid(*CmdLine) == typeid(DagInit))
2361       return;
2362
2363     TokenizeCmdline(InitPtrToString(CmdLine), cmds);
2364     for (StrVector::const_iterator B = cmds.begin(), E = cmds.end();
2365          B != E; ++B) {
2366       const std::string& cmd = *B;
2367
2368       if (cmd == "$CALL") {
2369         unsigned NumArgs = 0;
2370         checkedIncrement(B, E, "Syntax error in $CALL invocation!");
2371         const std::string& HookName = *B;
2372
2373
2374         if (HookName.at(0) == ')')
2375           throw "$CALL invoked with no arguments!";
2376
2377         while (++B != E && B->at(0) != ')') {
2378           ++NumArgs;
2379         }
2380
2381         StringMap<unsigned>::const_iterator H = HookNames_.find(HookName);
2382
2383         if (H != HookNames_.end() && H->second != NumArgs)
2384           throw "Overloading of hooks is not allowed. Overloaded hook: "
2385             + HookName;
2386         else
2387           HookNames_[HookName] = NumArgs;
2388
2389       }
2390     }
2391   }
2392
2393   void operator()(const DagInit* Test, unsigned, bool) {
2394     this->operator()(Test);
2395   }
2396   void operator()(const Init* Statement, unsigned) {
2397     this->operator()(Statement);
2398   }
2399 };
2400
2401 /// FillInHookNames - Actually extract the hook names from all command
2402 /// line strings. Helper function used by EmitHookDeclarations().
2403 void FillInHookNames(const ToolDescriptions& ToolDescs,
2404                      llvm::StringMap<unsigned>& HookNames)
2405 {
2406   // For all command lines:
2407   for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
2408          E = ToolDescs.end(); B != E; ++B) {
2409     const ToolDescription& D = *(*B);
2410     if (!D.CmdLine)
2411       continue;
2412     if (dynamic_cast<StringInit*>(D.CmdLine))
2413       // This is a string.
2414       ExtractHookNames(HookNames).operator()(D.CmdLine);
2415     else
2416       // This is a 'case' construct.
2417       WalkCase(D.CmdLine, Id(), ExtractHookNames(HookNames));
2418   }
2419 }
2420
2421 /// EmitHookDeclarations - Parse CmdLine fields of all the tool
2422 /// property records and emit hook function declaration for each
2423 /// instance of $CALL(HookName).
2424 void EmitHookDeclarations(const ToolDescriptions& ToolDescs, raw_ostream& O) {
2425   llvm::StringMap<unsigned> HookNames;
2426
2427   FillInHookNames(ToolDescs, HookNames);
2428   if (HookNames.empty())
2429     return;
2430
2431   O << "namespace hooks {\n";
2432   for (StringMap<unsigned>::const_iterator B = HookNames.begin(),
2433          E = HookNames.end(); B != E; ++B) {
2434     O.indent(Indent1) << "std::string " << B->first() << "(";
2435
2436     for (unsigned i = 0, j = B->second; i < j; ++i) {
2437       O << "const char* Arg" << i << (i+1 == j ? "" : ", ");
2438     }
2439
2440     O <<");\n";
2441   }
2442   O << "}\n\n";
2443 }
2444
2445 /// EmitRegisterPlugin - Emit code to register this plugin.
2446 void EmitRegisterPlugin(int Priority, raw_ostream& O) {
2447   O << "struct Plugin : public llvmc::BasePlugin {\n\n";
2448   O.indent(Indent1) << "int Priority() const { return "
2449                     << Priority << "; }\n\n";
2450   O.indent(Indent1) << "void PreprocessOptions() const\n";
2451   O.indent(Indent1) << "{ PreprocessOptionsLocal(); }\n\n";
2452   O.indent(Indent1) << "void PopulateLanguageMap(LanguageMap& langMap) const\n";
2453   O.indent(Indent1) << "{ PopulateLanguageMapLocal(langMap); }\n\n";
2454   O.indent(Indent1)
2455     << "void PopulateCompilationGraph(CompilationGraph& graph) const\n";
2456   O.indent(Indent1) << "{ PopulateCompilationGraphLocal(graph); }\n"
2457                     << "};\n\n"
2458                     << "static llvmc::RegisterPlugin<Plugin> RP;\n\n";
2459 }
2460
2461 /// EmitIncludes - Emit necessary #include directives and some
2462 /// additional declarations.
2463 void EmitIncludes(raw_ostream& O) {
2464   O << "#include \"llvm/CompilerDriver/BuiltinOptions.h\"\n"
2465     << "#include \"llvm/CompilerDriver/CompilationGraph.h\"\n"
2466     << "#include \"llvm/CompilerDriver/ForceLinkageMacros.h\"\n"
2467     << "#include \"llvm/CompilerDriver/Plugin.h\"\n"
2468     << "#include \"llvm/CompilerDriver/Tool.h\"\n\n"
2469
2470     << "#include \"llvm/ADT/StringExtras.h\"\n"
2471     << "#include \"llvm/Support/CommandLine.h\"\n"
2472     << "#include \"llvm/Support/raw_ostream.h\"\n\n"
2473
2474     << "#include <cstdlib>\n"
2475     << "#include <stdexcept>\n\n"
2476
2477     << "using namespace llvm;\n"
2478     << "using namespace llvmc;\n\n"
2479
2480     << "extern cl::opt<std::string> OutputFilename;\n\n"
2481
2482     << "inline const char* checkCString(const char* s)\n"
2483     << "{ return s == NULL ? \"\" : s; }\n\n";
2484 }
2485
2486
2487 /// PluginData - Holds all information about a plugin.
2488 struct PluginData {
2489   OptionDescriptions OptDescs;
2490   bool HasSink;
2491   bool HasExterns;
2492   ToolDescriptions ToolDescs;
2493   RecordVector Edges;
2494   int Priority;
2495 };
2496
2497 /// HasSink - Go through the list of tool descriptions and check if
2498 /// there are any with the 'sink' property set.
2499 bool HasSink(const ToolDescriptions& ToolDescs) {
2500   for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
2501          E = ToolDescs.end(); B != E; ++B)
2502     if ((*B)->isSink())
2503       return true;
2504
2505   return false;
2506 }
2507
2508 /// HasExterns - Go through the list of option descriptions and check
2509 /// if there are any external options.
2510 bool HasExterns(const OptionDescriptions& OptDescs) {
2511  for (OptionDescriptions::const_iterator B = OptDescs.begin(),
2512          E = OptDescs.end(); B != E; ++B)
2513     if (B->second.isExtern())
2514       return true;
2515
2516   return false;
2517 }
2518
2519 /// CollectPluginData - Collect tool and option properties,
2520 /// compilation graph edges and plugin priority from the parse tree.
2521 void CollectPluginData (const RecordKeeper& Records, PluginData& Data) {
2522   // Collect option properties.
2523   const RecordVector& OptionLists =
2524     Records.getAllDerivedDefinitions("OptionList");
2525   CollectOptionDescriptions(OptionLists.begin(), OptionLists.end(),
2526                             Data.OptDescs);
2527
2528   // Collect tool properties.
2529   const RecordVector& Tools = Records.getAllDerivedDefinitions("Tool");
2530   CollectToolDescriptions(Tools.begin(), Tools.end(), Data.ToolDescs);
2531   Data.HasSink = HasSink(Data.ToolDescs);
2532   Data.HasExterns = HasExterns(Data.OptDescs);
2533
2534   // Collect compilation graph edges.
2535   const RecordVector& CompilationGraphs =
2536     Records.getAllDerivedDefinitions("CompilationGraph");
2537   FillInEdgeVector(CompilationGraphs.begin(), CompilationGraphs.end(),
2538                    Data.Edges);
2539
2540   // Calculate the priority of this plugin.
2541   const RecordVector& Priorities =
2542     Records.getAllDerivedDefinitions("PluginPriority");
2543   Data.Priority = CalculatePriority(Priorities.begin(), Priorities.end());
2544 }
2545
2546 /// CheckPluginData - Perform some sanity checks on the collected data.
2547 void CheckPluginData(PluginData& Data) {
2548   // Filter out all tools not mentioned in the compilation graph.
2549   FilterNotInGraph(Data.Edges, Data.ToolDescs);
2550
2551   // Typecheck the compilation graph.
2552   TypecheckGraph(Data.Edges, Data.ToolDescs);
2553
2554   // Check that there are no options without side effects (specified
2555   // only in the OptionList).
2556   CheckForSuperfluousOptions(Data.Edges, Data.ToolDescs, Data.OptDescs);
2557
2558 }
2559
2560 void EmitPluginCode(const PluginData& Data, raw_ostream& O) {
2561   // Emit file header.
2562   EmitIncludes(O);
2563
2564   // Emit global option registration code.
2565   EmitOptionDefinitions(Data.OptDescs, Data.HasSink, Data.HasExterns, O);
2566
2567   // Emit hook declarations.
2568   EmitHookDeclarations(Data.ToolDescs, O);
2569
2570   O << "namespace {\n\n";
2571
2572   // Emit PreprocessOptionsLocal() function.
2573   EmitPreprocessOptions(Records, Data.OptDescs, O);
2574
2575   // Emit PopulateLanguageMapLocal() function
2576   // (language map maps from file extensions to language names).
2577   EmitPopulateLanguageMap(Records, O);
2578
2579   // Emit Tool classes.
2580   for (ToolDescriptions::const_iterator B = Data.ToolDescs.begin(),
2581          E = Data.ToolDescs.end(); B!=E; ++B)
2582     EmitToolClassDefinition(*(*B), Data.OptDescs, O);
2583
2584   // Emit Edge# classes.
2585   EmitEdgeClasses(Data.Edges, Data.OptDescs, O);
2586
2587   // Emit PopulateCompilationGraphLocal() function.
2588   EmitPopulateCompilationGraph(Data.Edges, Data.ToolDescs, O);
2589
2590   // Emit code for plugin registration.
2591   EmitRegisterPlugin(Data.Priority, O);
2592
2593   O << "} // End anonymous namespace.\n\n";
2594
2595   // Force linkage magic.
2596   O << "namespace llvmc {\n";
2597   O << "LLVMC_FORCE_LINKAGE_DECL(LLVMC_PLUGIN_NAME) {}\n";
2598   O << "}\n";
2599
2600   // EOF
2601 }
2602
2603
2604 // End of anonymous namespace
2605 }
2606
2607 /// run - The back-end entry point.
2608 void LLVMCConfigurationEmitter::run (raw_ostream &O) {
2609   try {
2610   PluginData Data;
2611
2612   CollectPluginData(Records, Data);
2613   CheckPluginData(Data);
2614
2615   EmitSourceFileHeader("LLVMC Configuration Library", O);
2616   EmitPluginCode(Data, O);
2617
2618   } catch (std::exception& Error) {
2619     throw Error.what() + std::string(" - usually this means a syntax error.");
2620   }
2621 }